Skip to main content

News

Show Posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.

Messages - casiotone

16
Engine Development / Re: minisphere 1.0.10
Awesome stuff. A way to enable filtering for images would be good.
17
Engine Development / Re: minisphere 1.0.10
How about a DoesFileExist function? Not sure why it wasn't added with the other file/directory listing functions.
18
Quote from: Lord English

casiotone has compiled it on OS X, that's the joystick assertion fixed in 1.0.10.  Can't speak for segfaults, but he didn't mention any to me.

But yes, I'll agree that it needs real testing on non-Windows platforms.  I recently set up Hyper-V on my Win8.1 laptop, so I should be able to build on Linux soon, at least.  Unfortunately OS X is out of my league, unless I can can manage to make a Hackintosh setup somehow...

The joystick issue is the only thing I've encountered - it's been working perfectly otherwise. I haven't tested the entire API yet though, just some simple maps and image blitting.
19
Engine Development / Re: CommonJS modules
This weekend I'm going to look into setting up a bower fork and registry for Sphere.

Bower's model should be a much better fit than npm as it dedupes modules and puts everything in one directory instead of npm's method of nesting dependencies, since loading multiple versions of the same library is likely to break in Sphere.

We can use this straight away for existing code without moving to CommonJS - it should be cool.
20
Engine Development / Re: CommonJS modules

I will say the dependency management would be useful.  This is actually what's stopped me from releasing the Specs threader as a standalone thing, it depends on Link and I didn't want script users to have to deal with the extra complexity of having an additional dependency (even if it's just one file), particularly since it's a dependency I don't maintain.

It's certainly something worth considering for inclusion in the Pegasus spec.

Well, it's already in the spec. But I'd like to see it now!  :)
21
Engine Development / Re: CommonJS modules
Lord English, modules are pretty simple - essentially a module works exactly the same as a script included with EvaluateScript, with a couple of differences:
   
   * The module is run in a new scope, and any variables defined do not leak into the global scope.
   * To export an API, a module has a 'magic' variable called exports. This is what is returned when you require a module.
   * A module can be a directory of scripts instead of just one script. In this case, the system reads package.json in the directory to find out what the main script is and includes that, or it defaults to index.js.
   
   A package is a distributable module that can be installed by a package manager like npm. A package includes a package.json file that describes the package and what dependencies it has. Using this information, the package manager can automatically install anything else necessary for the package to work.
   
   So, the benefits as I see them:
   
   1. Modules prevent naming conflicts

   Including a library currently requires creating your objects/other variables in the global scope so they can be accessed by game scripts. This can cause conflicts with other libraries or stuff in your own game.
   e.g. if I want to use Link.js, I have to make sure I don't have my own variable called 'Link'. I also have to make sure every other library I'm using also doesn't define 'Link'. If they do, I would have to modify those libraries and can no longer cleanly update them when a new version comes out.
   Instead of having 'Link' be a global, you can just require('link') wherever you need it. Any libraries that have their own 'Link' variable are unaffected.
   
   2. Packages allow better dependency management
   
   Without packages, if you include a library that depends on another library, you have to know that the dependency exists, and you have to know which version of the other library is expected. Alternatively, the library can include its dependencies inline, which causes conflicts if you have more than one library with the same dependency.
   With a package system, the dependencies are specified in the package.json and can be installed automatically. If two modules depend on the same package, only one copy can be installed and they will both use it.
   
   3. Packages allow easy updating
   
   All your installed packages are specified in your projects own package.json as dependencies. To update something, you just bump the version number and run the package manager to install it again.
   
   4. A package index makes finding libraries easier
   
   Instead of searching the internet, forums, etc, to find everything on different sites, we can create a single package index with every sphere library that's easily searchable. We also make installing libraries easy with a package manager: just run "spm install link" and now you can require('link') in your script.
   
   5. We can re-use packages from other JS package managers
   
   In my own project, I have included the lodash node package. Because it supports CommonJS, it works out of the box. (I only had to define a 'global' global to get it to think it was running on node).
   
   
   A lot of the problems are not *big* problems with Sphere games because of the lack of different libraries - generally you're going to be OK and not have many conflicts. But if Sphere is going to gain wide usage, they are problems that will need to be solved, and I think it's better to do it sooner rather than later.
   
   Note that backwards compatibility for libraries shouldn't be a problem - you can check for the presence of "require" in your library and set globals if it's not there. Your library will continue to work in the normal environment, but also be usable as a module.
   
   We're still writing scripts like its the 90s - but the state of JS development has moved on significantly since Sphere was released. These are features that most modern JS developers are going to expect as standard.
22
System.Environment.Is64BitOperatingSystem was added in .NET 4.0: https://msdn.microsoft.com/en-us/library/system.environment.is64bitoperatingsystem(VS.100).aspx
23
Engine Development / CommonJS modules
This has been discussed on github for sphere 2.0: https://github.com/sphere-group/pegasus/issues/9

I think all the current engines should move to implement require as a built-in as soon as possible, and Sphere libraries should begin to be shipped as simple npm-like packages that can be used with require. With a forked `npm` using a custom package index we can make Sphere libraries easy to install and use, with proper dependency management. In short, modern.

We can still shim support without built-in require for backwards compatibility - writing a module loader isn't that complicated, and we're only going to be loading JavaScript.

I have been working with minisphere and Duktape has half of it built in - it performs path resolution and you have to supply it with the module. I wrote a loader that enables use of require('module') that will look for four things:

1. module.js
2. module.json
3. module/index.js
4. module/package.json

The final check is for packages. We open the package.json and find out what the main file is called, then load that. We also have a convenience loader for JSON files.

It will look for files in your scripts directory, then in the modules directory. This is the directory that Sphere libraries would be installed to by the package manager.

Code: [Select]

(function() {
  var extensions, fileExists, jsHandler, jsonHandler, packageHandler, paths,
    indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; };

  jsHandler = function(filePath, file) {
    return file;
  };

  jsonHandler = function(filePath, file, exports) {
    var json, key, value;
    json = JSON.parse(file);
    for (key in json) {
      value = json[key];
      exports[key] = value;
    }
  };

  packageHandler = function(filePath, file) {
    var json, script;
    json = JSON.parse(file);
    file = OpenRawFile(filePath.substr(0, filePath.length - 12) + json.main);
    script = CreateStringFromByteArray(file.read(file.getSize()));
    return script;
  };

  fileExists = function(path) {
    var check, checked, entries, parts, testPath;
    if (path.substr(0, 3) === '../') {
      path = path.substr(3);
    }
    parts = path.split('/');
    checked = [];
    while (true) {
      testPath = checked.join('/');
      entries = GetDirectoryList(testPath);
      entries = entries.concat(GetFileList(testPath));
      check = parts.shift();
      if (indexOf.call(entries, check) >= 0) {
        checked.push(check);
        if (parts.length === 0) {
          return true;
        }
      } else {
        return false;
      }
    }
  };

  extensions = {
    '.js': jsHandler,
    '.json': jsonHandler,
    '/index.js': jsHandler,
    '/package.json': packageHandler
  };

  paths = ['../scripts', '../modules'];

  Duktape.modSearch = function(id, require, exports, module) {
    var extension, file, filePath, handler, i, len, path, script;
    for (i = 0, len = paths.length; i < len; i++) {
      path = paths[i];
      for (extension in extensions) {
        handler = extensions[extension];
        filePath = path + "/" + id + extension;
        if (fileExists(filePath)) {
          file = OpenRawFile(filePath);
          script = CreateStringFromByteArray(file.read(file.getSize()));
          return handler(filePath, script, exports);
        }
      }
    }
    throw new Error("Cannot find module " + id);
  };

}).call(this);


Duktape is currently limited and assigning module.exports doesn't work, only properties on exports. It also has limitations that mean we can't load package files from a subdirectory in the package. A replacement is being considered to make it more flexible, but this works otherwise. We can still shim instead of using Duktape until then.

Let's make this the first step to Sphere 2.0. A real module loader and a real package manager.
24
Engine Development / Re: minisphere 1.0.6


Sounds like duktape doesn't like using `undefined` as an object key. This is probably a bug, it should coerce to a string first, which SM and V8 do. e.g. hippo[undefined] = true; should be equivalent to hippo['undefined'] = true;.

Just wondering, what happens if you try:

Code: [Select]

var array = [];
array[{}] = true;
Abort(Object.keys(array));


This should give you "[object Object]" as the only key in the object.


It does.  Also, changing array[{}] to array[undefined] yields 'undefined' as the final output.

Well, that *is* weird then.
25
Engine Development / Re: minisphere 1.0.6

Is it bad that every time someone reports a major bug I rub my hands together excitedly in a "Let's get to work!" kind of way? :P

First, the simple one: That array thing is quite odd.  Here's a little test case:
Code: (javascript) [Select]
var hippo = [ [ "maggie" ] ];
var x, y = 0;
Abort(hippo[x][y]);


This fails in both minisphere and vanilla.  The errors are:
minisphere - TypeError: "invalid base value"
Sphere 1.5 - TypeError: "hippo[ x ] has no properties"

So, not sure what's going on, maybe behavior is different enough between the two engines that x ends up undefined sometimes in minisphere while it never does in Sphere.  I don't know.


Sounds like duktape doesn't like using `undefined` as an object key. This is probably a bug, it should coerce to a string first, which SM and V8 do. e.g. hippo[undefined] = true; should be equivalent to hippo['undefined'] = true;.

Just wondering, what happens if you try:

Code: [Select]

var array = [];
array[{}] = true;
Abort(Object.keys(array));


This should give you "[object Object]" as the only key in the object.
26
Engine Development / Re: TurboSphere

One issue with that is that a RFN font must necessarily be at least 256+(32*largest_code_point) of any font. So if you imported an ascii font, but then added, say, code point 2002 (nbs), the font must be at least 292 KB plus however big the font was anyway. On the bright side, it would compress very well  ;D That's not properly a limitation, though. It's just a minor inconvenience.

You should consider just bumping the version number and including a new table in the format with the character ranges that the font contains. e.g. an array of (int32, int32). Then your font could have simply 0x00 0xFF 0x2002 0x2002 as the range table and only include 256 glyphs. Wouldn't be too hard to implement.
27
Spherical News / Re: Server move
If you're reading this, everything went perfectly.
28
Spherical News / Server move
Hi guys,

Later today (around 12PM GMT) the server is going to be moved to new hardware. I've been told the downtime should be between 1 and 15 minutes. It'll be closer to the short end as there's not much to move. The site should come back automatically when the server is brought back up, but just in case, I'll be checking on it later.
29
Editor Development / Re: Radnen's Sphere Studio v1.1.6.0

Hmm, I guess I'll recode the tile selection stuff. It was elegant at one point but then there were a series of changes that kinda added code here and there and got kinda got messier as time went on.

I know that feeling!
30
Editor Development / Re: Radnen's Sphere Studio v1.1.6.0
I think there's a number of contributing problems with this bug. I've looked into it and not made much progress either, but what I've found:

https://github.com/Radnen/spherestudio/blob/master/MapEditPlugin/MapEditor.cs#L467

In TilesetControl_TileRemoved, it calls TilesetControl.Select to select the tile that has just been removed.

https://github.com/Radnen/spherestudio/blob/master/MapEditPlugin/Components/TilesetControl2.cs#L212

SelectTiles adds -1 to the Selected list when a tile is invalid. This is then checked for in other places, but imo this should be changed to just ignore invalid tiles so a selected value of -1 doesn't have to be handled anywhere else. e.g. instead of

Code: [Select]
if (tile < 0 || tile > Tileset.Tiles.Count - 1) tile = -1;
Selected.Add(tile);


A better solution would be

Code: [Select]
if (tile >= 0 && tile < Tileset.Tiles.Count)
{
  Selected.Add(tile)
}


The code is quite convoluted so I'm not sure on how it all fits together fully yet, so I might be wrong on this, but I don't see a reason to keep invalid selections in the Selected list.

I'm not sure, but I think TilesetControl.RemoveTiles should also remove the tiles from the Selected list, otherwise it can contain invalid tile indexes after removal.

I'm also not sure about this:

https://github.com/Radnen/spherestudio/blob/master/MapEditPlugin/MapEditor.cs#L452

Here, on the TileSelected event, it calls TilesetControl.SelectTiles again. I think this is dead code however, it's not referenced from MapEditor.cs and if it really was being run it would probably cause an infinite loop. I think the first thing to do is to clean up the map editor and tileset code.

Unfortunately when I was fiddling with all these things I still couldn't get it to work!