Spherical forums

Sphere Development => Engine Development => Topic started by: Fat Cerberus on January 25, 2015, 11:21:21 am

Title: miniSphere 5.3.0
Post by: Fat Cerberus on January 25, 2015, 11:21:21 am
miniSphere is the current official implementation of Sphere and a complete rewrite of Chad Austin's original Sphere game engine, coded from the ground up in C.  It uses Allegro (http://alleg.sourceforge.net/) for cross-platform graphics and sound and JavaScript is powered by ChakraCore (https://github.com/Microsoft/ChakraCore).  The engine boasts almost full parity with the Sphere 1.5 API and most Sphere 1.x games run in miniSphere with no modifications.  But make no mistake: this is a Sphere v2 engine, and includes many, many features not found in the engine it replaces.  These include Galileo, a scene graph API pioneered by TurboSphere which enables more flexible rendering than the Sphere v1 primitive-drawing functions; the RNG class for ultimate control over random number generation; SphereFS, a standard protocol for specifying asset filenames within the sandboxed file system; and full native support for JavaScript module syntax (import/export) as defined in ES2015.  Best of all, old and new API functions can be mixed within the same codebase, making migration of existing codebases to Sphere v2 very easy.

Thanks to ChakraCore, the same JavaScript engine that powers Microsoft Edge, miniSphere natively supports modern JavaScript features such as template strings, arrow functions, destructuring assignment, even modules!  The engine also comes with an SCons-inspired programmable build engine, Cell, also JS-powered, which can be used to build assets on-the-fly.  miniSphere was also the first implementation of Sphere to include support for single-step debugging!  Thanks to ChakraCore's powerful built-in debugger API, it does!  Using either Sphere Studio or the SSj command-line debugger (both included with the engine), you can set breakpoints, see console output, and step through your game's code line-by-line to find bugs, inspect variables and even run arbitrary JavaScript code.  It's an invaluable tool for any serious game developer.  Some might say it's miniSphere's killer feature!

miniSphere 5.3.0 - December 25, 2018 - Release Notes (https://github.com/fatcerberus/minisphere/releases/tag/v5.3.0) - GitHub Repo (https://github.com/fatcerberus/minisphere)
Includes miniSphere, SpheRun, Cell compiler, and SSj command-line debugger.
Windows release also includes Sphere Studio (.NET 4.5+ required).


note on macOS release:
The macOS release is maintained by @Rhuan.  While every attempt is made to coordinate milestone releases (e.g. 5.3.0) across all platforms, the macOS build can sometimes fall a few patches behind during a given release cycle.


Sphere v2 API Documentation
Title: Re: minisphere
Post by: Fat Cerberus on January 25, 2015, 07:26:51 pm
That's odd, I just got an email that Flying Jester replied to the topic, but there's nothing here...
Title: Re: minisphere
Post by: Flying Jester on January 25, 2015, 07:42:13 pm
I almost wrote a reply, but then I decided to investigate first.

SFML ;_;
I never tried to use it before, but it's a bit of a mess on OS X. I brought the engine up on OS X (mostly) using SCons and the prebuilt SFML libraries for OS X.
Title: Re: minisphere
Post by: Fat Cerberus on January 26, 2015, 09:58:43 pm
How up-to-date is the api.txt that comes with Sphere?  I'll need a reference in order to replicate the Sphere 1.x API.
Title: Re: minisphere
Post by: Flying Jester on January 26, 2015, 11:41:33 pm
Last I checked, it has a few functions that don't actually work in Sphere (surface.blitImage() jumps to mind). I haven't found anything it's missing yet

I've been using it (from my git repo) to fill out the TS map engine.

I'm curious where the line will be drawn between script and native. Are surfaces native or script?
Title: Re: minisphere
Post by: Fat Cerberus on January 27, 2015, 12:10:24 am
How would I do surfaces in script?  That definitely seems like something that should be native.
Title: Re: minisphere
Post by: Flying Jester on January 27, 2015, 03:40:02 am
It would be simple, just an object that has a UInt32Array, a width, and a height :)
Title: Re: minisphere
Post by: Fat Cerberus on January 27, 2015, 12:43:36 pm
Small issue with that: besides that that puts surface operations entirely in software, how would I implement methods like surface.drawText, not to mention all the primitives.  If I wanted a 1:1 mapping to Sphere 1.x I'd have to implement those all in JS as well, meaning I don't get the benefit of letting the hardware do it, as I could if I were to implement surfaces natively.
Title: Re: minisphere
Post by: Fat Cerberus on January 28, 2015, 10:51:29 pm
So I'm thinking maybe not surfaces, but a lot of things will be implemented scriptside in minisphere.  For example: Color objects.  Duktape's stack-based API is painful to use (I don't even remember Lua's being this bad...) and once constructors and prototypes get involved, it gets even more convoluted.  For simple objects like Color, there's no real benefit to creating them on the C side as in the end it's just a simple RGBA tuple.  JS can handle those very well on its own.

In the process I think I'm going to make tweaks to the structure of the API, clean things up a bit.  For example, BlendColors() and BlendColorsWeighted() both get folded into the Color object as a single method: color_obj.blendWith(color2, w1, w2).  Of course, to maintain compatibility with existing Sphere code, I'll be sure to expose some kind of legacy API, likely as an optional thing, similar to what Jester is planning to do with TurboSphere.
Title: Re: minisphere
Post by: Flying Jester on January 29, 2015, 02:28:31 am
I've been doing that to a certain extent with the map engine, and with images now.

I think that colors are one of the better objects to do that with, actually. In V8 there was a pretty high overhead to making any native-defined object, especially since that usually meant some native-side allocation had to occur. Making colors is easy to do all over the place in a normal Sphere script without even thinking about it. Putting them fully in script would help alleviate that. Especially because there is no particular reason they need to be done in native.

I think it's a good technique. Have a powerful, concise core API that Sphere's API is implementable in, and also a script-side layer that fills out the rest of the Sphere API. Even with the map engine, which is all script anyway =P
Title: Re: minisphere
Post by: Fat Cerberus on January 29, 2015, 10:32:23 pm
I'm not too concerned about script-to-native overhead--the purpose of a stack-based API like the one in Duktape and Lua is that any objects created are allocated in-engine, rather than on the native side.  For example, this:

Code: (c) [Select]
duk_push_global_object(ctx);
duk_push_object(ctx);
duk_push_int(ctx, 812);
duk_put_prop_string(ctx, -2, "number");
duk_put_prop_string(ctx, -2, "myObj");
duk_pop(ctx);


...is quite literally equivalent to this:
Code: (c) [Select]
duk_eval_string_noresult(ctx, "myObj = {}; myObj.number = 812;");


As you can probably tell, the bigger concern here is the unmaintainable mess the C-side constructors will end up becoming (hint: see first code snippet).  A lot of that can be avoided simply by implementing stuff directly in JS to start with.
Title: Re: minisphere
Post by: Fat Cerberus on January 30, 2015, 10:45:49 pm
Hm, so I'm thinking I may try out Allegro after all.  SFML was definitely designed for use in C++ (mapping a C++ API directly to C = incredibly bad idea), and I'd really like to keep this in C to keep it as simple as possible.
Title: Re: minisphere
Post by: Flying Jester on January 31, 2015, 12:35:33 am
I support this idea!

SFML is also not very friendly to OS X or other more alternative OS's (neither is CMake, which is primarily what stopped me from manhandling it).

Have you considered SDL2 (or SDL 1.2 if you want super-mega portability)? It's a very cleanly C library.
Title: Re: minisphere
Post by: Fat Cerberus on January 31, 2015, 12:18:26 pm
I hadn't thought about SDL.  I'll consider it, especially after seeing how much stuff allegro has with all those plugins.  How much portability would I be losing to go with SDL2 over 1.2?
Title: Re: minisphere
Post by: N E O on January 31, 2015, 01:05:21 pm

How much portability would I be losing to go with SDL2 over 1.2?


The main difference between SDL2 and 1.2 is API changes, especially WRT window handling (which is one of the many things abstracted to their newer image/surface/frame/etc buffer handling API). Most of the extra libraries (especially sdl_audio) do keep their APIs but simply changed internally to be SDL2-compatible at that time.

Support-wise, whatever 1.2 runs on SDL2 still runs on, but SDL2 might recommend a more C++ approach to it.

Re Allegro - It won't hurt to see how far an Allegro-based Sphere-compatible engine can go. If you choose to do it, I'd very much consider promoting it as an official multi-platform alternative to current vanilla 1.5, alongside TurboSphere and SSFML. :)
Title: Re: minisphere
Post by: Flying Jester on January 31, 2015, 09:38:14 pm
NEO: That's not entirely true. SDL2 does not work on some platforms like QNX, SunOS, Windows CE, BeOS, and AmigaOS4 where SDL 1.2 did work, and support is spotty on Solaris, AIX, HP-UX, and Haiku.

So basically, you lose some old-world mobile platforms and QNX, and it becomes hard going on traditional, commercial Unix, and Haiku. I for one do not mourn for the platforms that become unusable. Having Unix, Windows (Win32 and Metro), Haiku, Android, and iOS, in addition to a theoretical HTML5/JSM platform seems like plenty to me.

SDL2 supports compiling out certain portions, too (for instance, the SDL that I distribute with TS has no audio support), but I found that SFML can do that too, and I suspect Allegro could as well.

SDL2 (and for the most part SDL 1.2) are a mix of OOP and procedural code. I find it pretty easy to work with in either C or C++, it doesn't feel all that unnatural in either. I'd say its worth considering, Allegro is fine with me, too. These are all fairly comparable solutions, and I wouldn't say that its 'wrong' to choose any of them.
Title: Re: minisphere
Post by: Fat Cerberus on February 01, 2015, 02:37:57 am
So Allegro's API is actually quite nice.  Much less boilerplate required to get things up and running compared to SFML.  Just create a display and an event queue, and then a main loop that calls al_flip_display() and processes events and you're good to go.  SFML was such a pain in the ass, requiring creating structures all over the place just to do something as simple as draw a rectangle.

Honestly, Allegro seems like a perfect fit for the backend of a Sphere engine: Its API is very close in structure to the way the Sphere 1.x API is already designed, meaning this should be pretty painless.
Title: Re: minisphere
Post by: Radnen on February 01, 2015, 01:11:10 pm

So Allegro's API is actually quite nice.  Much less boilerplate required to get things up and running compared to SFML.  Just create a display and an event queue, and then a main loop that calls al_flip_display() and processes events and you're good to go.  SFML was such a pain in the ass, requiring creating structures all over the place just to do something as simple as draw a rectangle.


I found the C# binding far easier to use.


Honestly, Allegro seems like a perfect fit for the backend of a Sphere engine: Its API is very close in structure to the way the Sphere 1.x API is already designed, meaning this should be pretty painless.


I agree.
Title: Re: minisphere
Post by: Fat Cerberus on February 01, 2015, 11:31:40 pm
What should I return from GetVersion()?  I'm assuming 1.5 since that's the API I'm shooting to be compatible with...
Title: Re: minisphere
Post by: Radnen on February 01, 2015, 11:40:51 pm

What should I return from GetVersion()?  I'm assuming 1.5 since that's the API I'm shooting to be compatible with...


Yes, otherwise some games won't work. ;)
Title: Re: minisphere
Post by: Fat Cerberus on February 02, 2015, 02:07:47 am
So fairly big showstopper I just hit: Duktape creates and writes JS objects entirely in-engine with the only thing existing on the native side being the code of native functions.  There doesn't appear to be a way to create an object on the native side (e.g. a sound) and have data associated with it that is invisible to JS (pointers or handles, say) but readily accessible to native code.  The only facility Duktape supplies for this purpose is the "stash", which is itself an in-engine (but invisible to script) JS object and global to the JS context--not exactly suitable.

So yeah, not really sure what to do here.

edit: Also, Allegro's handling of alpha is... odd.  I draw two overlapping rectangles, both with alpha 0.  These should be completely invisible, right?  Instead I get this...

edit 2: Well, I figured it out the alpha issue anyway, Allegro's default blend mode assumes premultiplied alpha, so I just had to change it using al_set_blender()
Title: Re: minisphere
Post by: Fat Cerberus on February 04, 2015, 10:59:15 pm
Okay, so Duktape is very strange.  If you try to retrieve the location (file and line number) of a script error, it instead gives you the filename of the C source file which called the script and the line in that file where the Duktape call was made.  For instance, calling Abort() reports that the error happened in sphere_api.c on line 49--in other words, the duk_error call.  Even for, say, syntax errors though, it seems to correctly report the line in the script, but not the filename--instead it returns the path of the C file making the duk_peval_*() call.

Here's where things get strange though: It correctly reports the source file and line number for the duk_error() call even in release mode, where that information shouldn't even be available (there's no debugging info).  What sorcery is this?
Title: Re: minisphere
Post by: Flying Jester on February 05, 2015, 03:12:09 am
I'll guess that it's a macro, and uses the __LINE__ and __FILE__ macros. That's how assert.h's assert() does it.
Title: Re: minisphere
Post by: Fat Cerberus on February 06, 2015, 03:00:41 pm
Yeah, that's what it is, half of Duktape's API is just macros that call internal functions.  Thank goodness Intellisense works with macros now (it never used to, at least it didn't the last time I used VC++), otherwise that would be annoying as hell.

I also did some reading and found out I can store internal state for native-created JS objects.  It's simple, too: On the native side, you just set properties on the object with identifiers starting with 0xFF as the first character.  Since that creates an invalid UTF-8 string, such properties aren't accessible on the JS side but the native code can access them easily.
Title: Re: minisphere
Post by: Flying Jester on February 06, 2015, 06:49:35 pm
Does that mean that duktape makes no distinction from numerically-defined properties and string-defined properties?

I actually don't if a JS engine properly has to, but both V8 and SM make a clear distinction there.
Title: Re: minisphere
Post by: Fat Cerberus on February 06, 2015, 07:43:04 pm
Technically, at least according to the Duktape docs, the JS spec says that all properties (including array indices!) are canonically keyed by string, however:

http://duktape.org/guide.html#programming.6

Duktape special-cases arrays so that if you're only accessing properties by number, it's fast.
Title: Re: minisphere
Post by: Fat Cerberus on February 07, 2015, 11:44:50 am
So something interesting I found out: Duktape uses reference counting for garbage collection, only falling back on mark/sweep if refcounting fails to free the object--i.e. circular refs.  Which means a call like the following:

Code: (javascript) [Select]
LoadSound('bgm.ogg').play();


...will cause the garbage collector to finalize and free the sound as soon as play() returns (meaning this snippet is effectively an expensive no-op under Duktape), whereas, say, SpiderMonkey, the sound might actually stick around for a while.  Something to keep in mind.

As for actual minisphere news, I've implemented about half of the Sound API (NOT the SoundEffect API though, that's a different beast entirely), meaning minisphere can load and play music and sounds now!  It definitely helps that the learning curve on Allegro (and even Duktape, for the most part) is practically non-existent, which is awesome.  Now I remember why I used to love coding in C.  Sure, it's ridiculously easy to shoot yourself in the foot (although perhaps not quite so bad as C++), but the language is so simple that, for the most part, it ends up being self-documenting.
Title: Re: minisphere
Post by: DaVince on February 07, 2015, 03:56:26 pm
Nice work on this! I've quietly been following it in the background.


Yeah, that's what it is, half of Duktape's API is just macros that call internal functions.

If that's how it works, the name "Duktape" sounds very appropriate.

Quote
NOT the SoundEffect API though, that's a different beast entirely

Well, SoundEffect wasn't a part of Sphere 1.5 anyway. :)
Title: Re: minisphere
Post by: Fat Cerberus on February 07, 2015, 04:03:56 pm


Yeah, that's what it is, half of Duktape's API is just macros that call internal functions.

If that's how it works, the name "Duktape" sounds very appropriate.

Quote
NOT the SoundEffect API though, that's a different beast entirely

Well, SoundEffect wasn't a part of Sphere 1.5 anyway. :)


The api.txt that comes with Sphere 1.5 includes it... nothing like documenting a feature that doesn't exist.
Title: Re: minisphere
Post by: DaVince on February 07, 2015, 04:04:45 pm
Oh, that's interesting. I was pretty sure FBNil added the feature in 1.6... but I guess I was wrong then? :P
Title: Re: minisphere
Post by: Radnen on February 07, 2015, 04:19:54 pm

Oh, that's interesting. I was pretty sure FBNil added the feature in 1.6... but I guess I was wrong then? :P


It was experimental, I think. FBNil made it non-experimental. But then 1.6 is still an alpha version of Sphere still to this day.
Title: Re: minisphere
Post by: Fat Cerberus on February 07, 2015, 05:06:42 pm
So is there a safer (not subject to buffer overflows) version of sprintf() I can use?  sprintf_s() is VC++-only, and C99 support in VC is abysmal, meaning no snprintf() either.  See, my code for normalizing paths looks like this:

Code: (c) [Select]
char*
normalize_path(const char* path, const char* base_dir, char* out_abs_path)
{
char* game_path = "C:/cowz";
char* norm_path = strdup(path);
size_t path_len = strlen(norm_path);
for (char* c = norm_path; *c != '\0'; ++c) {
if (*c == '\\') *c = '/';
}
if (norm_path[0] == '/' || norm_path[1] == ':')
// absolute path - not allowed
return NULL;
bool is_homed = (strstr(norm_path, "~/") == norm_path);
if (is_homed) {
sprintf(out_abs_path, "%s/%s", game_path, norm_path + 2);
}
else {
sprintf(out_abs_path, "%s/%s/%s", game_path, base_dir, norm_path);
}
free(norm_path);
return out_abs_path;
}


Which is obviously subject to buffer overflow.  Not a good thing considering Sphere takes JS as input--too much leeway for exploits using overly-long paths.
Title: Re: minisphere
Post by: Flying Jester on February 07, 2015, 08:38:42 pm
You should check out using parts of BSD's libc. That's what I've been doing for my Kashyyk IRC client when I want some reasonable C-string support with MSVC.

For instance, I imported BSD libc's strcasestr function (look here, strcasestr.c, strcasestr.h, str-two-way.h (https://github.com/FlyingJester/Kashyyyk/tree/master/kashyyyk/platform)) for use with MSVC (and in more recent builds, MingW as well). I only compile the functions I need, not the entire library.
BSD's libc seems to be intended to work with pretty archaic and incapable compilers, and so it seems to mostly work with even MSVC, which it has no real reason to support. It also has very confined systems, so in the case of strcasestr, I only needed one extra file besides the source file and header for the function I wanted (and even then just a header).

Alternatively, just put in some defines or def'ed out functions that adapt snprintf, sprintf+strlen, and sprintf_s depending on what is available to the compiler. That way you can get sprintf_s and snprintf when they are available, and have a safe, if less efficient default when neither exists. I do that for `strdup' in TurboSphere. One define that uses strdup, one with strdup_, an inline function that uses strlen, malloc, and memcpy to replicate it.
Title: Re: minisphere
Post by: Radnen on February 07, 2015, 09:10:05 pm

Alternatively, just put in some defines or def'ed out functions that adapt snprintf, sprintf+strlen, and sprintf_s depending on what is available to the compiler. That way you can get sprintf_s and snprintf when they are available, and have a safe, if less efficient default when neither exists. I do that for `strdup' in TurboSphere. One define that uses strdup, one with strdup_, an inline function that uses strlen, malloc, and memcpy to replicate it.


This.
Title: Re: minisphere
Post by: Fat Cerberus on February 08, 2015, 01:59:14 am
...and I've just hit the one thing I absolutely hate about C: String processing.  Even just to parse the command line to interpret -game "<game dir>" is ridiculous.  Also, Duktape isn't particularly fast--in fact, I think it might even be slower than the SM in Sphere 1.5.  I had minisphere try to run Specs (which has lots of RequireScript in main.js), and there was about a half-second delay between the game window showing up and the JS error due to undefined identifiers (i.e. unimplemented APIs).  Granted, this was under the VC debugger, so I'm sure I took a performance hit just for that, but even so...

I'm starting to wonder how viable this project actually is. :(
Title: Re: minisphere
Post by: Flying Jester on February 08, 2015, 02:29:48 am
You could check out using stdargs (or was it stdarg?) for that. Or for more generally strings, something the NSPR. There is a reason that a LOT of C-based projects either have or use some system other than just raw C-strings for their string representations.

It shoudn't be that hard to do arg parsing like that in C. TurboSphere did its argument parsing in pure C up until very recently.

It's possible that duktape is much slower on error conditions (like an uncaught exception). That's true of a lot of virtual machines, especially because often there's not a lot of reason to be fast when you can't recover.
Title: Re: minisphere
Post by: Fat Cerberus on February 08, 2015, 10:47:46 am
Yeah, I found out from playing around that the game dir comes into main() as argv[1] = "-game" and argv[2] = <game dir> conveniently sans quotes, making it simpler than expected.  Of course, this was AFTER writing code to parse the full command line... oh well.

Can I count on this behavior though, or do there exist compilers that pass the full command line to main() as a single argument?

Also, MS apparently doesn't like strdup and getcwd (and probably some others).  The compiler complains that "The POSIX name is deprecated, use _strdup instead."  Last I checked, these weren't deprecated in any standard...  I would really like a clean build without preprocessor cruft everywhere, but that's looking more and more impossible.  Pure C is apparently not as portable as everyone makes it out to be.
Title: Re: minisphere
Post by: Flying Jester on February 08, 2015, 02:09:41 pm
You can count on un-escape spaces to separate arguments.

Code: [Select]

./engine -game startup
# argv[0] engine
# argv[1] -game
# argv[2] startup


Code: [Select]

./engine -game\ startup
# argv[0] engine
# argv[1] -game startup


Code: [Select]

./engine "-game startup"
# argv[0] engine
# argv[1] -game startup


This is true on bash and sh compatible shells, and on CMD. So you can properly count on it.

The posix names are deprecated in MSVC. `strdup' is, in fact, not pure C. If you want to be portable, you should consider something like this:

Code: [Select]


#ifdef _MSC_VER
#define STRDUP strdup_
#else
#define STRDUP strdup
#endif



Recently I've not been doing that, though. I begin to seriously doubt that MSVC's standard library will ever lose the posix names.

You can see on github how I dealt with paths in Kashyyyk, which is what how TurboSphere does it is based on:

https://github.com/FlyingJester/Kashyyyk/blob/master/kashyyyk/platform/win32_paths.c (https://github.com/FlyingJester/Kashyyyk/blob/master/kashyyyk/platform/win32_paths.c)
https://github.com/FlyingJester/Kashyyyk/blob/master/kashyyyk/platform/unix_paths.c (https://github.com/FlyingJester/Kashyyyk/blob/master/kashyyyk/platform/unix_paths.c)
https://github.com/FlyingJester/Kashyyyk/blob/master/kashyyyk/platform/cocoa_paths.m (https://github.com/FlyingJester/Kashyyyk/blob/master/kashyyyk/platform/cocoa_paths.m)
Title: Re: minisphere
Post by: Fat Cerberus on February 10, 2015, 07:23:15 pm
Let me just say for the record that Allegro is awesome.  So much stuff is built in that I never expected to be, I always thought it was just a graphics library.  For instance, a platform-agnostic way of handling file paths, avoiding all the path-parsing headaches discussed above.  Also: INI-style config management, meaning I don't even have to parse game.sgm myself, I can let Allegro do it. ;D

One potential source of incompatibility, though: Duktape doesn't recognize const, it causes a syntax error.  I realize it's not standard JS, but SpiderMonkey handles it without issue, so any existing Sphere game that declares things const won't run in minisphere.
Title: Re: minisphere
Post by: Radnen on February 10, 2015, 09:05:11 pm

One potential source of incompatibility, though: Duktape doesn't recognize const, it causes a syntax error.  I realize it's not standard JS, but SpiderMonkey handles it without issue, so any existing Sphere game that declares things const won't run in minisphere.


Same with Jurassic! I was able to modify the code though so I am using technically a modified version of it. You could do a RegEx replacement of const to var, but you have to make sure it's only ever in the context of a variable declaration and not say, in some text or a comment (meaning you'll have to write a custom pre-processor parser).
Title: Re: minisphere
Post by: Fat Cerberus on February 11, 2015, 10:42:50 am
Okay, so I think minisphere actually isn't too far off from being able to run Spectacles.  I think I just need surface support, which shouldn't be too difficult, and .rfn font support (plus associated text-drawing functions), which... may be harder.

See, Allegro has a function to register your own font loader, al_register_font_loader(), which I could use to let it load .rfn fonts, but here's the issue: The documentation for the ALLEGRO_FONT structure is, well, pretty much nonexistent--even a Google search turns up nothing of use.  Which leaves me only to look at how Allegro loads fonts internally to try to figure it out myself, and even that wasn't particularly helpful at last attempt.

I knew I had to hit a snag eventually.
Title: Re: minisphere
Post by: Flying Jester on February 11, 2015, 04:52:16 pm
It's not too difficult to even draw bitmap fonts yourself. Especially if you are using an immediate API.

I actually think .rfn (and .rws) support would best be done in script. I'm going to do that with TurboSphere.
Title: Re: minisphere
Post by: Fat Cerberus on February 11, 2015, 05:43:34 pm
See, I would do stuff in script, but Duktape is actually pretty slow so I need all the performance help I can get by doing stuff natively.  Besides, if I let allegro load the font instead of drawing the bitmaps manually, I get stuff like WrapText etc. basically for free instead of having to implement it myself.
Title: Re: minisphere
Post by: Fat Cerberus on February 12, 2015, 02:16:28 pm
So I finally got Allegro loading RFN fonts, and it actually seems to work pretty well.  Only issue: Apparently RFN fonts are actually stored fixed-width (including the default system font), despite vanilla Sphere rendering them variable-width--and the format supports it even!  This means naively rendering characters according to their associated glyphs' widths causes the string to be spaced quite far apart.  Still haven't figured out how to fix this yet.

I guess I could crop the glyph bitmaps at load time, but I'm reluctant to do so because that would mess with RFNs that were actually saved variable-width and would thus already be tuned for proper kerning, etc.

EDIT: Nevermind, ignore me, I'm an idiot.  The cause of my incorrect text rendering was this brain fart here:
Code: (c) [Select]
static int
rfn_render_char(const ALLEGRO_FONT* f, ALLEGRO_COLOR color, int ch, float x, float y)
{
rfn_font_t* rfn = f->data;
rfn_glyph_t* glyph = &rfn->glyphs[ch];
al_draw_tinted_bitmap(glyph->bitmap, color, x, y, 0x0);
return glyph->header.height; // <-- see, it's supposed to return the WIDTH of the char...
}
Title: Re: minisphere
Post by: N E O on February 13, 2015, 04:57:01 pm
Just out of curiosity, is anyone else here seeing centered code blocks on Lord English's C examples? I want to double-check if I need to edit more than one theme to fix that.
Title: Re: minisphere
Post by: DaVince on February 13, 2015, 05:19:37 pm
Looks like this here: http://i.imgur.com/C6o9Lgk.png
Title: Re: minisphere
Post by: Flying Jester on February 13, 2015, 05:40:51 pm
@NEO They appear correctly for me in Fx. I tested in Safari and Lynx too, just because you mentioned it, no issues there either.
Title: Re: minisphere
Post by: Radnen on February 13, 2015, 09:26:21 pm
NEO: Seems good on the default theme.
Title: Re: minisphere
Post by: N E O on February 14, 2015, 12:54:35 pm
Ok, so the issue is only with my unreleased Spherical theme; I know what needs to be fixed and how, I just wanted to make sure it was only one theme.
Title: Re: minisphere
Post by: DaVince on February 14, 2015, 02:47:59 pm
I thought I was supposed to have the Spherical theme. Could you enable it for me?
Title: Re: minisphere
Post by: Fat Cerberus on February 15, 2015, 10:00:37 am
Spectacles runs in minisphere!  There seems to be a good deal of lag on slower machines, though.  Not sure yet if the bottleneck is rendering-related (Allegro) or Duktape though.
Title: Re: minisphere
Post by: Radnen on February 15, 2015, 11:31:31 am
Wow that was fast!
Title: Re: minisphere
Post by: Fat Cerberus on February 15, 2015, 11:58:49 am
Yeah, as it turns out the Sphere 1.5 API isn't all that complicated, there's just a LOT of functions.  Most of the graphics APIs would be about 3-5 lines of code if it weren't for all the stack juggling Duktape requires.

So, who's up for trying to compile minisphere on something other than Windows to see how it works? :D
Title: Re: minisphere
Post by: N E O on February 15, 2015, 02:29:37 pm

I thought I was supposed to have the Spherical theme. Could you enable it for me?


It says you already have it, hm...
Title: Re: minisphere
Post by: Flying Jester on February 15, 2015, 10:23:07 pm

Yeah, as it turns out the Sphere 1.5 API isn't all that complicated, there's just a LOT of functions.  Most of the graphics APIs would be about 3-5 lines of code if it weren't for all the stack juggling Duktape requires.


Implementing the Sphere graphics API was precisely what lead me to believe that it would be better to have a very small API, even if it were a little more verbose. That's why TurboSphere just has the Shape and Group objects, and no primitives or even direct Surface or Image blitting at all.


So, who's up for trying to compile minisphere on something other than Windows to see how it works? :D


I can give it a try on some other platforms.

I already tried earlier, and I found the following:

Solaris US: Doesn't work, Allegro doesn't work there.
FreeBSD: Same
Haiku: Same

But I assume you are more interested in Linux and OS X.
Title: Re: minisphere
Post by: Fat Cerberus on February 15, 2015, 11:23:34 pm


Yeah, as it turns out the Sphere 1.5 API isn't all that complicated, there's just a LOT of functions.  Most of the graphics APIs would be about 3-5 lines of code if it weren't for all the stack juggling Duktape requires.


Implementing the Sphere graphics API was precisely what lead me to believe that it would be better to have a very small API, even if it were a little more verbose. That's why TurboSphere just has the Shape and Group objects, and no primitives or even direct Surface or Image blitting at all.


So, who's up for trying to compile minisphere on something other than Windows to see how it works? :D


I can give it a try on some other platforms.

I already tried earlier, and I found the following:

Solaris US: Doesn't work, Allegro doesn't work there.
FreeBSD: Same
Haiku: Same

But I assume you are more interested in Linux and OS X.


Yeah, Linux and OS X are my main concerns.  Honestly I don't know anyone that uses Solaris or FreeBSD (although I assume the latter is more common), and I've never even heard of Haiku.
Title: Re: minisphere
Post by: Radnen on February 16, 2015, 12:32:26 am
I keep getting a "syntax error: parse error (line 10)". I've tried to run the startup game or other games, but with no luck.

I'm also surprised that for a minisphere it's the same size on disk as my SSFML. But the memory use should be much, much shallower in yours.
Title: Re: minisphere
Post by: Fat Cerberus on February 16, 2015, 01:03:54 am

I keep getting a "syntax error: parse error (line 10)". I've tried to run the startup game or other games, but with no luck.

I'm also surprised that for a minisphere it's the same size on disk as my SSFML. But the memory use should be much, much shallower in yours.


Parse error means it encountered const.  If you change the consts to vars, you'll have a better shot at running it.

Also: It's still smaller than Sphere 1.5.  About half the size at last check.  Also a much smaller codebase.  Vanilla Sphere's codebase is frankly huge for such a simple engine.
Title: Re: minisphere
Post by: Flying Jester on February 16, 2015, 01:18:59 am

Also: It's still smaller than Sphere 1.5.  About half the size at last check.  Also a much smaller codebase.  Vanilla Sphere's codebase is frankly huge for such a simple engine.


Even if you include all the Allegro libraries? Sphere's codebase includes the entire editor, too (which has some guts in many shared components), as well as the loaders for many audio file types, image types (including all of libungif), and the binaries include the MSVC runtime, as well as several graphics plugins.

I'd be surprised if, including all the necessary libraries, minisphere was actually able to open all the same file types as Sphere, play most of the same games (stuff like const notwithstanding), and was still less than half the size.
Title: Re: minisphere
Post by: Radnen on February 16, 2015, 01:25:57 am
It still says that error no matter how simple of a script I put in it, even if it has <10 lines code.
Title: Re: minisphere
Post by: Fat Cerberus on February 16, 2015, 01:29:51 am
@FJ:
I'm using the Allegro monolithic library, which is about a 2.25MB DLL and includes all Allegro functionality, including audio (if you're using more than about 3 Allegro components, the monolithic is actually smaller than the individual DLLs).  The minisphere executable at current is around 550KB.  That's literally the entire engine in 2.8MB.  Even if you count the system directory (which I guess technically you should? Full Sphere 1.5 compliance and all): 3.89MB.

Admittedly not a huge difference--ignoring editor.exe and SciLexer.dll, but including config.exe and the system directory, Sphere 1.5 is 5.25MB.  Still, minisphere is smaller, so I think the name still stands! :)

@Radnen:
Very odd.  Give me a code sample that you tried that caused the error, I'll look into it.  It runs Spectacles very well, so...
Title: Re: minisphere
Post by: Radnen on February 16, 2015, 01:32:44 am

@Radnen:
Very odd.  Give me a code sample that you tried that caused the error, I'll look into it.  It runs Spectacles very well, so...


Well, it does it for anything, even if I use dll files, etc. how are you playing games with it? Do you drag them on to the executable or do you put everything into the startup folder? Because the startup game also did the same thing.
Title: Re: minisphere
Post by: Fat Cerberus on February 16, 2015, 01:34:16 am
You can put the game into the startup folder, but actually, all you have to do is point Sphere Studio at minisphere and it'll work.  It accepts the -game commandline argument just like 1.5 and SSFML does.
Title: Re: minisphere
Post by: Fat Cerberus on February 17, 2015, 03:13:39 am
So did you get it to run anything?  Specs uses a good chunk of the API, so I'd expect there must be at least some games out there that work.  Although most games use the map engine, so perhaps not...  Note that the startup game won't work even if you remove the consts as I didn't implement ExecuteGame et al. yet.

Anyway, I've just started on the map engine and am currently trying to get In the Steps of the Blackfoot running.  That was the game that introduced me to Sphere, so I kind of have a soft spot for it. :)
Title: Re: minisphere
Post by: Flying Jester on February 17, 2015, 03:19:28 am

Note that the startup game won't work even if you remove the consts as I didn't implement ExecuteGame et al. yet.


ExecuteGame is very challenging to implement with most JS engines. It's extremely difficult, or just plain impossible for V8 to cancel execution of a script from native. I am unsure of how difficult it is with SM, although it seems to have better support for such an idea. I would think that JS engines not expressly intended for a web browser may actually have an advantage here.

I basically have just written this part of the API off. It's a cool feature, but ultimately not that useful. I don't lose much sleep knowing the startup games don't run.
Title: Re: minisphere
Post by: Fat Cerberus on February 17, 2015, 03:27:11 am
That's the awesome thing about Duktape--everything is done in-engine, and the call to game() is protected, meaning all I have to do to bail out of script execution (including infinite while(true) loops!  Assuming they call FlipScreen anyway...) is throw an exception via duk_error().  This drops me off immediately after the duk_pcall, with the exception on the stack.  This is the same mechanism I use to bail out when the game window is closed, and it's awesome.
Title: Re: minisphere
Post by: Radnen on February 17, 2015, 12:32:44 pm

I basically have just written this part of the API off. It's a cool feature, but ultimately not that useful. I don't lose much sleep knowing the startup games don't run.


Not so fast! There is a... compromise. You could spawn an entirely new instance of Sphere. So you would have two games running simultaneously, but if you minimize one and play the other you should be fine. I'm intending to do this with SSFML.
Title: Re: minisphere
Post by: Flying Jester on February 17, 2015, 05:16:36 pm


I basically have just written this part of the API off. It's a cool feature, but ultimately not that useful. I don't lose much sleep knowing the startup games don't run.


Not so fast! There is a... compromise. You could spawn an entirely new instance of Sphere. So you would have two games running simultaneously, but if you minimize one and play the other you should be fine. I'm intending to do this with SSFML.


You mean an OS-level instance of Sphere? Like with `exec`?

That's an option. I for one would far prefer the engine actually be capable of starting and stopping, but so far that has been difficult.

I know that in Posix systems it would even be simple to startup a new Sphere process and assign it to a nohup parent process...hmm...
Title: Re: minisphere
Post by: Radnen on February 17, 2015, 05:45:51 pm

You mean an OS-level instance of Sphere? Like with `exec`?


Precisely.
Title: Re: minisphere
Post by: Fat Cerberus on February 18, 2015, 10:20:25 am
So out of morbid curiosity, I ran SSFML's startup game in minisphere and tried the surface fill test, one of the few things in there that actually works.  My results: ~1400 FPS.  Screenshot attached as proof. ;D

Of note: The main menu runs at around 700FPS on the same machine.

Laptop is i5-2450M with 4GB RAM, Win8.1 Pro x64.

Edit: In the interest of completeness, I also ran the test on Sphere 1.5.  It barely broke 550 FPS on the same machine.  Honestly, my experience so far has been that minisphere actually outperforms Sphere 1.5 in all cases.  At least with the standard32 plugin, anyway.  I should probably test it with the OpenGL plugin at some point...
Title: Re: minisphere
Post by: Radnen on February 18, 2015, 12:45:08 pm

So out of morbid curiosity, I ran SSFML's startup game in minisphere and tried the surface fill test, one of the few things in there that actually works.  My results: ~1400 FPS.  Screenshot attached as proof. ;D


Yep, you have better surfaces, even better than 1.5. But with HW surfaces in SSFML I could do 6500 fps on that same screen (~900 in Sphere 1.5 for comparison). I do 700 fps on that screen in SW (so worse than Sphere). But, only when many HW surfaces and features were used the fps started going way way down, it's like SFML just can't handle more than 2 or 3 surfaces on screen at the same time. I find this odd since I use hardware surfaces for tile animations in the map engine and it's really fast. But then again it's just a single surface.
Title: Re: minisphere
Post by: Flying Jester on February 18, 2015, 06:11:16 pm
The startup game is one of the worst games I know of. It does things that are exceedingly bad.

I'd be curious how FJ-GL does on your machine. I got about 600 FPS on the main menu using an ancient Dell D630.
Title: Re: minisphere
Post by: Fat Cerberus on February 18, 2015, 07:01:46 pm
I was referring to the SSFML startup game (essentially a test suite), not the default one that comes with 1.5.
Title: Re: minisphere
Post by: Fat Cerberus on February 18, 2015, 10:06:28 pm
New feature: You can change minisphere's taskbar icon by putting an image in the same directory as game.sgm with the filename game-icon.png.
Title: Re: minisphere
Post by: Fat Cerberus on February 19, 2015, 02:47:23 am
Okay so minisphere SUCKS at rendering windowstyles.  The "big window" test in Radnen's test suite?  30 fps.  Surface fill hits 1400fps easy, but it can't even maintain 60fps drawing a window?  What the hell? ???

From what I can tell, the tiling is what's doing it.  Disabling the window background as a test, it hit 1600 fps.  Which is weird, since it's just drawing the same bitmap multiple times, and I'm even batching them (unbatched, for the curious, it dropped to 3(!) fps).

This is a stumper.
Title: Re: minisphere
Post by: Radnen on February 19, 2015, 12:44:27 pm
The big window test is notoriously difficult on the graphics because it tiles a 1x1 pixel background image (in practice you won't see this). Compare to Standard32 Sphere 1.5 and SphereGL. I think SphereGL bottoms out at 2fps, or some other horrendously low number (even on my Nvidia GTX 970). In practice, try a windowstyle with a 16*16 or greater background image. Now, that said, if you are batching the image I'm really curious why you only get 30fps. Allegro must be doing some pretty naive graphics processing, despite the fact you can tell it to "defer" the drawing. I say this because you can totally do better with surfaces.
Title: Re: minisphere
Post by: Fat Cerberus on February 19, 2015, 01:40:38 pm
Standard32 Sphere manages 415 fps in the big window test (AMD A10-6800K), 13 with sphere_gl.  Note that on the same machine, this (13fps) is identical to minisphere's result.  I wonder if Allegro is using OpenGL under the hood?

No idea how SSFML pulls 3000fps in this test.  You must have one hell of a sprite batcher.
Title: Re: minisphere
Post by: Flying Jester on February 19, 2015, 02:11:19 pm
There are, I suspect, two reasons that the SphereGL driver sucks at this. The first is that sending so many vertices takes a lot of time, and bandwidth is the main limiting factor for doing hardware graphics. This is just a general issue with older OpenGL, and why using a newer version like 3.3 or 4.1 is better, because it makes doing that impossible.
The second issue is that SphereGL decides to unbind textures and disable texturing at the end of every call. This was the main place I saw for improvement when I wrote FJ-GL. There I do this lazily, just binding what ever texture I need at the start of every call, and using a 1px white texture for primitives.

I would suspect that with SphereGL, almost all of the time is spent binding, unbinding, enabling, and disabling texturing. Even if that wasn't happening, it's still deluging the GPU with vertices, which is generally not what you want to do.

An alternative would be to actually use UV coordinates to do hardware tiling of the texture, but the Sphere graphics driver API doesn't have that feature. Before I moved windowstyles to script in TS, this is what I did.
Title: Re: minisphere
Post by: Fat Cerberus on February 19, 2015, 03:06:03 pm
Hm, allegro lets me draw textured triangles via al_draw_prim().  I use this for my implementation of GradientRectangle.  I should test that later...

Oh, also abysmally slow in minisphere: GrabImage.  The SSFML image test runs at around 15fps.  Sphere 1.5 and SSFML both handle this test with aplomb.  Allegro must not like me using the backbuffer as a blit source...

Edit: I tried out the U/V hardware tiling, it seems to work pretty well, except for the SSFML Big Window test.  This is what I got.  Does the hardware not like tiling 1x1 textures?
Title: Re: minisphere
Post by: Radnen on February 19, 2015, 04:58:02 pm

Edit: I tried out the U/V hardware tiling, it seems to work pretty well, except for the SSFML Big Window test.  This is what I got.  Does the hardware not like tiling 1x1 textures?


Yes. I was not sprite-batching that 1x1 pixel, I was U/V wrapping it. Essentially I'm letting the gpu do the tiling rather than physically inputting the coords of the tiles, so I'm really only sending 4 vertices to the gpu while the rasterizer does an excellent job at tiling it. I apply this technique for the sides as well, don't forget those! That Big Window test should run really fast if done right. I'd love to use the U/V method to speed up my tile maps but it assumes it's the same image being repeated, and for tile maps the tiles change.

As for your error, are you sure you are tiling it correctly? It seems to tile at 16x16 rather than 1x1, don't use the corner size for the background image size.
Title: Re: minisphere
Post by: Fat Cerberus on February 19, 2015, 05:00:05 pm
Yeah, I got it to run at 1k+ fps, but it's not being tiled correctly.  The normal window test it tiles file, but the 1x1 background... See above.
Title: Re: minisphere
Post by: Radnen on February 19, 2015, 05:01:45 pm
ooops, you got me mid edit. I did a double check, and maybe you are tiling with the wrong parameters?

As for your lower than mine FPS, it might just be duktape?
Title: Re: minisphere
Post by: Fat Cerberus on February 19, 2015, 05:12:20 pm
Code: (c) [Select]
vertex_color = al_map_rgba(255, 255, 255, 255);
ALLEGRO_VERTEX v[] = {
{ x, y, 0, 0, 0, vertex_color },
{ x + width, y, 0, width, 0, vertex_color },
{ x, y + height, 0, 0, height, vertex_color },
{ x + width, y + height, 0, width, height, vertex_color }
};
al_draw_prim(v, NULL, bitmap, 0, 4, ALLEGRO_PRIM_TRIANGLE_STRIP);


Coord order is XYZ, UV.
Title: Re: minisphere
Post by: Radnen on February 19, 2015, 05:36:48 pm
And width and height are 1 here? I see single variables here, something has to tell it tile a 1x1 sized object in a WxH sized area.
Title: Re: minisphere
Post by: Flying Jester on February 19, 2015, 06:29:41 pm

And width and height are 1 here? I see single variables here, something has to tell it tile a 1x1 sized object in a WxH sized area.


How does Allegro do it? In OpenGL, you would just use a UV that is the number of times you want it tiled horizontally and vertically, respectively. You never need to specify the source texture's size in any way, because it's 'size' is normalized to 1.0fx1.0f before the texturing stage.
Title: Re: minisphere
Post by: Fat Cerberus on February 19, 2015, 06:41:37 pm
The code samples I've seen you specify pixels in the range of (0,0)-(w, h) for UV.  Maybe just because Allegro is designed for 2D or perhaps a remnant of its all-SW-rendered days.  I'll experiment more later.
Title: Re: minisphere
Post by: Fat Cerberus on February 19, 2015, 07:19:33 pm
https://www.allegro.cc/manual/5/ALLEGRO_VERTEX

Quote
u, v - Texture coordinates measured in pixels


So yeah, Allegro uses direct pixel offsets into the image for UV.
Title: Re: minisphere
Post by: Flying Jester on February 19, 2015, 07:48:59 pm
Ah, so it's 100% in raster coordinates, no normalization at all.

In that case, I'd expect your code to work. Maybe an Allegro issue with 1x1 textures?
Title: Re: minisphere
Post by: Radnen on February 19, 2015, 10:48:33 pm
Raw JS benchmark on my machine, in milliseconds, lower is better, in fps, higher is better (rounded to nearest ten just to look pretty):

Code: (javascript) [Select]

function game() {
var t = GetTime();

for (var i = 0; i < 10000000; ++i) {  }

Abort(GetTime() - t);
}


Sphere 1.5: 1090
MiniSphere: 472
Sphere SFML: 23

Code: (javascript) [Select]

function game() {
var fps  = 0;
var tfps = 0;
var t2   = GetTime();

while (t2 + 5000 > GetTime()) {
fps++;
Rectangle(0, 0, GetScreenWidth(), GetScreenHeight(), red);
FlipScreen();
}

Abort(fps / 5);
}


Sphere 1.5: 3000
Minisphere: 11500
Sphere SFML: 7900

Code: (javascript) [Select]

function game() {
var fps  = 0;
var tfps = 0;
var t2   = GetTime();

while (t2 + 5000 > GetTime()) {
fps++;
f.drawText(0, 0, "Hello World! Hello World! Hello World! Hello World! Hello World!");
FlipScreen();
}

Abort(fps / 5);
}


I will say minisphere draws shorter strings much faster, but it slows down longer the string. SSFML never slows down on almost any string length.

Sphere 1.5: 4900
Minisphere: 6250
Sphere SFML: 7250

Edit:
I'd say I'm rather pleased with the speed of minisphere. It draws things much faster than I had ever anticipated. I've NEVER seen an fps higher than 8500 on this machine in SSFML, but on my Win7 I can get to 10,000 with SSFML (weird, huh). So, it's awesome to see minisphere get 11,500+.

Edit 2:
In terms of space, to load the demos above:
Sphere 1.5: 3.8MB
minisphere: 8.9MB
Sphere SFML: 39.8MB (!!)

Crazy how C/C++ programs utilize so little space!
Title: Re: minisphere
Post by: Fat Cerberus on February 20, 2015, 12:14:26 am

In terms of space, to load the demos above:
Sphere 1.5: 3.8MB
minisphere: 8.9MB
Sphere SFML: 39.8MB (!!)

Crazy how C/C++ programs utilize so little space!


I assume this is RAM usage?  But yeah, I'm happy see that, outside of memory footprint (which is still tiny, let's be honest here :) ), minisphere soundly kicks Sphere 1.5's ass.  That was one of my main goals with the project, since Sphere 1.5 was really starting to show its shortcomings performance-wise with Specs, especially on less powerful machines.  Somehow, some way, Duktape, even being all-bytecode with no JIT to speak of, is STILL more than twice as fast as 1.5's Spidermonkey.

It's also good to see that you got it to build.  I was going to include the Allegro binaries in the repo, but decided it wasn't necessary since I'm just using pre-built binaries that are, at present, readily available on the web.  It's just a matter of unzipping them to the proper location.  I tried to make it as painless as possible other than that, as long as you're using Visual Studio anyway!

At some point I'm going to have to try to build minisphere on Linux.
Title: Re: minisphere
Post by: Flying Jester on February 20, 2015, 12:43:48 am
So I got minisphere building on OS X again.

Same as last time, it just locks up hard when it starts up. I know that I have no startup folder or games folder, but still...

EDIT:

Nevermind, it deadlocks even with directories nicely in place. I'll investigate.
Title: Re: minisphere
Post by: Fat Cerberus on February 20, 2015, 12:55:59 am
There's a check in place, if there's no startup folder you're supposed to get an error message like the one pictured in this screenshot.  Maybe OS X and Allegro don't get along?

Title: Re: minisphere
Post by: Radnen on February 20, 2015, 12:56:19 am
minisphere only worked with the -game parameter. I just used my Sphere Studio. Building it was easy, I just didn't know how to start running a game. The startup game had consts and so it failed, and dragging a .sgm onto the executable didn't run the game.

@LordEnglish: yes, I meant RAM. .NET apps use the CLR and .NET runtime which are memory hogs, but if I account for that I still get about 20+MB's RAM usage out of it... so it's still a memory hog (but I'm not really going to worry about that, it's just a curiosity).
Title: Re: minisphere
Post by: Fat Cerberus on February 20, 2015, 01:01:25 am

minisphere only worked with the -game parameter. I just used my Sphere Studio. Building it was easy, I just didn't know how to start running a game. The startup game had consts and so it failed, and dragging a .sgm onto the executable didn't run the game..


Does drag-and-drop work with Sphere 1.5?  Last time I tried I thought it didn't work, so I've always just opened stuff in Sphere Studio.  I'll have to implement that now.
Title: Re: minisphere
Post by: Flying Jester on February 20, 2015, 01:08:26 am
It's not the startup folder apparently, it's the system folder. I opened an issue, you are reading the system font without checking that it exists (maybe more things later, that's where it errors out).
Title: Re: minisphere
Post by: Fat Cerberus on February 20, 2015, 01:10:38 am

It's not the startup folder apparently, it's the system folder. I opened an issue, you are reading the system font without checking that it exists (maybe more things later, that's where it errors out).


Yeah, there's a gross lack of sanity checks in here.  You wonder how I implemented this all so fast, well, here's your answer. :P

I'll look into it.

Edit: Found the issue.  There are no checks whatsoever in al_load_rfn_font() despite all my other loading functions having ample error checking.  The crash is because it's trying to read from an ALLEGRO_FILE* that is NULL (because the file didn't exist).
Title: Re: minisphere
Post by: Radnen on February 20, 2015, 02:38:49 am

Does drag-and-drop work with Sphere 1.5?  Last time I tried I thought it didn't work, so I've always just opened stuff in Sphere Studio.  I'll have to implement that now.


Well, Sphere was able to do this magical thing called "registering a filetype", I couldn't seem to do this easily in .net but if I implemented drag and drop, I was able to set the Engine.exe of SSFML to open on default for any .sgm related files and it worked. I can play games in SSFML by double-clicking the .sgm game icon. This is a feature I want to add to Sphere Studio too.
Title: Re: minisphere
Post by: Flying Jester on February 20, 2015, 02:51:12 am

Well, Sphere was able to do this magical thing called "registering a filetype", I couldn't seem to do this easily in .net but if I implemented drag and drop, I was able to set the Engine.exe of SSFML to open on default for any .sgm related files and it worked. I can play games in SSFML by double-clicking the .sgm game icon. This is a feature I want to add to Sphere Studio too.


I think that was something that the installer itself did.

Drag-and-drop is much simpler, fortunately.
Title: Re: minisphere
Post by: Radnen on February 20, 2015, 02:54:10 am

I think that was something that the installer itself did.


File->Options->Register filetypes. But, it doesn't seem to list .sgm, but it does have .spk.
Title: Re: minisphere
Post by: Fat Cerberus on February 20, 2015, 02:56:03 am
That reminds me, at some point I have to add SPK support to minisphere.  That should be fun... :-\
Title: Re: minisphere
Post by: Flying Jester on February 20, 2015, 03:02:33 am
SPK support isn't that bad. It's extremely simple and uses zlib.

I would recommend for simplicity having the engine, when told to `run' an SPK, unpack the SPK into a subdirectory of your engine's root and run the game from there.

Or just don't do SPKs. It's a pretty silly format to begin with.
Title: Re: minisphere
Post by: Fat Cerberus on February 20, 2015, 10:21:58 pm

I would recommend for simplicity having the engine, when told to `run' an SPK, unpack the SPK into a subdirectory of your engine's root and run the game from there.

Or just don't do SPKs. It's a pretty silly format to begin with.


I kind of like the idea having a single file to distribute a game, and I found out I don't even have to unpack it to disk--Allegro lets me open a buffer in memory as a file (sort of like a memory mapped file but in reverse...) that I can pass to loading functions.

Of course, if we're being honest, if I weren't trying for near-1:1 Sphere compatibility I would probably just use zip instead of SPK... Well, I'll see what happens.  Either way it's not a priority for a while at least.
Title: Re: minisphere
Post by: Fat Cerberus on February 21, 2015, 02:14:23 am
(Sort of) new feature: minisphere displays internal FPS when the framerate is throttled, as by calling SetFrameRate().  This helps to differentiate skipped frames from actual slowdown.
Title: Re: minisphere
Post by: DaVince on February 21, 2015, 07:17:47 am
I still wouldn't mind having something like an spk2 format which is really just a zip or tarball you can associate with Sphere.

Nice work, by the way. And yes, you could drag an SGM over engine.exe in 1.5. Used to do it a lot. :)
Title: Re: minisphere
Post by: Fat Cerberus on February 21, 2015, 09:20:48 pm
@Radnen:
Let me just say that the SSFML testbed has been invaluable in filling out the Sphere API.  I'm almost at the point of being able to run all the non-map-engine tests, there's now only 2 or 3 that error out due to missing APIs.  Most of my implementations have gone off without a hitch and produce identical output to SSFML and Sphere 1.5 (outside of the speed tests, which seem universally faster than Sphere 1.5)--except for the surface test.

Here's the thing: I'm not actually sure what's wrong in my implementation because I can't decipher the surface test code.  It creates 4 surfaces and then proceeds to juggle them like crazy, so I don't know where minisphere is failing, but clearly something is screwed up, as you can see in the attached screenshot.  The green-tinged versions of the Blockman sprite are missing, and the whole bottom row is just the green blocks without the rotated silhouette...
Title: Re: minisphere
Post by: Flying Jester on February 21, 2015, 09:38:18 pm

Most of my implementations have gone off without a hitch and produce identical output to SSFML and Sphere 1.5 (outside of the speed tests, which seem universally faster than Sphere 1.5)--except for the surface test.


I'm curious if you've tried the version of Sphere 1.6+ that I compiled with MSVC 2010 a year ago, available at rpgmaker.net/users/FlyingJester/locker/sphere16fj.zip (http://rpgmaker.net/users/FlyingJester/locker/sphere16fj.zip). I found that simply using a newer compiler made the engine between 10% and 50% faster, depending on the situation. Using slightly newer OpenGL with FJ-GL also mad many tests--particularly texturing--up to 25% faster.

I would not be too surprised if you were still faster than that, but it would still be interesting to see the results.
Title: Re: minisphere
Post by: Radnen on February 21, 2015, 10:26:56 pm
I was doing another round of speed tests, this time using my link library.

I have a test where I compare Link.js with Lazy.js and my old Query.js functional programming libraries. I was shocked to see Query.js outpace the other by a magnitude of 10. Lazy execution is just SLOW on both minisphere and Sphere-SFML.

Code: (javascript) [Select]

// times in SSFML:
Link: 966ms
Lazy: 965ms
Query: 76ms

// times in minisphere:
Link: 2300ms
Lazy: 2298ms
Query: 132ms

// times in Sphere 1.5:
(out of memory)

// in 1.5 using 10 times less results:
Link: 300ms
Lazy: 300ms
Query: 19ms


As a reminder, Query is the library I originally made that Link is based off of. The only problem is it doesn't lazy execute the chain. Safe to say, it really is fast and kicks the crap out of the other two if you need it for a tight execution loop. In a web browser, this is not the case and is actually slower by many factors (query forces through the chain n times, where n is each added operation, Link and Lazy go through the chain once).
Title: Re: minisphere
Post by: Fat Cerberus on February 21, 2015, 10:46:33 pm

I'm curious if you've tried the version of Sphere 1.6+ that I compiled with MSVC 2010 a year ago, available at rpgmaker.net/users/FlyingJester/locker/sphere16fj.zip (http://rpgmaker.net/users/FlyingJester/locker/sphere16fj.zip). I found that simply using a newer compiler made the engine between 10% and 50% faster, depending on the situation. Using slightly newer OpenGL with FJ-GL also mad many tests--particularly texturing--up to 25% faster.

I would not be too surprised if you were still faster than that, but it would still be interesting to see the results.


minisphere still beats it, but admittedly by a much narrower margin.  Anything purely script-based though, like the Color creation benchmark, blows minisphere out of the water.  That doesn't surprise me though, since I assume this is TraceMonkey or newer and not the ancient SM in 1.5.

All 1.6FJ tests are with FJ-GL.  Testbed runs at 320x240.  CPU is an AMD A10-6800K and I'm using the GPU built into the chip (Radeon HD 8670D).

Surface Fill Rate: Fills a full-screen surface with solid green via .rectangle() and blits it.
1.6FJ: Hovers around 650 fps.
minisphere: ~2300.

Big Window: Draws a window covering nearly the full screen using a windowstyle with a 1x1 tiled background.
1.6FJ: An abysmal 15 fps.
minisphere: ~2800. (although I haven't fixed that tiling bug yet...)

Many Primitives: Fills the screen with 32x24 GradientRectangles (so 100 of them).  The one test 1.6FJ beats me at.
1.6FJ: ~3000 fps.
minisphere: ~1450.

Surfaces: Creates 4 surfaces and juggles them in odd ways.  As mentioned above, I can't really decipher the test.
1.6FJ: ~320 fps.
minisphere: ~425. (caveat emptor: minisphere doesn't render this test correctly).

Windows: Draws 3 windows using a windowstyle, two of them with a color mask, the second of which continuously expands and contracts. Note that minisphere currently ignores the colormask.
1.6FJ: ~2230 fps.
minisphere: ~2900.

So yes, minisphere is still faster at rendering, in most cases by a sizable margin. ;D
Title: Re: minisphere
Post by: Flying Jester on February 22, 2015, 07:45:57 pm

minisphere still beats it, but admittedly by a much narrower margin.  Anything purely script-based though, like the Color creation benchmark, blows minisphere out of the water.  That doesn't surprise me though, since I assume this is TraceMonkey or newer and not the ancient SM in 1.5.


It's the very last release without any JIT or tracing engine.

For a few things it's still the fastest JS engine I've seen--for example, the empty loop test with lower values (~1000000), probably since it's a very mature interpreter and isn't spending time running the code through any tracers or type analyzers, as modern SpiderMonkey does. In most real-world scenarios, this isn't the case, though.
Title: Re: minisphere
Post by: Fat Cerberus on February 23, 2015, 03:12:56 pm
Just started work on the map engine, and I have a question regarding the RMP format.  The layer header contains the following fields:

Code: [Select]
float32 parallax_x;
float32 parallax_y;
float32 scrolling_x;
float32 scrolling_y;


What I'm wondering is, what do these coordinates represent, exactly?  I know what parallax is, but I'm completely stumped as to what purpose the X/Y coordinates serve.

Also, whose idea was it to make map layers have individual width and height? ???  I can't think of a single circumstance where that makes sense.
Title: Re: minisphere
Post by: Flying Jester on February 23, 2015, 04:41:11 pm

Also, whose idea was it to make map layers have individual width and height? ???  I can't think of a single circumstance where that makes sense.

I know what parallax is

You've answered your own question :)
Title: Re: minisphere
Post by: Fat Cerberus on February 23, 2015, 04:53:06 pm
So what, it just tiles the parallax layer if it's smaller than the main layer(s)?  Besides I thought Sphere's implementation of parallax was just an image, not a real map layer.

That still doesn't answer what the parallax and scrolling X/Y in the layer header are.
Title: Re: minisphere
Post by: Flying Jester on February 23, 2015, 05:08:06 pm
No, a parallax layer could, if a different size, benefit from being larger than the main map layers.

I haven't worked with this in a while, but I'm fairly certain that parallax values control the origin when using parallax, and scrolling control the parallax speeds.

You could just poke those values with a hex editor and see the result, too. That's how I originally figured it out.
Title: Re: minisphere
Post by: Radnen on February 23, 2015, 08:15:09 pm
Parallax X/Y is a value usually default at 1. It is the mutiplier added to the camera for the parallax effect. 1, 1 is neutral, or no movement while 2 is twice as fast, etc.

Scroll X/Y is a value usually default at 0. It is the constant speed that constantly moves the background by that amount. 2 makes it scroll fast (2 pixels), while 1 is slower (the maps FPS dictates apparent speed).
Title: Re: minisphere
Post by: Fat Cerberus on February 24, 2015, 01:27:24 am
So if the scroll values are nonzero, then it scrolls continuously even if the player isn't moving?  That makes sense, then.  I guess you'd use that for a moving cloud background or such.
Title: Re: minisphere
Post by: Fat Cerberus on February 25, 2015, 02:21:12 am
I got the map engine working!  So far it can load the bitmaps from an RTS tileset and load and render a map using the proper tiles.  ChangeMap works.

Oh, and just because I'm meticulous like this: I ran minisphere and Sphere 1.5 at the same time, lined up the windows, Alt+Tabbed between them and the output is identical!  I wasn't sure if I got the alignment on the sprites right or not, but it looks like I did.
Title: Re: minisphere
Post by: Radnen on February 25, 2015, 02:35:31 am
Awesome! The map is the most daunting part. It's not hard to do but there's certainly a lot of pieces in it. To emulate Sphere correctly you'll basically need to copy it's line intersection code for obstructions and the command queue code for movement. I'd be impressed if you manage to get lithonite.js working the way it was intended. (In SSFML it works mostly correctly besides a few edge cases... with edges!)

If you are drawing the layers to surfaces and then drawing the surface to screen, check to make sure you can do tile animations easily and fast enough. That'll be the next big step.
Title: Re: minisphere
Post by: Fat Cerberus on February 25, 2015, 09:55:21 am
I didn't even bother with the extra complexity of surfaces.  I just told Allegro to defer drawing and drew all the visible tiles directly to the backbuffer.  See, I looked into how the deferred drawing works, and what benefits most from it is bitmap drawing--when you defer, Allegro batches all al_draw_bitmap() calls and then sends them all to the GPU at once as a single, huge triangle list.  In theory this should be blazing fast without the need to cache the layers on a surface.  Even more so once I implement atlasing for tilesets (currently each tile gets its own bitmap).
Title: Re: minisphere
Post by: Radnen on February 25, 2015, 12:19:03 pm

I didn't even bother with the extra complexity of surfaces.  I just told Allegro to defer drawing and drew all the visible tiles directly to the backbuffer.  See, I looked into how the deferred drawing works, and what benefits most from it is bitmap drawing--when you defer, Allegro batches all al_draw_bitmap() calls and then sends them all to the GPU at once as a single, huge triangle list.  In theory this should be blazing fast without the need to cache the layers on a surface.  Even more so once I implement atlasing for tilesets (currently each tile gets its own bitmap).


Ok, awesome! That actually will make animations easier to do. Tileset atlasing would also end up as a huge win, too. Allegro would be using OpenGL, and sending different texture pointers to HW is certainly a bottleneck.
Title: Re: minisphere
Post by: Fat Cerberus on February 25, 2015, 03:19:43 pm
Okay, whose idea was it to use line segments for obstruction? >:(. I know it's more flexible than bounding-box collision, but the crazy math required to check for intersections is insane.  Nothing like rects where it's just a few comparisons and you're done.  I looked at Sphere's source code and the TestSegments function alone must be at least 100 lines of code...
Title: Re: minisphere
Post by: Radnen on February 25, 2015, 04:29:45 pm
Line intersect is faster than pixel-perfect and can be nearly as accurate (if you map a decent contour), while bounding-box can be clunky on organic objects. That said my implementation of line intersect code is definitely not 100 lines, but then again I did abstract things away into helper classes. But even then, a hundred lines for that is a lot.

https://github.com/Radnen/sphere-sfml/blob/master/Engine/Engine/Objects/Line.cs#L33-49

The math there is the core of it, I'm sure you can abstract lines into a struct in C and make a few helper functions. It's literally that, and for loops, checking all the lines, whether the source is a person, a tile, or a custom map obstruction line.
Title: Re: minisphere
Post by: Flying Jester on February 25, 2015, 06:48:39 pm
It's not that crazy (https://github.com/FlyingJester/TurboSphere/blob/master/bin/system/scripts/turbo/segment.js#L49), or at least it shouldn't have be. My JS implementation is totally contained inside that one file, and you'll note it's only 109 lines :)

Eventually, Chad Austin had wanted to use BSP trees for obstructions. I suspect that was a part of the change to segments.
Title: Re: minisphere
Post by: Fat Cerberus on February 25, 2015, 09:16:35 pm
Yeah, wow, yours and Radnen's are so much shorter and more elegant.  I just checked the code in Sphere again, and this is what it looks like:
https://github.com/sphere-group/sphere/blob/master/sphere/source/common/ObstructionMap.cpp#L63-L189

Even accounting for blank lines and comments, that function still has to be close to 100 lines of code.
Title: Re: minisphere
Post by: Fat Cerberus on March 01, 2015, 11:38:30 am
Look what works in minisphere! ;D  Well, at least up till ExecuteGame is called...
Title: Re: minisphere
Post by: Fat Cerberus on March 04, 2015, 10:59:19 am
In the Steps of the Blackfoot is almost completely functional (barring a couple glitches and lack of person-tile collision) in minisphere! :D
Title: Re: minisphere
Post by: DaVince on March 05, 2015, 10:57:18 am
Wow, nice work man. :) Is performance decent?
Title: Re: minisphere
Post by: Fat Cerberus on March 05, 2015, 11:54:08 am

Wow, nice work man. :) Is performance decent?


It performs better than Sphere 1.5 in nearly all cases. ;D
Title: Re: minisphere
Post by: Fat Cerberus on March 07, 2015, 02:11:27 am
This just in: minisphere fully supports obstruction!

At this point I think minisphere is just about ready for a public beta release.  There are still a bunch of unimplemented APIs, but even as-is many existing Sphere games run with minimal--sometimes no--modification, so no real sense holding back anymore.  So get ready, minisphere is coming! ;D

Or, you know, you could just check it out from GitHub now and build it yourself, but... ;)

update: Aquatis now runs up to the intro cinematic before erroring out due to lack of Surface:applyLookup().  So close...
Title: Re: minisphere
Post by: Fat Cerberus on March 09, 2015, 02:25:56 am
Just released the first public beta of minisphere! ;D  Try it out!  Link is in the OP, but I'll repost it here for convenience.

Current release: minisphere 1.0-b1 (March 9, 2015)
Download on Google Drive (https://drive.google.com/file/d/0BxPKLRqQOUSNcjFBdXZ2dDNhd2M/view?usp=sharing) - GitHub (https://github.com/fatcerberus/minisphere)
Title: Re: minisphere v1.0-b1
Post by: Fat Cerberus on March 10, 2015, 01:37:51 am
So, a few new features:

GetExtensions() returns a list of strings representing the engine's capabilities.  For example, calling this in minisphere currently returns:
[ "sphere-legacy", "minisphere" ]

I got the idea after skimming the Pegasus stuff on GitHub.

The other new feature is an optional stack offset passed to Abort(), like so:
Code: (javascript) [Select]
Abort("ThisFunctionSucks(): This function sucks, why did you call it?", -1);


It allows you to blame the error on a script further up the call stack, useful in libraries to report invalid parameters or other such errors.  If the stack offset is not provided, it defaults to 0, meaning "location of Abort call" - i.e. the normal behavior.
Title: Re: minisphere v1.0-b1
Post by: Radnen on March 10, 2015, 02:04:39 am

It allows you to blame the error on a script further up the call stack, useful in libraries to report invalid parameters or other such errors.  If the stack offset is not provided, it defaults to 0, meaning "location of Abort call" - i.e. the normal behavior.


That's really awesome! In RadLib I had to do some SM only hacks to get line numbers and report the penultimate function call in the call stack. This would undoubtedly make that process much easier under your engine. +1
Title: Re: minisphere v1.0-b1
Post by: Fat Cerberus on March 10, 2015, 07:13:36 pm
See, the whole thing was kind of a happy accident - by default Duktape reported Abort-generated exceptions as coming from api.c, since that's where the duk_error() call is.  In order to get it to show the script file that aborted instead, I had to call into Duktape to walk a step or two up the stack and then use duk_error_raw, which lets you override the file name and line number of the thrown exception.  Of course, since I now had full access to the callstack, well... :)
Title: Re: minisphere v1.0-b1
Post by: Flying Jester on March 10, 2015, 07:18:51 pm
Just before I switched to SM, TurboSphere reported the entire JS stack on crash. Unfortunately, V8 couldn't give line numbers for higher frames, but it was still nice to see.

Would that be possible/not-horribly-complicated with Duktape?
Title: Re: minisphere v1.0-b1
Post by: Fat Cerberus on March 10, 2015, 07:25:50 pm
Trivial.  The stack offset on Abort isn't required to be -1, it can go all the way up the stack if needed and even gives line numbers.  The functionality I use to do it--Duktape.act()--is even exposed to script, so as long as minisphere uses Duktape, the entire callstack will available to scripts at any time.

I have to say, Duktape doesn't look like much, but it's actually a pretty awesome little JS engine.  It definitely took me by surprise.
Title: Re: minisphere 1.0b1
Post by: Fat Cerberus on March 10, 2015, 09:01:22 pm
Just implemented atlasing for RFN fonts.  The original implementation used individual ALLEGRO_BITMAPs for each glyph, which I suspect was the main reason for minisphere's horrible text-rendering performance up to now.  The drag became especially noticeable in Spectacles when the console was displayed.  Now it seems to be much better!
Title: Re: minisphere 1.0b1
Post by: Radnen on March 10, 2015, 09:23:34 pm

Just implemented atlasing for RFN fonts.  The original implementation used individual ALLEGRO_BITMAPs for each glyph, which I suspect was the main reason for minisphere's horrible text-rendering performance up to now.  The drag became especially noticeable in Spectacles when the console was displayed.  Now it seems to be much better!


Awesome!

Were you able to figure out the windowstyle issue? I know it may break on 1x1 sized images, but what about 2x2 or larger?
Title: Re: minisphere 1.0b1
Post by: Fat Cerberus on March 10, 2015, 09:28:17 pm
See, the odd thing is, that big window test?  It displays fine if I force Allegro into OpenGL mode.  It's only with D3D (Allegro's default under Windows) that the issue shows up.  I'll have to test with larger backgrounds though.  Honestly I haven't really worried about it since nobody's going to be using 1x1 windowstyles in a real game and the more typical sizes seem to render fine.
Title: Re: minisphere 1.0b1
Post by: Fat Cerberus on March 11, 2015, 03:14:20 am
So I just finished implementing zones, which completes the map engine. ;D. Still missing APIs I'm sure, but the map engine itself is, as far as I can tell, a complete functional recreation of Sphere's.

Now... what exactly do I need to do to get Lithonite working?  It seems to work somewhat in minisphere, but many of the zone types are completely non-functional and others are glitchy--for example slopes cause me to get stuck in diagonal movement eternally, and jumping off ledges makes my guy fly off the map completely out of my control.  Since the APIs Lithonite needs are all implemented and should be behaving identically to Sphere, I fail to understand what is causing the glitches.

Also: Lithonite reminded me that I never actually implemented tile animation... I should get on that!
Title: Re: minisphere 1.0b1
Post by: Fat Cerberus on March 11, 2015, 09:41:16 am
So that didn't take long--I got Lithonite working! :D  Little-known fact about SetDelayScript(): Despite the name of the function, it actually queues scripts, rather than setting one at a time.  Not supporting this was the reason it didn't work for me, and likely the reason it doesn't work properly in SSFML either--it only tracks one delay script at a time.
Title: Re: minisphere 1.0b1
Post by: Radnen on March 11, 2015, 08:10:12 pm

Not supporting this was the reason it didn't work for me, and likely the reason it doesn't work properly in SSFML either--it only tracks one delay script at a time.


Good to know!

Also I really need to implement more of the API esp. zone and trigger execution nuances, etc. I just need to find the time sometime to do it.
Title: Re: minisphere 1.0b1
Post by: Fat Cerberus on March 11, 2015, 11:39:30 pm

Also I really need to implement more of the API esp. zone and trigger execution nuances, etc. I just need to find the time sometime to do it.


I have to say, recreating Sphere like this, I have a new respect for the built-in map engine.  I always wrote it off because of the all the bugs in the Sphere 1.x implementation, but now I think it's pretty great.  The fact that minisphere fixes a lot of the aforementioned bugs (some of them without conscious effort on my part even) makes it that much more awesome.
Title: Re: minisphere 1.0b1
Post by: Fat Cerberus on March 12, 2015, 12:32:41 am
What's the best way to implement tile animation?  My current implementation just does a brute-force traversal of the map, counting frames for each tile and switching them in-place, but I have a feeling this is going to end up being a performance drain on larger maps.  I looked at both SSFML and Sphere's source, but I can't make heads or tails of the lookup method either one uses.  Care to enlighten me?

Edit: Okay, I really need to shut up. :-X  Leave me to my own devices for an hour and I figure stuff out every single time.  Instead of traversing the map, I set up a system where I walk the tileset and, at render time, remap the tile indices passed in from the map engine to their current animation state.  Funny thing about it: I ended up looking at the Sphere source again after doing this, and it turns out Sphere uses this exact same system, the code for it is just a lot sloppier.
Title: Re: minisphere 1.0b1
Post by: DaVince on March 12, 2015, 03:42:07 pm
Wow, Lord English. You're making amazing progress with this. I wish I had enough time to check it out!
Title: Re: minisphere 1.0b1
Post by: Radnen on March 12, 2015, 08:05:25 pm

Edit: Okay, I really need to shut up. :-X  Leave me to my own devices for an hour and I figure stuff out every single time.  Instead of traversing the map, I set up a system where I walk the tileset and, at render time, remap the tile indices passed in from the map engine to their current animation state.  Funny thing about it: I ended up looking at the Sphere source again after doing this, and it turns out Sphere uses this exact same system, the code for it is just a lot sloppier.


Sane here. I walk the tileset, find the correct timings (just once), and then just use them at the appropriate time intervals. I only update the timings when the user sets the tile animation in code.

BTW I just want to add between you me and FJ, working on our own engines has really helped us see how Sphere works internally and I'd say we'd all know at this point how to hack sphere into submission JS code-side. ;)
Title: Re: minisphere 1.0b1
Post by: Fat Cerberus on March 12, 2015, 11:40:15 pm
Speaking of tilesets, I just implemented tile atlasing!  My refcounted image system really helped here, I just have it create subimages off of the atlas, then free the atlas--when the last subimage (tile) is freed, the atlas gets freed automatically.  The best part is that the subimages are normal image_t pointers, so the atlas doesn't even interfere with things like SetTileImage, which can just free and replace the image pointer as normal.
Title: Re: minisphere 1.0b1
Post by: Fat Cerberus on March 14, 2015, 01:28:03 am
Well, minisphere has been a far bigger success than I ever anticipated.  Not only does it beat Sphere 1.5 in performance hands-down, but it runs the vast majority of existing Sphere games better than Sphere does.  I've known Sphere was buggy for quite a while, but I never realized it was quite this bad until I started comparing the two engines side-by-side later in development.

This is the part where I'll be honest: minisphere's development was largely motivated by self-interest.  After I finished the Spectacles battle engine, I started work on the field, and then realized that Sphere's map engine doesn't react well at all to blocking logic, UpdateMapEngine be damned.  For the longest time I thought it was a bug in the Specs threader, but no, it turns out it has something to do with Sphere's frameskipping logic causing it to skip a ton of FlipScreens (exactly equal to the number of frames spent in the MapEngine loop, interestingly enough), which I didn't fully realize until I got minisphere's map engine up and running and the threader behaved just fine there.

Whatever the case, I'm confident to say that the version of minisphere as it exists on GitHub right now is quite suitable as a drop-in replacement for Sphere 1.5.  I'll be posting minisphere 1.0b2 soon.  It would be a release candidate instead of a beta, but I haven't implemented networking support yet.  I want to at least do that before going gold with 1.0.
Title: Re: minisphere 1.0b1
Post by: Flying Jester on March 14, 2015, 06:03:46 am

This is the part where I'll be honest: minisphere's development was largely motivated by self-interest.


So was TurboSphere. I was frustrated by not being able to do N-body physics and 3D matrix transformations in script, and I was disappointed in the polygon drawing performance.
The best engines solve actual problems that you run into :)
Title: Re: minisphere 1.0b1
Post by: Fat Cerberus on March 14, 2015, 10:30:23 am
New API function: IsSkippedFrame().  This returns true if the next FlipScreen will be ignored, allowing the game to skip rendering for a frame to maximize the effectiveness of frame skipping.  The engine already does this internally for primitives and blits (except for render-to-surface, which is exempt for obvious reasons), so figured I may as well expose it to script. :)
Title: Re: minisphere 1.0b1
Post by: N E O on March 15, 2015, 12:36:44 am
Since you've implemented the map engine, can you run my NShoot demo, Artyxx (https://github.com/apollolux/artyxx) in minisphere? I want to find out if the issues it had in vanilla 1.5 still exist, since I know that I also had sloppy code at the time (e.g. wrote an unoptimized particle system script NPart b/c the beta ParticleSystem didn't have collision or the ability to access individual particles for me to script collision myself) but was running against a whole bunch of map engine ridiculousness too.
Title: Re: minisphere 1.0b1
Post by: Fat Cerberus on March 15, 2015, 01:57:45 am
Hm, seems I can't even get past the intro.  minisphere fails with "invalid base value" (I haven't located the cause yet, but basically this is Duktape's obtuse way of calling out attempts to use undefined as an object--probably due to an API I haven't implemented yet), and Sphere 1.5 fails at the same point with an error on SetLayerRenderer (invalid integer "Base" for argument 1).
Title: Re: minisphere 1.0b1
Post by: Fat Cerberus on March 15, 2015, 02:40:39 am
So one thing that always bugged me about the Sphere map engine is that maps smaller than the screen are rendered aligned to the top-left corner of the screen.  Well, I've fixed that: Small maps will be centered in minisphere, as shown in the screenshot below.

Edit: Also, just because of how awesome this is: One of my most recent changes was to massively improve the CPU usage of minisphere under framerate throttling.  As you can see in the second screenshot here, my 2nd gen i5 is barely breaking a sweat running minisphere at 60fps without skipping a single frame.  See, when there's time left over after a frame, instead of uselessly spinning, the process actually goes to sleep via al_wait_for_event_timed(), greatly reducing its CPU footprint.  Of course, this doesn't apply if framerate throttling is off--at that point there's obviously nothing I can do.
Title: Re: minisphere 1.0b1
Post by: Radnen on March 15, 2015, 04:36:47 am
Heh, you know most of the awesomeness with minisphere has a lot to do with, well... allegro being awesome. :P

This truly is a light-weight and fast implementation of Sphere! Can't wait to see full parity with the Sphere catalog. And as a bonus since allegro is so awesome there might be a future when minisphere get's a more decent engine like V8, but in the meantime this simply seems good enough.
Title: Re: minisphere 1.0b1
Post by: Fat Cerberus on March 15, 2015, 10:31:25 am

And as a bonus since allegro is so awesome there might be a future when minisphere get's a more decent engine like V8, but in the meantime this simply seems good enough.


Yes, unfortunately Duktape is the weak link here.  For what it is (a lightweight, easy-to-embed JS engine, basically the JS answer to Lua) it's great, but there are some issues.  Namely, compiling scripts, even tiny delayscripts, is slow, even compared to Sphere 1.5's SpiderMonkey.  This means that anything that abuses delayscripts--like, say, Lithonite--is going to take a pretty noticeable performance hit.  Of course this can be alleviated in new games if I allow SetDelayScript and friends to take a (already-compiled) function as argument, but this does nothing to help games using the older method.

Not only that, but games with large codebases, for instance Trial & Error and Aquatis, cause a pretty painful delay on startup while all the scripts are compiled.
Title: Re: minisphere 1.0b1
Post by: Fat Cerberus on March 16, 2015, 12:52:39 am
So I was going to wait until after releasing 1.0b2 to do this, but I had some free time today and implemented the networking API.  For this I used a tiny asynchronous networking library called Dyad (https://github.com/rxi/dyad), which is essentially just a thin wrapper over the target platform's native sockets implementation (e.g. Winsock for Windows, BSD sockets for other platforms) and adds only about 3k to the engine executable's size.

I tested it out with this code:
Code: (javascript) [Select]
var socket = OpenAddress("www.google.com", 80);
while (!socket.isConnected()) FlipScreen();
socket.write(CreateByteArrayFromString("GET / HTTP/1.1\r\nHost: www.google.com\r\n\r\n"));
while (socket.getPendingReadSize() == 0) FlipScreen();
Abort(CreateStringFromByteArray(socket.read(socket.getPendingReadSize())));


And got some HTML code back in both Sphere and minisphere, so it works perfectly!
Title: Re: minisphere 1.0b2
Post by: Fat Cerberus on March 16, 2015, 02:07:59 pm
minisphere 1.0b2 is out. ;D
Title: Re: minisphere 1.0b2
Post by: DaVince on March 17, 2015, 08:36:26 am
"Oh, I just casually implemented networking inbetween minor versions." Damn, man. ;D
Title: Re: minisphere 1.0b2
Post by: Fat Cerberus on March 17, 2015, 11:34:02 am
Haha, what can I say, I'm very motivated.  :D. For what it's worth, I'm getting very close to a 1.0 release, but I need some outside testing to happen first, particularly with regard to joystick support, which I couldn't test myself as I don't have a gamepad handy.

I'm thinking I might need to make some enhancements to the networking API, though.  As implemented in Sphere (and minisphere), it's very barebones and lacks basic functionality--for example, there's no way to tell from script when a socket has finished receiving data.
Title: Re: minisphere 1.0b2
Post by: Flying Jester on March 17, 2015, 05:33:49 pm
I think the networking API is very close to what it should be. I rather think it should basically be the same as the BSD socket API, which it almost is. Mainly, I believe that there should be an "Accept" function in addition to "ListenOnPort".

I'm not sure what you mean by "finished receiving data".

Is the SCons file commit going to be pulled in?
Title: Re: minisphere 1.0b2
Post by: Fat Cerberus on March 17, 2015, 05:45:14 pm
Ignore me on the finished receiving thing.  I didn't do enough research into how sockets work to realize that there was no built-in facility for the receiver to know when the other end has sent a full response (for instance, a full HTML doc), it's just an open data channel.

...and yes, that means I somehow successfully implemented networking without knowing a thing about how sockets work.  :P

As for SCons, can I cherry-pick only the SCons stuff somehow?  The rest of the commits in that pull would probably be a very bad idea to merge in at this point.  I may just have to close the pull and import them manually.
Title: Re: minisphere 1.0b2
Post by: Flying Jester on March 17, 2015, 09:32:18 pm

Ignore me on the finished receiving thing.  I didn't do enough research into how sockets work to realize that there was no built-in facility for the receiver to know when the other end has sent a full response (for instance, a full HTML doc), it's just an open data channel.

...and yes, that means I somehow successfully implemented networking without knowing a thing about how sockets work.  :P

As for SCons, can I cherry-pick only the SCons stuff somehow?  The rest of the commits in that pull would probably be a very bad idea to merge in at this point.  I may just have to close the pull and import them manually.


I do know there is a way to cherry-pick certain commits, using a command literally called `git cherrypick', but I don't recall exactly how it works. I haven;t had to do that since last summer.

I can just make up some new SCons files. There are new source files to account for, anyway. It's probably easiest that way.

Re sockets, you are guaranteed that write commands are not broken when they are read on the other end, even if the amount sent is greater than what a literal packet can hold. You are only in danger of having multiple responses queued up and not being able to distinguish where one ends and another begins. This is almost always solved by the application.

And I believe that anything more is totally up to the application, and really should only be in script in a Sphere-like environment. Only holding the BSD API allows Sphere-like engines to talk to any kind of server and be any kind of server. Any extension of this by the engine in native, I believe, puts this in danger.
Title: Re: minisphere 1.0b2
Post by: Fat Cerberus on March 18, 2015, 12:12:14 am
So I see what you mean about the lack of any kind of Accept() function for listening sockets.  As it's implemented in Sphere, a socket created via ListenOnPort is literally replaced by the first thing to connect to it, meaning trickery like this is required to run an actual server:

Code: (javascript) [Select]
Threads.doWith({ socket: ListenOnPort(80) },
function() {
if (this.socket.isConnected()) {
var text = GetVersionString();
var data = CreateByteArrayFromString("HTTP/1.1 200 OK\r\nContent-Length: " + text.length + "\r\n\r\n" + text);
this.socket.write(data);
this.socket.close();
this.socket = ListenOnPort(80);
}
return true;
}
);


(Also, let's just take a moment to appreciate how awesome the Specs threader is. :) )
Title: Re: minisphere 1.0b2
Post by: Fat Cerberus on March 18, 2015, 10:03:49 pm
So I made some improvements to the networking API as suggested by Jester:

ListenOnPort() now takes an optional second parameter, max_backlog.  If not provided, it defaults to zero, which causes the socket to behave as in Sphere 1.5, closing the listener and replacing the socket in-place with that of the first client connection.  If max_backlog is greater than zero, it acts as a BSD socket, and the script must call the new Socket:acceptNext() method to get socket objects for new client connections.  If acceptNext() is not called periodically, any pending connections past the size of the backlog will be automatically dropped.  The listening socket remains open as a listener until closed.

The way this was done, it's fully backwards compatible with the Sphere API and only adds one new method. :)

Edit: Okay, I fibbed.  There are 3 new methods: The aforementioned acceptNext(), getRemoteAddress() and getRemotePort().  It's good to know who's connecting to your server, methinks. :P
Title: Re: minisphere 1.0b3
Post by: Fat Cerberus on March 19, 2015, 03:22:18 pm
Just posted minisphere 1.0b3.  See OP for download link and changelog.

At this point I have to recommend Sphere developers use minisphere over vanilla Sphere if possible.  Only a few APIs are unimplemented (particularly oddball stuff like color matrices), and minisphere is not only faster, but in my testing at least, less glitchy than Sphere 1.5.

Oh, and NEO: After a few necessary minor edits to the code, your Artyxx demo works great in minisphere. 8)
Title: Re: minisphere 1.0b3
Post by: Radnen on March 19, 2015, 08:12:57 pm

At this point I have to recommend Sphere developers use minisphere over vanilla Sphere if possible.  Only a few APIs are unimplemented (particularly oddball stuff like color matrices), and minisphere is not only faster, but in my testing at least, less glitchy than Sphere 1.5.


I will say the only outstanding issues are discrepancies between SpiderMonkey and ECMA5.1, such as const and error constructors and other wacky additions Mozilla decided to add. Since my RadLib library has lots of this intrinsic stuff I'll have to spend time converting it. But yes, I should update my code rather because ECMA complacent JS ideally works anywhere ECMA is supported: it's the smallest subset that's considered correct JS.
Title: Re: minisphere 1.0b3
Post by: Radnen on March 19, 2015, 08:18:21 pm
I'm going to log bugs on github, even if they can't be fixed (such as const).
Title: Re: minisphere 1.0b3
Post by: Fat Cerberus on March 19, 2015, 08:21:27 pm
I actually tried to fix the const thing early on by editing Duktape, but it's lexer code is... Obtuse.  Go ahead, try to find keywords in duktape.c, they just aren't there.  It baffles me.
Title: Re: minisphere 1.0b3
Post by: Fat Cerberus on March 20, 2015, 12:27:41 pm
Good news: I posted an issue on Duktape's GitHub repo regarding the lack of a reported filename for syntax errors, and the dev fixed it.  So now minisphere reports the exact location of syntax errors, making it easier to locate consts that need to be changed. :)
Title: Re: minisphere 1.0b2
Post by: Flying Jester on March 20, 2015, 09:08:56 pm

So I made some improvements to the networking API as suggested by Jester:

ListenOnPort() now takes an optional second parameter, max_backlog.  If not provided, it defaults to zero, which causes the socket to behave as in Sphere 1.5


It defaults to 16 in Sphere 1.5. That's just the number of pending connections that have not yet been Accept'ed before connections start getting refused outright.
Title: Re: minisphere 1.0b3
Post by: Fat Cerberus on March 20, 2015, 09:26:07 pm
That makes no sense because Sphere 1.5 has no accept() method for listeners and (from what I can tell) the listening socket closes as soon as someone connects to it, at which point the object becomes (i.e. is internally mutated into) a normal bidirectional socket.  Sphere might set a backlog of 16 internally, but the way the API is exposed, it effectively can only accept a single connection.  Hence the zero default in minisphere to specify the legacy behavior.

Note that the actual backlog on a socket is likely going to be larger than whatever you pass to ListenOnPort() for the second parameter anyway because Dyad is set up to accept() connections automatically--I get a callback with the new socket only after this has been done for me.  Which means minisphere can't actually reject any connections--it has to disconnect them after they've already been established if its own backlog is full.
Title: Re: minisphere 1.0b3
Post by: Radnen on March 20, 2015, 09:51:10 pm
Do connections close properly when Sphere shuts down? One thing I noticed is that when I made networked games in Sphere 1.5, and you hit the X button or Alt+F4 out of the app, you couldn't close open files, connections, etc.

In fact it'd be nice to have access to that as a new feature. The "on close" or "shutdown" callback.
Title: Re: minisphere 1.0b3
Post by: Fat Cerberus on March 20, 2015, 10:02:52 pm
All native-implemented objects in minisphere have finalizers and Duktape guarantees they will be called on shutdown if the GC hasn't done so already.  Duktape also uses refcounting in addition to mark-and-sweep, so in most cases you don't even have to wait for an object to be collected when it goes out of scope--it's finalized immediately.  Short of a segfault (or refcounting bug in minisphere--I've encountered these before and they're not pretty), you're not likely to leak resources in minisphere.

That said, a shutdown callback could be useful.  I'll consider implementing such a thing.
Title: Re: minisphere 1.0b3
Post by: Fat Cerberus on March 21, 2015, 01:21:50 pm
I've decided to make minisphere's API functions more JS engine agnostic.  They are now defined like this:

Code: (c) [Select]
static js_retval_t
js_CreateColor(_JS_C_FUNC_ARGS_)
{
js_begin_api_func("CreateColor");
js_require_num_args(3);
js_int_arg(1, r_val);
js_int_arg(2, g_val);
js_int_arg(3, b_val);
js_maybe_int_arg(4, a_val, 255);

r_val = fmin(fmax(r_val, 0), 255);
g_val = fmin(fmax(g_val, 0), 255);
b_val = fmin(fmax(b_val, 0), 255);
a_val = fmin(fmax(a_val, 0), 255);
js_return_sphereobj(color, al_map_rgba(r_val, g_val, b_val, a_val));
}


Unlike Sphere's beginfunc() macro, this still looks like a normal C function and so doesn't hurt the code's readability.

The thing is though, I don't know if I'm up for the massive refactoring that's going to be required to get all my API functions to conform to this setup... :-\
Title: Re: minisphere 1.0b4
Post by: Fat Cerberus on March 22, 2015, 10:26:57 am
minisphere 1.0b4 is up.  No new APIs this time around, just under-the-hood changes.  Much of the architecture was rewritten, however (I now use fopen instead of Allegro's file routines, for example), so I thought it was good to push out another release so I could get some testing in.
Title: Re: minisphere 1.0b4
Post by: N E O on March 22, 2015, 07:21:39 pm

Oh, and NEO: After a few necessary minor edits to the code, your Artyxx demo works great in minisphere. 8)


Groovy! Can you PR those edits to the repo?
Title: Re: minisphere 1.0b4
Post by: Fat Cerberus on March 22, 2015, 09:48:39 pm


Oh, and NEO: After a few necessary minor edits to the code, your Artyxx demo works great in minisphere. 8)


Groovy! Can you PR those edits to the repo?


Haha, sure, thing. :)  Until you said that I had actually forgotten I checked it out from GitHub!
Title: Re: minisphere 1.0b3
Post by: Flying Jester on March 23, 2015, 01:28:09 am

That makes no sense because Sphere 1.5 has no accept() method for listeners and (from what I can tell) the listening socket closes as soon as someone connects to it, at which point the object becomes (i.e. is internally mutated into) a normal bidirectional socket.  Sphere might set a backlog of 16 internally, but the way the API is exposed, it effectively can only accept a single connection.  Hence the zero default in minisphere to specify the legacy behavior.


That's not what that number means. Setting that number to zero in Linux or BSD will result in no connections whatsoever being accepted. If any are accepted with winsock, that is a bug in winsock or a misinterpretation of the BSD API. Setting that number sets the number of connections that can exist waiting on listening socket, waiting for an Accept. Setting it to zero means that there can be zero sockets ready to be accepted, the queue has a size of zero and will always be empty.

Setting it to one is much more correct.
Title: Re: minisphere 1.0b3
Post by: Fat Cerberus on March 23, 2015, 01:37:34 am


That makes no sense because Sphere 1.5 has no accept() method for listeners and (from what I can tell) the listening socket closes as soon as someone connects to it, at which point the object becomes (i.e. is internally mutated into) a normal bidirectional socket.  Sphere might set a backlog of 16 internally, but the way the API is exposed, it effectively can only accept a single connection.  Hence the zero default in minisphere to specify the legacy behavior.


That's not what that number means. Setting that number to zero in Linux or BSD will result in no connections whatsoever being accepted. If any are accepted with winsock, that is a bug in winsock or a misinterpretation of the BSD API. Setting that number sets the number of connections that can exist waiting on listening socket, waiting for an Accept. Setting it to zero means that there can be zero sockets ready to be accepted, the queue has a size of zero and will always be empty.

Setting it to one is much more correct.


I know what the backlog is.  I researched sockets after implementing the networking API to better understand how everything works.

Here's the thing: The Dyad library I'm using for networking manages it for me.  From what I can tell, Dyad by default sets a backlog of 511 and accepts connections for me, it's just that, for compatibility reasons, I defined zero passed to ListenOnPort() (NOT winsock) to be a sentinel meaning "make this socket behave as in Sphere 1.5".  It doesn't mean the actual backlog is zero--that would be nonsensical!

Long story short: minisphere still accepts connections past the backlog value passed to ListenOnPort, it just drops them immediately if it's own backlog is full.  Understand now?
Title: Re: minisphere 1.0b4
Post by: Fat Cerberus on March 24, 2015, 11:00:24 pm
New APIs: RoundRectangle and OutlinedRoundRectangle.  No idea why Sphere didn't have these, but now minisphere does!
Title: Re: minisphere 1.0b4
Post by: Fat Cerberus on March 25, 2015, 12:45:01 am
Hm, looks like minisphere was so successful that I attracted a spambot! :P
Title: Re: minisphere 1.0b4
Post by: Fat Cerberus on March 25, 2015, 02:57:56 am
Okay, so heads up: Next release of minisphere will include at least the following as system scripts:



I may add more, but these five seemed like good candidates for essential functionality to include in the default distribution.

I'm removing all the old legacy cruft that the system scripts folder comes with in vanilla.  I haven't seen a game yet that uses any of them, and at least half of them are broken or incompatible now anyway.  They're just dead weight at this point.
Title: Re: minisphere 1.0b4
Post by: Flying Jester on March 25, 2015, 09:39:08 pm
The three that I know are used at least sometimes are circles.js, time.js, and colors.js. I would leave at least those. Colors just needs a working CreateColor (I modified the one included with TurboSphere to use the color constructor), time.js just needs GetTime(), and circles.js needs Surfaces that have the circle primitive methods.

On the other hand, I really recommend exposing a Delay function that replaces time.js from the engine itself, as TurboSphere does, to allow games to not use 100% of the CPU even when idling.
Title: Re: minisphere 1.0b4
Post by: Fat Cerberus on March 26, 2015, 03:21:01 am

On the other hand, I really recommend exposing a Delay function that replaces time.js from the engine itself, as TurboSphere does, to allow games to not use 100% of the CPU even when idling.


Way ahead of you on that one.  I already implemented Delay() a few days ago, it will be in 1.0b5.  Keeping CPU usage down is one of my main concerns with minisphere.  I hate that Sphere 1.5 maxes out a core the whole time it's running, which is why I implemented the timed sleep after FlipScreen a few betas ago.
Title: Re: minisphere 1.0b4
Post by: Fat Cerberus on March 26, 2015, 12:54:51 pm
So, minisphere finally has in-engine error messages.  Having to grab the mouse when an error popped up during testing was starting to get annoying. :P  See screenshot below:

Edit: minisphere 1.0b5 is out!  This will probably be the last beta, next release will either be 1.0 or a release candidate, depending on how confident I'm feeling about the code.
Title: Re: minisphere 1.0b5
Post by: Fat Cerberus on March 26, 2015, 05:24:49 pm
Oh, by the way, there's an Easter egg related to the Abort and Alert functions, let's see if anyone can find it.  :) (No cheating by looking at the code!)
Title: Re: minisphere 1.0
Post by: Fat Cerberus on March 28, 2015, 03:48:39 pm
Well, after 2 months of nonstop coding, minisphere 1.0 has been released! ;D  There's still a handful of Sphere APIs missing or unimplemented, but no real showstoppers, so I figured now was as good a time as any for the 1.0 release.

See the OP to download and go crazy!  Don't forget to report bugs as I'm sure there's a ton of them... :P
Title: Re: minisphere 1.0.1
Post by: Fat Cerberus on March 29, 2015, 01:45:02 am
Just posted minisphere 1.0.1, fixing a couple bugs discovered by Radnen.
Title: Re: minisphere 1.0.1
Post by: DaVince on March 29, 2015, 06:29:48 am
Awesome! Good work. Any way to compile this under Linux?
Title: Re: minisphere 1.0.1
Post by: Flying Jester on March 29, 2015, 06:57:41 am
So, I just tried compiling Minisphere on OS X.

How high is the warning level on MSVC turned up for you? You have on bazillion implicit-int and default-return warnings now...it wasn't like that before.

I opened another pull request. I had to remove min/max again, and itoa is nonstandard and does not exist outside MSVC and GCC, but it's just a few lines different, plus the SCons files. The bare minimum to confirm that everything is compiling correctly.
Title: Re: minisphere 1.0.1
Post by: Fat Cerberus on March 29, 2015, 10:00:21 am

So, I just tried compiling Minisphere on OS X.

How high is the warning level on MSVC turned up for you? You have on bazillion implicit-int and default-return warnings now...it wasn't like that before.

I opened another pull request. I had to remove min/max again, and itoa is nonstandard and does not exist outside MSVC and GCC, but it's just a few lines different, plus the SCons files. The bare minimum to confirm that everything is compiling correctly.


The warning level is whatever MSVC's default is.  It doesn't usually warn for implicit conversions, so I don't bother with casts.  I'm trying to keep those to a minimum anyway to make the code easy to read; if given the choice between cluttering up the code with casts or putting up with warnings, I'll generally choose the latter.  If I wanted to have to cast everything I'd be using c++ not C...

Long story short, I find implicit conversion warnings patronizing. :P

A min/max snuck back in?  I've been using fmin/fmax... Must have been a brainfart on my part.

The default returns are actually spurious and can be ignored.  There is no platform-independent way to declare a no-return function so I just put up with them.  duk_error_ni() calls duk_error_va_raw, which calls longjmp and thus doesn't return.  The compiler isn't smart enough to figure that out though, so you get warnings.  Before I was calling the built in duk_error directly, which IS declared no-return, which is why you didn't get them before.
Title: Re: minisphere 1.0.1
Post by: Fat Cerberus on March 29, 2015, 11:38:22 am

Awesome! Good work. Any way to compile this under Linux?


Well as you can see, Jester got it to compile under OS X, so in theory nothing should be stopping it from compiling in Linux either.  I tried to write the code to be as portable as possible, and libraries were also carefully chosen to this end (Allegro, Duktape and Dyad are all supposed to work on at least the Big 3).  Unfortunately Win8.1 doesn't appreciate dual boot configurations and I don't have a spare computer, or I would have tried this myself in Ubuntu.
Title: Re: minisphere 1.0.1
Post by: Flying Jester on March 29, 2015, 05:48:14 pm
Note that it aborts on something about joystick in Allegro when starting up on OS X. But it should still compile with GCC, at least on 64-bit systems.

https://github.com/FlyingJester/TSPR/blob/master/noreturn.h (https://github.com/FlyingJester/TSPR/blob/master/noreturn.h)

It's not too difficult to do noreturn in a way that MSVC, Clang, and GCC accept :)
Title: Re: minisphere 1.0.1
Post by: Fat Cerberus on March 29, 2015, 06:16:08 pm
Do you know what the joystick error is by any chance?  If I knew the exact message I could google it.
Title: Re: minisphere 1.0.1
Post by: Fat Cerberus on March 29, 2015, 10:36:55 pm
@Flying Jester:
Well, I experimented with raising the warning level in MSVC from level 3 to level 4, and got a ton of spurious warnings, so I'm thinking I will probably lower it again.  What irks me most is all the C4706 warnings (assignment within conditional expression) from perfectly idiomatic lines like this:
Code: [Select]
if (!(image = create_subimage(parent, x, y, width, height))) goto on_error;


That code is perfectly clear in its intent, the warning is not needed.  And sure, I could go around disabling warnings individually, but that starts to defeat the purpose of the higher warning level, so I might as well just leave it at level 3 where it compiles cleanly.  I think the low number of major bugs putting together an engine this fast speaks to the fact of me knowing what I'm doing here without the compiler complaining at me. :P

Also: Don't ever try to compile a Win32 app in MSVC with -Wall - You will get a crapton of warnings (as in, tens of thousands! :o) just from the Windows headers alone.
Title: Re: minisphere 1.0.1
Post by: Flying Jester on March 29, 2015, 11:21:03 pm
Some of it a little concerning, even so. This is on the default the settings for GCC/Clang. Clang not pretending to be GCC is even less forgiving.

You should probably at least add safe-guard return statements or use some macros to fix the non-return statements. Technically it's undefined behaviour to even call a function like that.

Some some stuff, like this:

Code: [Select]

static js_BindJoystickButton(duk_context* ctx)


It's not well formed ANSI C to not have a return type. GCC is gracious about it, but Clang doesn't accept it.

In this case:
Code: [Select]

minisphere/main.c:267:13: warning: assigning to 'char *' from 'const char *' discards qualifiers [-Wincompatible-pointer-types-discards-qualifiers]
                file_name = file_name != NULL ? file_name + 1 : file_path;


This is bad. Not respecting constness is undefined behaviour, as well. If you cannot avoid it then you should add a cast.

...anyway...

In some cases it is telling you that you are not following the standard, but the compiler is willing to let it slide, such as in the default-int, const-incorrectness, and non-returns. The compiler could quite validly deny this code even to compile. These are the ones I'm properly worried about, because a standards-compliant compiler may or may not actually compile it.
Title: Re: minisphere 1.0.1
Post by: Fat Cerberus on March 29, 2015, 11:55:49 pm
The functions with no return type I discovered myself during my foray into /W4, those were accidental and I'm not even sure how that happened.  I must have been falling over tired when I wrote something like static js_BindJoystickButton.  I fixed it in my latest commit.

As for const-correctness, from what I understand - if we're being technical about it it's not undefined behavior to cast away constness (C++ has const_cast for a reason), it's only UB if you write to an actual constant.  I'm not saying this isn't a potential source of bugs of course, just want to dispel any misconceptions.  That said, const-correctness is something I do take seriously (if you look at the code, I declare a good number of const pointers myself), but if MSVC doesn't warn me about it, I may not always catch violations.  But even with /W4, I don't get any such warnings, and /Wall is just unfeasible as mentioned above.  Clang must just be REALLY pedantic.

I did fix the no-return functions in the latest commit, I added a noreturn macro so I can now use noreturn in place of a return type.  I wasn't aware GCC would accept the __attributes__ before the function declaration, I thought it had to go after, which would have complicated the macro.  Thanks for the tip. :)

Oh, and regarding that const violation on line 267, I'm thinking that came about due to confusion with strrchr, which is defined, at least in MSVC, as:
Code: [Select]
char* strrchr(const char*, int);


Not sure who had that bright idea, but that's a const correctness violation waiting to happen--and in fact, one did.  Anyway, I fixed it.
Title: Re: minisphere 1.0.1
Post by: Flying Jester on March 30, 2015, 12:28:56 am
That's my biggest peeve about MSVC. Its standard library tends to take the standard a little loosely, and unlike the GCC and Cland standard libraries it doesn't offer warnings when you use nonstandard functions.


As for const-correctness, from what I understand - if we're being technical about it it's not undefined behavior to cast away constness (C++ has const_cast for a reason), it's only UB if you write to an actual constant.  I'm not saying this isn't a potential source of bugs of course, just want to dispel any misconceptions.  That said, const-correctness is something I do take seriously (if you look at the code, I declare a good number of const pointers myself), but if MSVC doesn't warn me about it, I may not always catch violations.  But even with /W4, I don't get any such warnings, and /Wall is just unfeasible as mentioned above.  Clang must just be REALLY pedantic.


Clang doesn't joke around :D That's why I am so happy that TurboSphere compiles with -Wall -Werror with both GCC-compatiblity and pure Clang mode.
Title: Re: minisphere 1.0.2
Post by: Fat Cerberus on March 30, 2015, 02:33:32 am
minisphere 1.0.2 is up, fixing a lockup when using IsKeyPressed in a loop.  Had to use git bisect to find this one, it had me stumped for over a week.
Title: Re: minisphere 812.8.2 now with awesome 3D!
Post by: Fat Cerberus on April 01, 2015, 01:01:36 pm
Hey, check out the new 812.8.2 version of minisphere!  It's flipping awesome! :D
Title: Re: minisphere 812.8.2 now with awesome 3D!
Post by: Radnen on April 01, 2015, 02:10:12 pm

Hey, check out the new 812.8.2 version of minisphere!  It's flipping awesome! :D


3D!? That's amazing! I'll definitely check it out when I get home. But I'll have to be very careful of the hunger pig.
Title: Re: minisphere 812.8.2 now with awesome 3D!
Post by: Fat Cerberus on April 01, 2015, 11:35:19 pm
Sorry guys, I'm going to have to pull 812.8.2 at midnight.  It seems everyone that tested it ended up getting eaten by that hunger-pig at 8:12pm. :'(

...April fools!  There was no 812.8.2 version of minisphere with awesome 3D rendering, I made it up (not that it wasn't entirely obvious anyway, haha). ;D. I did post a real bug fix release today though (1.0.3), in case anyone missed it.
Title: Re: minisphere 1.0.3
Post by: Fat Cerberus on April 02, 2015, 11:30:18 am
Odd, I can't get Kefka's Revenge to run in minisphere.  I get an error loading jewtheblue.bmp, which doesn't make sense since Allegro is supposed to support BMP.

Edit: Figured it out, the offending image is actually a PNG image saved as .bmp (Thank goodness for hex editors!).  Allegro apparently doesn't appreciate the file extension being changed, while Corona doesn't seem to mind.  I'm debating whether I should code in a workaround for this or just leave it alone and make a note in the readme... I'm leaning towards the latter.

Edit2: Aww, looks like KR isn't going to run in minisphere any time soon as it uses the animation API, which I currently have no means of supporting.
Title: Re: minisphere 1.0.3
Post by: Radnen on April 02, 2015, 09:21:46 pm

Edit: Figured it out, the offending image is actually a PNG image saved as .bmp (Thank goodness for hex editors!).  Allegro apparently doesn't appreciate the file extension being changed, while Corona doesn't seem to mind.  I'm debating whether I should code in a workaround for this or just leave it alone and make a note in the readme... I'm leaning towards the latter.


AFAIK corona uses the file contents to verify the data, while a lot of libraries tend to use the stupid file extension. Our Sphere engines for example can load rws files without .rws appended to it. Using the first 4 chars to verify the filetype.
Title: Re: minisphere 1.0.3
Post by: N E O on April 03, 2015, 02:11:34 pm
Looking forward to reading OSX compilation instructions so I can give this a shot on my Mavericks MacBook Air!
Title: Re: minisphere 1.0.3
Post by: DaVince on April 03, 2015, 02:20:41 pm

Odd, I can't get Kefka's Revenge to run in minisphere.  I get an error loading jewtheblue.bmp, which doesn't make sense since Allegro is supposed to support BMP.

Edit: Figured it out, the offending image is actually a PNG image saved as .bmp (Thank goodness for hex editors!).  Allegro apparently doesn't appreciate the file extension being changed, while Corona doesn't seem to mind.  I'm debating whether I should code in a workaround for this or just leave it alone and make a note in the readme... I'm leaning towards the latter.

Edit2: Aww, looks like KR isn't going to run in minisphere any time soon as it uses the animation API, which I currently have no means of supporting.

It uses MNG for only a select few things, like the little dragon morph animation on the title screen. Maybe they could simply be stubbed?
Title: Re: minisphere 1.0.3
Post by: Fat Cerberus on April 03, 2015, 03:26:45 pm

Looking forward to reading OSX compilation instructions so I can give this a shot on my Mavericks MacBook Air!


There's an SCons script in the repo now, courtesy of Jester.  You should probably be able to use that to build it.  Just keep in mind you will likely get some warnings. :)
Title: Re: minisphere 1.0.3
Post by: DaVince on April 03, 2015, 09:41:53 pm
Tried to compile from master:

Code: [Select]
gcc -o minisphere/font.o -c minisphere/font.c
minisphere/font.c: In function 'free_font':
minisphere/font.c:189:2: error: 'for' loop initial declarations are only allowed in C99 or C11 mode
  for (int i = 0; i < font->num_glyphs; ++i) {
  ^
minisphere/font.c:189:2: note: use option -std=c99, -std=gnu99, -std=c11 or -std=gnu11 to compile your code
scons: *** [minisphere/font.o] Error 1
scons: building terminated because of errors.


:(
Title: Re: minisphere 1.0.3
Post by: Fat Cerberus on April 03, 2015, 09:49:49 pm
Oops, that was some of my earlier code, while I was still in JS mode, I accidentally declared the index variable in the for loop itself, which is illegal ANSI C and requires the compiler to be in C99 mode to compile successfully.  It's odd though, that SCons script should be exactly what Jester used to get it to build, I haven't modified it...

I'll have to go through the code and do some more cleanup.
Title: Re: minisphere 1.0.4
Post by: Fat Cerberus on April 04, 2015, 02:36:52 am
DaVince, try compiling again from the latest master.  I fixed the offending line; there don't appear to be any other instances.
Title: Re: minisphere 1.0.4
Post by: DaVince on April 04, 2015, 07:07:00 am
It seems to have compiled all the source files into object files, but then fails at the next step... Am I missing a dependency, perhaps? I checked, but there's no libfmod in the package repository (Ubuntu), so I'm not sure how to proceed...

Code: [Select]
gcc -o minisphere/msphere minisphere/api.o minisphere/bytearray.o minisphere/color.o minisphere/duktape.o minisphere/dyad.o minisphere/file.o minisphere/font.o minisphere/geometry.o minisphere/image.o minisphere/input.o minisphere/logger.o minisphere/lstring.o minisphere/main.o minisphere/map_engine.o minisphere/obsmap.o minisphere/persons.o minisphere/primitives.o minisphere/rawfile.o minisphere/script.o minisphere/sockets.o minisphere/sound.o minisphere/spriteset.o minisphere/surface.o minisphere/tileset.o minisphere/windowstyle.o -lallegro -lallegro_audio -lallegro_acodec -lallegro_color -lallegro_dialog -lallegro_font -lallegro_image -lallegro_primitives -lallegro_ttf -lallegro_main
/usr/bin/ld: minisphere/duktape.o: undefined reference to symbol 'fmod@@GLIBC_2.2.5'
/lib/x86_64-linux-gnu/libm.so.6: error adding symbols: DSO missing from command line
collect2: error: ld returned 1 exit status
scons: *** [minisphere/msphere] Error 1
scons: building terminated because of errors.


Speaking of dependencies, could you please list them in an INSTALL file or something? I noticed I needed liballegro5-dev liballegro-audio5-dev liballegro-image5-dev and installed the other allegro 5 packages just to be sure that I got all appropriate dependencies too, but I'm not sure what else is necessary. All the Allegro libs I am now noticing in the first line in the log up here, I suppose?
Title: Re: minisphere 1.0.4
Post by: Fat Cerberus on April 04, 2015, 10:09:01 am
fmod is a standard C function (floating point modulo).  No idea what's going on there, but it's nothing to do with minisphere itself, that's for sure.

As for dependencies, Allegro 5 should be the only one.  You were right to install the whole shebang there, as I'm pretty sure I use the majority of them.  My only other two dependencies are Duktape and a small networking library called Dyad, both of whose .c files are included in the project.

Sorry for the lack of build documentation, I'm a Windows developer by nature so I'm used to having a nice IDE (read: Visual Studio) take care of everything for me.  I'd much rather write code for my own program than my build tools, thank you. :P
Title: Re: minisphere 1.0.4
Post by: DaVince on April 04, 2015, 05:29:59 pm
After some research, it seems that -lm needs to be added at the end of the gcc linker command. But I'm not sure how to do this with these scons files.

Edit: figured it out. I added a line after line 40 in SConscript with:
Code: [Select]
"m"


And now it's compiled. I like that you're showing a file dialog to ask for the sgm!
Title: Re: minisphere 1.0.4
Post by: DaVince on April 04, 2015, 05:46:27 pm
I tried running Sir Boingers. It ran the main menu just fine (after changing all const keywords to var and resaving some scripts as UTF-8).

There is a bug, however: when I try entering the game, or other parts of it, it errors out. Except since I use the space bar, the window closes almost immediately and I can't read the error message at my leasure. Could you perhaps add a short delay (like half a second) before reading the space bar input, or only start checking for it once the last in-game keypress has been released?

Also, after taking a quick screenshot while the error displayed, it turns out it couldn't load the map. (default/tutorial.rmp). Do you know what's up with that? Is it because it's in a subfolder (maps/default/tutorial.rmp)? And do you think you could output the error to the console too?

Edit: just noticed it plays back the menu sound effects only once, too. Is it because I'm stopping the last instance and then immediately playing it back again, perhaps?
Title: Re: minisphere 1.0.4
Post by: Fat Cerberus on April 04, 2015, 05:53:09 pm

I tried running Sir Boingers. It ran the main menu just fine (after changing all const keywords to var and resaving some scripts as UTF-8).

There is a bug, however: when I try entering the game, or other parts of it, it errors out. Except since I use the space bar, the window closes almost immediately and I can't read the error message at my leasure. Could you perhaps add a short delay (like half a second) before reading the space bar input, or only start checking for it once the last in-game keypress has been released?

Also, after taking a quick screenshot while the error displayed, it turns out it couldn't load the map. (default/tutorial.rmp). Do you know what's up with that? Is it because it's in a subfolder (maps/default/tutorial.rmp)? And do you think you could output the error to the console too?

Edit: just noticed it plays back the menu sound effects only once, too. Is it because I'm stopping the last instance and then immediately playing it back again, perhaps?


Which OS is this?  If anything other than Windows, I'm impressed you got this far, it means I did something right! ;D  Still, I'd like to diagnose some of this stuff.  I'll go get the game in question and see what I can do.

As for the spacebar to close the error, I originally made it so you had to press Escape to close it, but added the spacebar option for convenience.  Maybe I should go back to just [Esc] to close out.
Title: Re: minisphere 1.0.4
Post by: Fat Cerberus on April 04, 2015, 07:02:04 pm

Also, after taking a quick screenshot while the error displayed, it turns out it couldn't load the map. (default/tutorial.rmp). Do you know what's up with that? Is it because it's in a subfolder (maps/default/tutorial.rmp)? And do you think you could output the error to the console too?

Edit: just noticed it plays back the menu sound effects only once, too. Is it because I'm stopping the last instance and then immediately playing it back again, perhaps?


Figured out the map issue after stepping through the map load function with the debugger a few times.  The map itself loads just fine, it's actually the tileset that causes the load failure.  Good call on the subdirectory thing: It turns out the tileset filename stored in the RMP file is relative to the directory containing that map--whereas minisphere assumes it's always relative to <gamedir>/maps.  So yeah, having the map in a subdirectory tripped it up.  Shouldn't be too difficult to fix.  1.0.5, here we come!

As for the sounds, I have noticed a few issues with sound myself, but I haven't been able to pin down the cause yet.  Either I'm doing something wrong or Allegro's audio routines are glitched.  I'm thinking more the former, though... ;)  The sound stuff was actually one of the first things I implemented way back in the beginning of minisphere's development (yes, my priorities are odd, don't judge me! :) ), so the code could probably use another go-over.

Edit: So apparently minisphere doesn't like playing the same sound more than once, despite the explicit al_seek_audio_stream_secs(stream, 0.0); in js_Sound_stop().  Further investigation will be needed.  I didn't notice this before because all my sound-playing in Specs is done through Scenario's built-in playSound scenelet, which loads sounds anew each time they're played.  I never bothered to implement caching for that scenelet...

Edit2: Damn it, best I can tell it's a race condition in Allegro.  This is my working theory: Allegro apparently runs the stream in a separate thread. When you call the stream functions, it queues the operation to be done on the worker thread.  So even though I've queued a rewind, I also call play immediately afterwards.  I'm guessing Allegro processes the play operation before the seek, so it immediately stops again as it's still at the end of the stream.

Edit3: Aaand I was right.  When the stream ends "naturally" (manual starts and stops don't seem to affect it), the stream feeder thread terminates and never gets restarted unless you recreate the stream.  Looks like it was an Allegro bug after all!
Title: Re: minisphere 1.0.4
Post by: Radnen on April 05, 2015, 01:29:07 am
Big problem. I can't run Blockman in it because it has trouble parsing all the code files. I got it to stop spewing syntax errors due to my use of const, but now it's giving me a 'not callable' issue that I cannot resolve.

Basically the minimal use case looks like this:
Code: (javascript) [Select]

function SuperClass() {
this.weight = 5;
}

function SubClass() {
SuperClass.call(this);
}

SubClass.prototype = new SuperClass(); // ERROR here.

var a = new SubClass();
Abort(a instanceof SuperClass);


The above works 100% in minisphere. Then why the error? In Blockman I use the above pattern on hundreds of files and at some point it starts saying not callable on a myriad of functions using this design pattern. This games runs just fine in Sphere 1.5 and SSFML, but it gives me not callable issues on what are seemingly normal function calls.

I do some tests and try to spout out some info:
Code: (javascript) [Select]

Abort(FuncInQuestion); // FuncInQuestion() { /*ecma code*/ }
Abort(typeof FuncInQuestion); // function
Abort(FuncInQuestion()); // TypeError: not callable


This happens because the analyzer thought these functions were somehow set to not callable, when in fact they are. I'm not sure if it's a scoping thing either because if it were, the first two tests would fail since the function in question could not be found. So this is really weird indeed.
Title: Re: minisphere 1.0.4
Post by: Fat Cerberus on April 05, 2015, 01:33:40 am
Odd, sounds like a Duktape bug.  I could post an issue on the Duktape repo, but I'd need a use case that can reproduce it reliably.  But from the sounds of things I'm guessing you can't reproduce it on command...?
Title: Re: minisphere 1.0.4
Post by: Radnen on April 05, 2015, 01:59:08 am
It's hard when it's a random function call in a many thousand line project. :/

Sometimes it's not just that pattern above but as simple as this:
Code: (javascript) [Select]

function Item() {
    this.inner_item = new Item2(); // not callable error
}


I mean, the Item2() in the example above had been loaded, I can print various qualities about it, but I just can't call it.
Title: Re: minisphere 1.0.4
Post by: Fat Cerberus on April 05, 2015, 02:10:35 am
Code: (javascript) [Select]
var Item = function() {
        return function Item() {
                this.weight = 5;
        }
}

var a = new Item();
Abort(a.weight); // undefined


No bug, no ES deficiency, this code is just broken:
Code: (javascript) [Select]
Abort(a); // function Item() {/* ecmascript */}


[forrestgump]And that's all I have to say about that.[/forrestgump] :P
Title: Re: minisphere 1.0.4
Post by: Radnen on April 05, 2015, 02:16:20 am
No, I'm mentally retarded there. But I'm still getting a not callable issue. Don't know what it could be tho.

It should be:
Code: (javascript) [Select]
var Item = (function() {
        return function Item() {
                this.weight = 5;
        }
})();

var a = new Item();
Abort(a.weight); // 5

Title: Re: minisphere 1.0.4
Post by: Fat Cerberus on April 05, 2015, 03:03:41 am
By the way: minisphere includes an Alert() function that just throws up a message box without terminating the game.  Might be useful for these little testcases.

edit: also where can I get the latest Blockman?  I have an older copy right now from the Spherical Downloads drive, which is actually one of the games I used for compatibility testing. :-). But that version seems to run just fine, so I'm unable to reproduce this issue with it.
Title: Re: minisphere 1.0.4
Post by: Fat Cerberus on April 05, 2015, 03:18:17 am
Oh, and by the way, your whodunnit game works flawlessly since 1.0.1. ;D
Title: Re: minisphere 1.0.4
Post by: Radnen on April 05, 2015, 04:22:12 am
I'll send you a D/L link in a PM since I still don't want this game to be released publicly yet.
Title: Re: minisphere 1.0.4
Post by: Fat Cerberus on April 05, 2015, 09:56:22 am
Interesting, I stepped through the internal call code inside Duktape for the offending call, and it successfully gets into the bytecode for constructor.  So this "not callable" error is very baffling, since it actually does call the function...

Dammit, I just figured out: the error is misleading.  I have an error callback that modifies the filename and line number for error messages starting with "not " because otherwise Duktape doesn't report that info for invalid parameters.  The callback uses the info from one step up the call stack, which means the error is actually inside the constructor.  I will keep investigating.

Edit: Yep, I sent us both on a wild goose chase.  I fixed the error callback to pass through "not callable" errors and here's the actual offending line of code:
Code: (javascript) [Select]
this.__defineGetter__("focusedControl", function() { return _focused_control; });


.......... *facepalm*

I'm going to go sheepishly add __defineGetter__/__defineSetter__ polyfills now... :-[
Title: Re: minisphere 1.0.4
Post by: Fat Cerberus on April 05, 2015, 10:49:29 am
Well, several fixes (and const removals) later I got it to get to the main menu, but I can't move the cursor or even confirm my selection.  Apparently something's borked with my input routines... which is odd, since input seems to work fine in every other game I've tested.
Title: Re: minisphere 1.0.4
Post by: DaVince on April 05, 2015, 11:46:26 am
I'm on Linux, so nice work getting it to work this far! :)


As for the spacebar to close the error, I originally made it so you had to press Escape to close it, but added the spacebar option for convenience.  Maybe I should go back to just [Esc] to close out.

Nah, then the same problem would occur when the error message displays during an esc key press action. I like this short pause you added better.

Still errors out though (http://i.imgur.com/269oLjG.png). Compiled from latest source (updated "an hour ago").
Title: Re: minisphere 1.0.4
Post by: Fat Cerberus on April 05, 2015, 11:50:06 am
Yeah, I didn't fix the map loading issue yet.  I got sidetracked trying to get Radnen's game running. :P. I'll do the fix later today, it shouldn't take too long.  Just have to extract the directory info from the map path and prepend that to the tileset name and I should be golden.
Title: Re: minisphere 1.0.4
Post by: DaVince on April 05, 2015, 11:54:53 am
Ah, okay! Sorry to be premature, I saw updates and just assumed. :P In the meantime, I found another crash (http://i.imgur.com/uV04vlt.png) when trying to open either option 2 or 3 in the menu. I'm not sure what's going on because the offending line looks rather innocent:

Code: [Select]
for (var y = 0; y < this.row_amount; y++)
    { for (var x = 0; x < this.col_amount; x++)
      { var opt = this.options[x][y]; //<<<<< it errors on this line
        if (opt != undefined)
Title: Re: minisphere 1.0.4
Post by: Radnen on April 05, 2015, 12:17:49 pm

Well, several fixes (and const removals) later I got it to get to the main menu, but I can't move the cursor or even confirm my selection.  Apparently something's borked with my input routines... which is odd, since input seems to work fine in every other game I've tested.


SSFML uses a slightly different keymapping. Rename Options2.ini to Options.ini and it'll be set to use the keymaps for Sphere 1.5. I really need to manually change the keymaps, I wonder, do you use 1.5's keymaps?
Title: Re: minisphere 1.0.4
Post by: Fat Cerberus on April 05, 2015, 12:23:45 pm
If you mean GetPlayerKey:

Menu: Tab (I think)
ABXY: Z, X, C, V
Title: Re: minisphere 1.0.4
Post by: DaVince on April 05, 2015, 12:58:25 pm
I also encountered the issue of input not being read in one of my old games. The one attached, to be exact. It expects input from the Ctrl key, but nothing happens. Escape does work for some reason.

(Note: give the game 2 seconds to really start. This is on purpose.)
Title: Re: minisphere 1.0.4
Post by: DaVince on April 05, 2015, 01:29:49 pm
I sent Minisphere 1.0.4 to a friend and she sent the following error message back:

(http://i.imgur.com/zjX9YU2.jpg)

Note that I renamed the file to Sarah.exe, put the game in startup, and the only other folder was system. It worked on Wine so I wouldn't assume it wouldn't even run on her system. I have no clue what this error means at all either.
Title: Re: minisphere 1.0.4
Post by: Fat Cerberus on April 05, 2015, 01:33:43 pm
Looks like a function used by allegro doesn't exist in her version of Windows (kernel32 is the OS kernel)...
Title: Re: minisphere 1.0.4
Post by: DaVince on April 05, 2015, 01:49:08 pm
Okay, well, that's Vista. Guess we got that cleared up. Is it possible to show a more informative error?
Title: Re: minisphere 1.0.4
Post by: Fat Cerberus on April 05, 2015, 01:59:03 pm
Not really, that's an OS-triggered error while loading the executable, no way to catch it because the engine isn't even running yet.
Title: Re: minisphere 1.0.4
Post by: DaVince on April 05, 2015, 02:26:06 pm
After a bit of looking around it seems that compiling with an older MSVC or with MingW would solve this. I might mess around with this later (no promises though :P).
Title: Re: minisphere 1.0.4
Post by: Fat Cerberus on April 05, 2015, 02:50:40 pm
I found this blog post:
http://blogs.msdn.com/b/vcblog/archive/2009/08/27/windows-sdk-v7-0-v7-0a-incompatibility-workaround.aspx

A bunch of Win32 APIs were apparently shuffled around in Win7.  It looks like the fix is as simple as defining a preprocessor macro.  That's a simple enough thing to do, I'll add this to the queue for 1.0.5.  The next release is getting a ton of fixes! :D
Title: Re: minisphere 1.0.4
Post by: DaVince on April 05, 2015, 03:26:23 pm
Awesome! Nice work. :D
Title: Re: minisphere 1.0.4
Post by: Fat Cerberus on April 05, 2015, 08:33:21 pm
Alright, 1.0.5 should relax the Win7+ requirement.  It was the MSVC 11 build of Allegro I was using.  I linked minisphere against the MSVC 9 libs and K32GetModuleFileNameExA disappeared from Dependency Walker. :)

I also fixed the maps in subdirectories issue, but now I'm getting an "invalid base value" error whose cause I can't pin down.  It can never be simple, can it...

@Radnen: OOH, I see what you mean about the mappings now.  I opened the options file, and saw this line:
Code: (javascript) [Select]
keys={"upKey":77,"downKey":79,"leftKey":80,"rightKey":78,"AKey":59,"BKey":55,"XKey":60,"YKey":68,"LKey":72,"RKey":76,"startKey":70,"selectKey":61}


...and suddenly understood jack everything. :P  See, minisphere uses Allegro's key constants directly, it doesn't remap them.  Obviously those values are different than whatever Sphere 1.5 defines them as.  I never thought it would be an issue since I expected games to always use the named constants, but didn't account for the possibility of keys being saved out to a file...
Title: Re: minisphere 1.0.4
Post by: Flying Jester on April 05, 2015, 09:23:23 pm
Out of curiosity, does Duktape support ArrayBuffers or 'let'?
Title: Re: minisphere 1.0.4
Post by: Fat Cerberus on April 05, 2015, 09:25:31 pm
I don't believe so.  I know the developer is currently working on implementing TypedArrays though...

`let` is ES6, yes?  It has some ES6 stuff, but I don't believe that's one of them.  I'd have to double-check though.
Title: Re: minisphere 1.0.4
Post by: Radnen on April 05, 2015, 09:36:06 pm

I never thought it would be an issue since I expected games to always use the named constants, but didn't account for the possibility of keys being saved out to a file...


Yeah, the game has the ability for you to set your own key mappings.

I added the ability for the game to recognize default keys on startup. If no options.ini is available it'll fill it out with the correct keys on first run. If you switch sphere engine, just delete options.ini and it'll re-scan the keys again.
Title: Re: minisphere 1.0.4
Post by: Fat Cerberus on April 05, 2015, 11:59:27 pm
Okay, that did the trick, now I can select stuff from the menu.  Unfortunately, now I'm getting the same error as in DaVince's game: Invalid base value, with no filename or line number to indicate where the issue is.  What fun...
Title: Re: minisphere 1.0.4
Post by: Fat Cerberus on April 06, 2015, 12:34:11 am
Radnen, you'll be happy to know I just got Blockman to run in minisphere. ;D  There do appear to be a few glitches, though--such as persons occasionally "jumping" from one place to another during cutscenes instead of moving smoothly, and some camera jerkiness.  Not sure what's causing that.

However, there's unfortunately one thing that prevents it from being fully playable: FollowPerson is not implemented.  I've been putting that off forever... I knew it would come back to bite me eventually. :(
Title: Re: minisphere 1.0.4
Post by: Radnen on April 06, 2015, 12:38:36 am

Radnen, you'll be happy to know I just got Blockman to run in minisphere. ;D  There do appear to be a few glitches, though--such as persons occasionally "jumping" from one place to another during cutscenes instead of moving smoothly, and some camera jerkiness.  Not sure what's causing that.


Don't worry, happens in Sphere too! :P


However, there's unfortunately one thing that prevents it from being fully playable: FollowPerson is not implemented.  I've been putting that off forever... I knew it would come back to bite me eventually. :(


Yeah, I've been wanting to write my own FollowPerson rather than use Sphere's anyways. :P So once you do fix it, I might not use it. There is only 1 instance in the game FollowPerson is used, and it's optional to follow that person.
Title: Re: minisphere 1.0.4
Post by: Fat Cerberus on April 06, 2015, 01:12:46 am


Radnen, you'll be happy to know I just got Blockman to run in minisphere. ;D  There do appear to be a few glitches, though--such as persons occasionally "jumping" from one place to another during cutscenes instead of moving smoothly, and some camera jerkiness.  Not sure what's causing that.


Don't worry, happens in Sphere too! :P


Oh good, so nothing to fix on my end.  Phew!
Title: Re: minisphere 1.0.5
Post by: Fat Cerberus on April 06, 2015, 02:22:26 am
Well, that was a hell of a ride. 1.0.5 is done.  This release represents a huge chunk of maintenance and fixes about 7 different bugs.  Most of them were pretty minor in the grand scheme of things, but they were enough to prevent a lot of games from running, so fixing them is important.

@DaVince: Could you have your friend try minisphere on Vista again, this time with 1.0.5?  I'm pretty sure the Win7+ requirement is gone, but I don't currently have access to a Vista or XP machine to know for sure.  Also: Sir Boingers now (mostly) works. It tends to error out on death/damage though, due to the stricter type checking in minisphere (this is mentioned in the readme).  With a few edits to the game itself, it should now run flawlessly.  Awesome game, by the way. :D
Title: Re: minisphere 1.0.5
Post by: Radnen on April 06, 2015, 02:25:50 am

Well, that was a hell of a ride. 1.0.5 is done.  This release represents a huge chunk of maintenance and fixes about 7 different bugs.  Most of them were pretty minor in the grand scheme of things, but they were enough to prevent a lot of games from running, so fixing them is important.


I know exactly what you mean by that. ;)
Title: Re: minisphere 1.0.5
Post by: DaVince on April 06, 2015, 09:46:44 am

@DaVince: Could you have your friend try minisphere on Vista again, this time with 1.0.5?  I'm pretty sure the Win7+ requirement is gone, but I don't currently have access to a Vista or XP machine to know for sure.  Also: Sir Boingers now (mostly) works. It tends to error out on death/damage though, due to the stricter type checking in minisphere (this is mentioned in the readme).  With a few edits to the game itself, it should now run flawlessly.  Awesome game, by the way. :D

Sure, I'll send it to her and let you know. And thanks! :)

I've also fixed those bugs, though I'll hold off on releasing a Sir Boingers with such a minor modification until I've done more tests/fixing... and I might as well continue actual development on the game now that I have the opportunity.

Also, I couldn't help but notice that the error displayed was simply "not boolean" - it didn't tell me what variable exactly it was having trouble with. While that was no issue whatsoever for my simple code, imagine it happening on a more complex line.
Title: Re: minisphere 1.0.5
Post by: Fat Cerberus on April 06, 2015, 10:59:33 am

Also, I couldn't help but notice that the error displayed was simply "not boolean" - it didn't tell me what variable exactly it was having trouble with. While that was no issue whatsoever for my simple code, imagine it happening on a more complex line.


A bit of background on that.  Here's what an API function looks like internally:
Code: (javascript) [Select]
static duk_ret_t
js_SetPersonVisible(duk_context* ctx)
{
const char* name = duk_require_string(ctx, 0);
bool is_visible = duk_require_boolean(ctx, 1);

person_t* person;

if ((person = find_person(name)) == NULL)
duk_error_ni(ctx, -1, DUK_ERR_REFERENCE_ERROR, "SetPersonVisible(): Person '%s' doesn't exist", name);
person->is_visible = is_visible;
return 0;
}


duk_require_*() is shorthand for "get the value at this location on stack, but if it's not the type I'm looking for, throw an exception".  It's very convenient, and keeps the code size down.  But normally you don't even get a filename and line number for such errors: the only reason you do in minisphere is because I manually pull it from the call stack. Otherwise you'd just get a completely useless bare "not boolean" error.

I could fix it, of course, but that would require a bunch of extra conditional checks in every single API function, which really puts me off.  Go look at the Sphere source sometime: For a lot of API calls, half the function is argument checking (which, mind you, doesn't really make sense since it still ends up type-coercing 90% of what you throw at it anyway; Spidermonkey is a ridiculously verbose API), and I'd prefer to avoid that here.  The "mini" in minisphere is really about the code size more than anything; the fact that the engine itself takes up less space than Sphere 1.5 is just icing on the cake.
Title: Re: minisphere 1.0.5
Post by: DaVince on April 06, 2015, 11:19:24 am
Okay. If it can't be helped, it can't be helped. Thanks for the explanation.

I really love the fact that all you really need to distribute a game is the engine binary, startup and system folder, by the way. So much cleaner.
Title: Re: minisphere 1.0.5
Post by: Fat Cerberus on April 06, 2015, 11:29:00 am

I really love the fact that all you really need to distribute a game is the engine binary, startup and system folder, by the way. So much cleaner.


Yep, early in development you also needed the Allegro monolith DLL, but a static link fixed that handily (I static link to the MSVC runtime for the same reason).  I always hated that Sphere requires you to distribute about 10 different DLL files along with the engine.  Worse, some of those are only needed for the editor, and it's not necessarily obvious which ones.  So you have to basically guess which ones you can leave out, or just copy them all and bloat your distributable unnecessarily.  Having everything self-contained in the engine executable means that's no longer an issue. :)

If I could, I would also get rid of the system folder requirement, but as a usable system font--at the very least--is required for the engine to even run, not much I can do there.
Title: Re: minisphere 1.0.6
Post by: Fat Cerberus on April 06, 2015, 12:31:25 pm
Just posted a quick hotfix release, 1.0.6, fixing a map collision bug that rendered Sir Boingers unwinnable.
Title: Re: minisphere 1.0.6
Post by: DaVince on April 06, 2015, 01:37:39 pm
Could you insert this after line 40 in minisphere/SConscript? It fixes compilation on Linux:

Code: [Select]
    "m",


Well, I suppose that's not supposed to be in a variable called allegro_libs, but hell if I know where else you're supposed to put it. :P
Title: Re: minisphere 1.0.6
Post by: Fat Cerberus on April 06, 2015, 02:24:30 pm
Done. :)
Title: Re: minisphere 1.0.6
Post by: Fat Cerberus on April 06, 2015, 03:34:55 pm
@Radnen: Curse you and your evil ways! :P  Apparently you delete persons in a command generator script?  minisphere doesn't particularly appreciate entities being pulled out from under it, and it leads to all sorts of random crashes.  Should be fun to fix...
Title: Re: minisphere 1.0.6
Post by: Radnen on April 06, 2015, 07:34:42 pm

@Radnen: Curse you and your evil ways! :P  Apparently you delete persons in a command generator script?  minisphere doesn't particularly appreciate entities being pulled out from under it, and it leads to all sorts of random crashes.  Should be fun to fix...


I guess, I don't remember. I try not to do that in a command generator. In fact I never aim to use it because in Sphere1.5 it's really slow performing.

A pattern I do use is this:

1. I set person to a death animation.
2. I queue animation commands.
3. I queue a person script that destroys the person.

That way the death script is cleanly executed when the animation ends. Otherwise I'm set using an update script, continuously checking for a final state and then destroying the person, making sure I don't accidentally destroy an already destroyed person (which ought to just do nothing, come to think of it).
Title: Re: minisphere 1.0.6
Post by: Fat Cerberus on April 06, 2015, 07:40:30 pm
That's what's crashing it, the person script destroys the entity but the engine tries to read the next command and crashes because the underlying person structure has already been freed.  I didn't anticipate this eventuality, so minisphere doesn't handle it very well.
Title: Re: minisphere 1.0.6
Post by: Radnen on April 06, 2015, 07:49:13 pm
Oh, I see what you mean by command generator, I use the person command queue. I've never been a fan of the GENERATE_COMMANDS command, I'm not sure what it does and SSFML does not have that implemented. I say I'm not sure because it slows down a lot when you put logic in it, like random movement. I found that an update script that iterates over the entities on the map is a 1000 times faster than using the GENERATE COMMANDS script area.

So here is my feature request: Does minisphere's executable icon change? I'm not sure how that works, but is there a way you can set up a build script such that you can build minisphere with your own icon? It's not something I imagine most people doing, but it could be great.

I found minisphere to be way easier than Sphere 1.6 to build, less dependencies and less odd code to go wrong.
Title: Re: minisphere 1.0.6
Post by: Flying Jester on April 06, 2015, 08:22:41 pm
We should, at some point, try to document what all these commands really do. Some are self explanatory, but others like GENERATE_COMMANDS don't really make sense to me. Even COMMAND_WAIT doesn't seem clear to me.
Title: Re: minisphere 1.0.6
Post by: Fat Cerberus on April 06, 2015, 08:27:47 pm

We should, at some point, try to document what all these commands really do. Some are self explanatory, but others like GENERATE_COMMANDS don't really make sense to me. Even COMMAND_WAIT doesn't seem clear to me.


COMMAND_WAIT you insert into the command queue if you want the entity to not do anything for one frame, but otherwise still be under programmatic control.  As for the command generator, the engine calls it for a person on any frame that there is nothing else in that person's queue. Youre supposed to use it to implement automatic movement, e.g. for NPCs.  As for why it's so slow, I have a theory that sphere recompiles it every time it's called.  It should be fast in minisphere since I pre-compile all person scripts.
Title: Re: minisphere 1.0.6
Post by: DaVince on April 06, 2015, 08:32:33 pm
ON_GENERATE_COMMANDS is used to run commands on each frame. (I used it to make people walk and look around in Pokemon GS/SS.)
COMMAND_WAIT is used to add a short pause where a character does nothing for a frame. Useful when you're inputting a list of commands and want to run it all (like walk north, wait a bit, then walk back south). I used that one in GS/SS too.

I wasn't exactly *good* back when I worked on that game, of course. :P But I think COMMAND_WAIT has its uses. ON_GENERATE_COMMANDS, not so much.

...Ninja'd.
Title: Re: minisphere 1.0.6
Post by: Fat Cerberus on April 06, 2015, 09:06:20 pm
The perks of making a compatible engine: you learn how the original works inside and out. :P  up to and including all the annoying little idiosynchrosies that I nonetheless have to emulate to avoid breaking things.  I'm not shy about fixing outright bugs though.  For that reason minisphere will probably never be 100% compatible with Sphere, but that's fine.  If at the end of the day I'm only at 90% parity with vanilla due to bug fixes, I'll take it.

Of course it probably helps that I have a knack for picking up on little subtleties.  Great example being, it didn't take me long at all to figure out that Sphere doesn't destroy entities created before a MapEngine() call, which I believe bit Radnen during SSFML development.  And that even made sense to me: the flag is called `destroy_with_map`, and no map is destroyed in a map engine start since none is loaded yet.

Honestly I think I've had more fun with this project than if I just made a whole new, unrelated engine, which was my original plan.  Getting to see how Sphere works under the hood was worth it all by itself. :)

As for command generator scripts, I wouldn't give them up for anything.  It helps keep each entity self-contained without having to feed NPCs movement commands from somewhere else in the code (the update script, for instance).  Any time the engine offers to manage something for me, I'll jump at the chance.  Less bookkeeping to bloat my own code that way. :P
Title: Re: minisphere 1.0.6
Post by: Fat Cerberus on April 07, 2015, 02:10:25 am
I just added the Allegro libs to the repo.  This makes it ridiculously simple to build the engine on Windows as everything needed is now included--you just need to provide MSVC, which is also simple thanks to VS Community.  One of the many benefits of having all your dependencies be MIT/zlib licensed--you can just throw the files in and not have to worry about licensing issues. :)

Obviously there are no issues on Linux or OS X thanks to the SCons script, but I know compiling in Windows can be hell (and I develop in Windows, so that's saying something! :P), so doing this will make everyone's life a lot easier.
Title: Re: minisphere 1.0.6
Post by: Radnen on April 07, 2015, 02:23:12 am
There is no NuGet for C projects? If so, I guess Allegro isn't there... I just took dependencies out of Sphere Studio and into NuGet packages to decrease the filesize of the git repo. Too bad though since it's been logged in the commit history, so those old DLL files will truly stay in it forever. :/
Title: Re: minisphere 1.0.6
Post by: Fat Cerberus on April 07, 2015, 02:27:28 am
No Allegro on NuGet, I've already checked.  That was the first thing I tried, but no such luck.  No DLLs in mine though, just about 13MB worth of .lib files... Oh well.  Note that the debug build is static-linked now as well.  Maybe I'll think about adding console logging to it now...

Edit: Wait, no, make that 5MB.  Not too bad, then.  Not sure where I got 13 from...
Title: Re: minisphere 1.0.6
Post by: DaVince on April 07, 2015, 06:21:53 am

Of course it probably helps that I have a knack for picking up on little subtleties.  Great example being, it didn't take me long at all to figure out that Sphere doesn't destroy entities created before a MapEngine() call, which I believe bit Radnen during SSFML development.  And that even made sense to me: the flag is called `destroy_with_map`, and no map is destroyed in a map engine start since none is loaded yet.


Actually, it seems like there's a bug regarding not destroying persons: when Sir Boingers switches to the next map, all the entities from the previous map are spawned at the entry point location. Which means I get to see this when starting level 2. Those objects (the flame, blue pad and spike ball above it) are all from level 1.

(http://i.imgur.com/QDutsU8.png)

This causes "person does not exist" issues down the line (like when dying/restarting the level).

Edit: by the way, you can experience this quickly for yourself by pressing F7 (the skip level key). It accumulates with each level.

Edit 2: mp3 is not supported, the engine crashes with a playback error. Is that right?
Title: Re: minisphere 1.0.6
Post by: DaVince on April 07, 2015, 07:38:26 am
Okay, I've found out what the "Invalid base value" error was. I suspect that my code had a bug in it - namely that it would try to access an array inside an array, except the outer array would sometimes be undefined. What I mean is that there's a possibility that x in this.options[ x ][ y ] might have been undefined. Original Sphere seemed to be able to handle this.options[undefined][0] but Duktape doesn't. (And really, why should it? :) )

After adding this line to my code, everything is fine again:
Code: [Select]
if (this.options[x] == undefined) continue;
Title: Re: minisphere 1.0.6
Post by: Fat Cerberus on April 07, 2015, 09:24:40 am
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.

As for the persons respawning at the start of the next level, I noticed that myself, but thanks to a lack of testing in Sphere 1.5 I didn't realize it was a minisphere bug--I thought it was a bug in Sir Boingers.  Are you exiting and restarting the map engine when switching levels by any chance?  Because I'm thinking that's what it is--minisphere normally removes transient persons when switching maps just like in Sphere, but this doesn't happen if you stop and restart the map engine.  Apparently it does in Sphere.

Oh and yes, no mp3 support sadly :(.  Allegro apparently doesn't include it, I assume due to licensing issues, and I haven't yet found any addons to re-add support for it.
Title: Re: minisphere 1.0.6
Post by: DaVince on April 07, 2015, 09:30:27 am
Yep, I close and reopen the map engine. It ended up working out better (the map engine only runs when necessary - I can finish a map, run some code, then continue with the next one in a more convenient way). That must be the issue, then.

And my test case doesn't work in regular Sphere either (errors out with "has no properties" too). I'm not exactly sure why my fix worked and the game works fine in regular Sphere.
Title: Re: minisphere 1.0.6
Post by: Fat Cerberus on April 07, 2015, 11:02:27 am
I fixed the bug.  Try the latest master.  :D
Title: Re: minisphere 1.0.6
Post by: casiotone on April 07, 2015, 12:14:10 pm

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.
Title: Re: minisphere 1.0.6
Post by: Fat Cerberus on April 07, 2015, 12:44:38 pm

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.
Title: Re: minisphere 1.0.6
Post by: Defiant on April 07, 2015, 08:22:04 pm
So I downloaded miniSphere the other day, and maybe I'm a little dunce, but does this work on XP? I keep getting an error saying it's not a vaild Win32 application, is there something I'm missing?
Title: Re: minisphere 1.0.6
Post by: Fat Cerberus on April 07, 2015, 08:35:51 pm
That doesn't make sense.  I could see if maybe it wasn't compatible with XP and crashed or something, but "not a valid win32 application" suggests the .exe got corrupted somehow.  It's not a 64-bit build either... Odd.
Title: Re: minisphere 1.0.6
Post by: Defiant on April 07, 2015, 08:53:41 pm
I've tried downloading from both Git-hub and the google drive links, both throw that error.
Title: Re: minisphere 1.0.6
Post by: Fat Cerberus on April 07, 2015, 08:56:41 pm
From GitHub... You compiled it yourself?  It definitely shouldn't be showing that particular error.  The only time you should get that is if the .exe is either corrupt or 64-bit, and since I know for a fact it's not the latter...

I will do some research myself.
Title: Re: minisphere 1.0.6
Post by: Fat Cerberus on April 07, 2015, 09:02:32 pm
Okay, just found out I have to change the MSVC project configuration to get it to run on XP.  Apparently MSVC 2012 and later only target Vista+ by default.  My bad.

That doesn't explain the error if you're building it yourself though... Sounds like a virus.
Title: Re: minisphere 1.0.6
Post by: Defiant on April 07, 2015, 09:05:46 pm
Brain fart, I thought there was a link on Github for the pre-compiled version of it, I remember downloading the source, but never tried to compile it, my bad. So yea, only actually downloaded it from the Google drive on a couple separate instances and same thing.
Title: Re: minisphere 1.0.6
Post by: Fat Cerberus on April 07, 2015, 09:11:22 pm
Alright, then that's my fault.  A quick toggle in MSVC will fix it, chalk up another one for 1.0.7. :P. Thanks for reporting. :D
Title: Re: minisphere 1.0.6
Post by: Fat Cerberus on April 07, 2015, 10:32:11 pm
Okay, everybody, word to the wise for Sphere implementors: Don't use a texture atlas for windowstyles.  For a while now I've been trying to figure out what happened to cause the main screen in Radnen's SSFML test suite to slow down to a crawl (~20 fps) when it ran well before.  When I first noticed this, I ran minisphere in the profiler (VS 2013 Community is awesome) and found out Allegro was switching to software rendering when drawing the windowstyle.  That was about a week ago, and then I forgot about it because I had no idea what might be causing it.

Just now it finally dawned on me: Quite a while ago I modified the windowstyle loader to load the bitmaps into an atlas instead of individually.  The reason for the switch to software rendering is because I use U/V tiling... which can't be done in hardware for only part of a texture, so Allegro switches to software to pull it off.

Of course, the flipside of this illustrates just why I love Allegro: It does everything in its power to service a request without me having to write a ton of fallback code.  This keeps minisphere's codebase small and still ensures it will run on as many systems as possible. 8)
Title: Re: minisphere 1.0.6
Post by: Radnen on April 08, 2015, 12:16:46 am

Oh and yes, no mp3 support sadly :(.  Allegro apparently doesn't include it, I assume due to licensing issues, and I haven't yet found any addons to re-add support for it.


SSFML can play mp3, but no idea on the licensing.

The Sphere Studio can, but it's an IrrKlang plugin, so I can remove the support at any time if licensing ever becomes an issue.

I thought allegro uses any audio codecs installed/recognized by it. It's odd for it to not have that ability, unless I'm missing something.
Title: Re: minisphere 1.0.6
Post by: Fat Cerberus on April 08, 2015, 12:19:51 am
MP3 is patented and requires a licensing fee and/or royalties if your project is large enough.  Hence most open-source libraries leave it out.  That's why Vorbis was invented. :P
Title: Re: minisphere 1.0.6
Post by: casiotone on April 08, 2015, 03:56:23 am


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.
Title: Re: minisphere 1.0.6
Post by: Fat Cerberus on April 08, 2015, 03:01:38 pm
minisphere 1.0.7 is coming.  I'm almost tempted to do a version bump to 1.1 due to both Duktape and Allegro receiving major upgrades (1.2.1 and 5.1.9 respectively), but as that's under-the-hood, I think I will keep it at 1.0 for now.

In any case, the Allegro upgrade shrunk the size of the engine from around 2.5mb down to about 2mb--and even seems to have made things faster! ;D
Title: Re: minisphere 1.0.7
Post by: Fat Cerberus on April 09, 2015, 02:28:24 pm
1.0.7 is out!

Radnen, try running Blockman in minisphere now.  It works much better with the fixes in this release.  Also: The engine is now under 2MB and still completely self-contained!

@Defiant: Could you try this latest release on XP?  I ended up having to build Allegro and all its dependencies myself with VS2013 in XP mode (9 static libraries for those keeping count  :-\), so it better work now or I might have to murder someone. :P
Title: Re: minisphere 1.0.7
Post by: Fat Cerberus on April 10, 2015, 02:06:04 am
This just in: I got the minisphere engine binary down to under 1.5MB without sacrificing any functionality. :)  Compiling Allegro myself was totally worth it, I can leave out all the useless stuff I don't need (like OpenAL, which Allegro doesn't even really take advantage of).  This means the engine is less than a third the size of Sphere 1.5! (By my count, 6.5MB, including the config utility and video plugins and excluding the editor)

minisphere truly lives up to its name! 8)

Also fixed: The audio deadlocks.  I may not have mentioned it, but after the Allegro upgrade I started seeing random hangs when playing sounds.  I'm guessing these were caused by OpenAL, since that's the biggest thing I excised from Allegro and the lockups have since stopped happening. *crosses fingers*
Title: Re: minisphere 1.0.8
Post by: Defiant on April 10, 2015, 07:47:58 pm
@Lord English:
It's at least a valid application now, but it crashes on opening it.

Title: Re: minisphere 1.0.8
Post by: Fat Cerberus on April 10, 2015, 07:52:10 pm
Hm, I might have to set up a virtual machine with XP for testing.  Not sure why it's crashing like that, if you click for more details (the Click Here link), what does it say?
Title: Re: minisphere 1.0.8
Post by: Defiant on April 10, 2015, 08:00:19 pm
It comes up with the screenshot below... but when I click technical details I can't copy&paste the information there, and it's got all the modules and some hex data.
Title: Re: minisphere 1.0.8
Post by: Fat Cerberus on April 10, 2015, 08:10:21 pm
That's helpful, actually--it's a null pointer dereference.  All the zeroes under address are a dead giveaway.  Something isn't being initialized properly for whatever reason...

I'll investigate.
Title: Re: minisphere 1.0.8
Post by: N E O on April 11, 2015, 01:54:58 pm
Re MP3 (and certain other file types) support - would you like to give a try to using JS loaders like mp3.js for these?
Title: Re: minisphere 1.0.8
Post by: Fat Cerberus on April 11, 2015, 05:51:24 pm
That would of course be an option, although it would require me to expose some sort of raw stream object to script, which would deviate pretty sharply from the Sphere 1.x API.  Maybe for minisphere 2.0 (the planned Pegasus edition), but certainly not in this first version.
Title: Re: minisphere 1.0.8
Post by: Flying Jester on April 11, 2015, 07:57:23 pm
it would require me to expose some sort of raw stream object to script


An ArrayBuffer. The word you are looking for is ArrayBuffer.  :P  But It should be possible even with ye olde ByteArrays, though, shouldn't it?

We need to do a lot of work on Pegasus still. Right now it's still just an early draft. I agree with most of it, but there are lots of little points to iron out, and lots of stuff I don't think should be a part of the core API but rather an extension.
Title: Re: minisphere 1.0.8
Post by: Fat Cerberus on April 11, 2015, 08:36:38 pm
The ArrayBuffer is only part of it. That's just data after all--the engine itself still has to be able to know what to do with it. It's like saying you could implement networking entirely in script with just ByteArrays. :P

Also, I'm pretty sure Duktape doesn't support ArrayBuffers. (Not yet anyway.  The developer is working on it from what I understand...)

As for Pegasus and not being finalized: let me just say I despise design-by-committee.  I'd rather forge ahead now and work out the specifics later.  I don't really mind refactoring and we want to get people excited about Sphere 2.0, which isn't going to happen unless they see concrete evidence in the form of a working engine.

I mean look at ES6.  That's still a draft, but a lot of JS engines went ahead and implemented parts of it anyway.  Duktape has the Proxy object for example--which I took advantage of to implement ByteArrays in minisphere.  And seeing that in action in turn got me more excited about ES6.  I don't see why we can't do the same with Pegasus.
Title: Re: minisphere 1.0.8
Post by: Flying Jester on April 11, 2015, 09:53:42 pm

The ArrayBuffer is only part of it. That's just data after all--the engine itself still has to be able to know what to do with it. It's like saying you could implement networking entirely in script with just ByteArrays. :P



Fair enough. I still need to actually expose this from my audio plugin, too.



As for Pegasus and not being finalized: let me just say I despise design-by-committee.  I'd rather forge ahead now and work out the specifics later.  I don't really mind refactoring and we want to get people excited about Sphere 2.0, which isn't going to happen unless they see concrete evidence in the form of a working engine.


Sure. Most of my concerns could even be fixed just by changing what is required to be called an extension and what isn't :)
Title: Re: minisphere 1.0.9
Post by: Fat Cerberus on April 12, 2015, 02:13:20 am
1.0.9 is now available, now with FollowPerson(), function support for Set*Script, and a couple small fixes.
Title: Re: minisphere 1.0.9
Post by: DaVince on April 12, 2015, 08:40:23 am
I see you made FollowPerson() behave exactly like in Sphere 1.5, which is to say it takes the follower a bit of walking before suddenly warping in behind the leader. I always thought the FollowPerson() function was useless exactly *because* it behaves this way. Could you make it instead that the follower will try to catch up to the leader from whatever position they were already in when the FollowPerson() command was called?
Title: Re: minisphere 1.0.9
Post by: Fat Cerberus on April 12, 2015, 09:55:21 am
The problem there is that doing that requires built-in pathfinding, something I'm not too keen on building into the engine. I don't think that's really the function's intended purpose anyway--it's just a minimal implementation you can use to make your party members follow each other around.  Anything more advanced is left up to the game developer to do in script.

TL;DR incoming: See, I've learned something while working on this project, it's the thing that makes Sphere such an awesome engine: It provides a lot of built-in functionality, which allows you to get a game up and running very quickly, but it's also quite deliberately designed to get out of the way when you decide you want to step outside of its provided parameters.  You generally don't appreciate this as someone on the outside looking in developing a game, but seeing the finer points of how the engine does things under the hood, I've started to appreciate the little subtleties.

A great example: I had to fix edge script triggering not once, but twice because of this.  When I first implemented edge scripts, a cursory glance at the reference implementation (i.e. Sphere) yielded this code:
Code: (c++) [Select]
if (input_valid)
{
    if (!UpdateEdgeScripts())
        return false;
}

I naturally interpreted this to mean that edge script activation requires a valid input attachment (AttachInput).  I later found out this wasn't the case when the Trial and Error intro turned out to be broken in minisphere, and, after another quick look--this time at the UpdateEdgeScripts() function--changed it to require an active camera attachment instead.  This fixed T&E, but was still incorrect, which I didn't find out until Radnen sent me his Blockman game and I couldn't move between maps.  The game manages the camera itself in script, so there's no AttachCamera() calls to be found.  In other words, the edge script activation logic only cares about where the camera actually *is*, not who's holding it.  Realizing this was an epiphany: I suddenly understood that the engine was deliberately designed this way so that you could replace AttachCamera() with your own implementation if you wanted to, and that doing so wouldn't break other things that you might not necessarily want to replace.

Sphere doesn't look like much, but it's actually a pretty well-engineered little engine. :D

As for that input_valid variable?  Turns out what it actually means is whether the map engine is currently accepting input at all (i.e. are we inside the main MapEngine() loop), regardless of whether there's a current input attachment or not.  Poor choice of naming, which I of course rectified in minisphere (it's called is_main_loop there :P).
Title: Re: minisphere 1.0.9
Post by: DaVince on April 12, 2015, 12:11:09 pm
Quote
The problem there is that doing that requires built-in pathfinding, something I'm not too keen on building into the engine. I don't think that's really the function's intended purpose anyway--it's just a minimal implementation you can use to make your party members follow each other around.  Anything more advanced is left up to the game developer to do in script.


Well, I honestly was just thinking about solving it like "move toward player at twice or thrice the normal speed without regarding any collision" (since it disregards collision anyway) just so the transition of a character being where it is to arriving near the player makes more sense. I never expect FollowPerson() to be used when the follower isn't already at least near the leader, and there wouldn't be a point to the function at all when it's implemented with its current looks-like-it-is-bugged behavior. And I rather like the simple function and would use it if it wasn't for this one small nagging thing.

Also, that is an extremely cool story! Pretty neat way for the engine to figure out the right thing. :D
Title: Re: minisphere 1.0.9
Post by: Fat Cerberus on April 12, 2015, 01:40:23 pm
Well to be fair, it doesn't have to deal with collision since the followers just follow the exact path the leader does and outside of edge cases with vastly different base dimensions, they're guaranteed not collide with anything either.  This improves performance, which is important since the follow tracking has to move a lot of data around every frame itself.

But I do agree with the sentiment here.  I'll see what I can do.  Post an issue on GitHub about it so we can track it. :)
Title: Re: minisphere 1.0.9
Post by: DaVince on April 12, 2015, 02:56:06 pm
Done (https://github.com/fatcerberus/minisphere/issues/22). I also explained how I think this would work best while keeping it simple, in my opinion.
Title: Re: minisphere 1.0.9
Post by: Fat Cerberus on April 13, 2015, 02:00:38 am
Okay, functions-as-scripts is awesome and I have no idea why I didn't implement it sooner.  As part of my tests of SetDefaultPersonScript I wrote this bit of tomfoolery:

Code: (javascript) [Select]
SetDefaultPersonScript(SCRIPT_ON_ACTIVATE_TOUCH, function() {
food = GetCurrentPerson();
if (GetInputPerson() == 'maggie' && food != 'robert') {
new Scenario()
.playSound('Munch.wav')
.run();
DestroyPerson(food);
}
});


So much nicer than using a string for that; you don't get syntax highlighting for code in strings. :P  Also, yes: minisphere has SetDefaultPersonScript.  Sphere 1.5 apparently has it as well (I didn't think it did, but no unknown identifier errors when I call it), however it appears to be broken there as my test above didn't work in vanilla.  It works perfectly in minisphere. :D  So much eatiness...

Edit: Well, that explains that then.  Apparently Sphere's implementation of default person scripts is only partial: It only ever calls the default script for ON_CREATE, none of the other default person scripts are ever touched.  How did such an incomplete implementation like that ever make it into the official 1.5 release? ???
Title: Re: minisphere 1.0.9
Post by: Fat Cerberus on April 14, 2015, 02:13:41 am
Well, the next release is coming along.  This one is taking longer than usual since I want to get all the wrinkles ironed out first, as I'm planning for 1.0.10 to be the last 1.0 release before I start working on a few bigger changes for minisphere 1.1 (FollowPerson enhancements, config.exe...).

I finally fixed an audio deadlock bug that's been plaguing me since upgrading Allegro a few releases ago.  I assume nobody else ran into it as I received no bug reports of the sort, which I suppose is a good thing.  Here's what the changelog for 1.0.10 looks like thus far:

Code: [Select]
v1.0.10 - 
- Fixes IsKeyPressed() not recognizing modifier keys on right side of
  keyboard (#20)
- Improves SetPersonFrame compatibility (out-of-range frame is now
  wrapped instead of throwing an error)
- Fixes joystick assert error when running minisphere in OS X. (#19)
- Fixes wrong direction being rendered for 4-direction person sprites
  moving diagonally
- Fixes random deadlocks when playing sounds


So quite a few small but important fixes here.

Oh, also, @Radnen: Did you ever test out the SetPersonFrame fix I posted on GitHub?  I was waiting on you to test it before I merged it into master.
Title: Re: minisphere 1.0.9
Post by: Radnen on April 14, 2015, 10:00:02 am

Oh, also, @Radnen: Did you ever test out the SetPersonFrame fix I posted on GitHub?  I was waiting on you to test it before I merged it into master.


Yeah I saw it, I've literally had no time to test it. I'll test later today, sorry for the wait.
Title: Re: minisphere 1.0.9
Post by: Fat Cerberus on April 14, 2015, 03:28:02 pm
New plan for v1.1: a native x64 Windows build.  Now that I can compile Allegro myself on Windows, there's little stopping me from doing this. :)
Title: Re: minisphere 1.0.9
Post by: Flying Jester on April 14, 2015, 05:08:02 pm
It's always best to compile your dependencies yourself on Windows :)
Title: Re: minisphere 1.0.9
Post by: Radnen on April 14, 2015, 10:21:30 pm

Oh, also, @Radnen: Did you ever test out the SetPersonFrame fix I posted on GitHub?  I was waiting on you to test it before I merged it into master.


Yes, it fixed it. Also, minisphere is too much like sphere 1.5 in that it has the same animation bug that future boy nil fixed. You notice it in my blockman game when picking up bushes, rockets, etc. It has a glitchiness due to the last frame not being respected (when the last frame is met, make sure to go through it entire delay stack before switching over to frame 0).
Title: Re: minisphere 1.0.9
Post by: Fat Cerberus on April 14, 2015, 10:24:56 pm
What exactly is the bug?  Odd that I would have replicated it, as I made sure to always initialize the delay when switching frames.  There must be oddities with the animation setup that make it easy to screw up...
Title: Re: minisphere 1.0.9
Post by: Fat Cerberus on April 14, 2015, 11:06:45 pm
Hm, I think I found the "bug".

Blockman: 5 frames (excluding east/west which have 4)
Held object: 4 frames

SetPersonFrame() now correctly modulus-wraps the frame index, HOWEVER GetPersonFrame() returns the real current frame.  This is the source of the problem.  To illustrate:

Suppose Blockman is currently on the fourth frame of his animation:


Not really sure how FBN would have "fixed" this, as I wouldn't consider it a bug in the first place. ???
Title: Re: minisphere 1.0.9
Post by: Radnen on April 15, 2015, 12:03:33 am
It's with QueuePersonCommand and COMMAND_ANIMATE.

Say you have 5 frames at 8 delay frames each, you can loop through like this to animate a direction:
Code: (javascript) [Select]

for (var f = 0; f < 5; ++f) {
    for (var d = 0; d < 8; ++d) {
        QueuePersonCommand(COMMAND_ANIMATE);
    }
}


You'll notice in Sphere 1.5 you get a strange glitch in the animation where f == 4, we are at frame 0 for 8 frames. In Sphere 1.6 when f ==4, it correctly animates frame 5 for 8 frames.
Title: Re: minisphere 1.0.9
Post by: Fat Cerberus on April 15, 2015, 01:47:22 am
minisphere's COMMAND_ANIMATE implementation looks like this:

Code: (c) [Select]
switch (command) {
case COMMAND_ANIMATE:
    person->revert_frames = person->revert_delay;
    if (person->anim_frames > 0 && --person->anim_frames == 0) {
        ++person->frame;
        person->anim_frames = get_sprite_frame_delay(person->sprite, person->direction, person->frame);
    }
    break;
// ...
}


And for good measure, get_sprite_frame_delay:
Code: (c) [Select]
int
get_sprite_frame_delay(const spriteset_t* spriteset, const char* pose_name, int frame_index)
{
    const spriteset_pose_t* pose;
   
    if ((pose = find_sprite_pose(spriteset, pose_name)) == NULL)
        return 0;
    frame_index %= pose->num_frames;
    return pose->frames[frame_index].delay;
}


Looking at this code, I don't understand why this is happening, but I'm rather tired at the moment.  I'll have to investigate properly in the morning.
Title: Re: minisphere 1.0.9
Post by: Radnen on April 15, 2015, 01:49:55 am
Are you looking at Sphere 1.5's source or 1.6's? I'd compare the two to see what he did...
Title: Re: minisphere 1.0.9
Post by: Fat Cerberus on April 15, 2015, 01:51:09 am

Are you looking at Sphere 1.5's source or 1.6's? I'd compare the two to see what he did...


I have the one from sphere-group on GitHub, I assume that's 1.6?  That's what I've been using as reference this whole time.
Title: Re: minisphere 1.0.9
Post by: Radnen on April 15, 2015, 02:50:55 am
I thought the github branch had branches for 1.5/1.6, but to me it seems to be all of 1.6. Maybe that code is the corrected version? But your engine still has the Sphere 1.5 animation bug. Hmm...
Title: Re: minisphere 1.0.9
Post by: Flying Jester on April 15, 2015, 03:23:09 am

...but to me it seems to be all of 1.6.

I'm 99% sure that Sphere-Group/Sphere is 1.6, with some more work done after the official 1.6 beta binaries were made. Well, plus the work Raahkin and I did to make it work again on OS X and Linux, respectively. It's got the particle engine, the new sound effect object, and some other secret new stuff like the zlib API that shouldn't be in 1.5.
Title: Re: minisphere 1.0.9
Post by: Fat Cerberus on April 15, 2015, 10:36:55 am
...wow.  Just all I will say is "wow".  Still haven't found the cause of the animation bug, but I did find this:

Code: (c++) [Select]
for (unsigned int i = 0; i < m_Directions.size(); i++)
  if (strcmp_ci(direction.c_str(), m_Directions[i].name.c_str()) == 0)
  {
    d = i;

    // stop immediately.
    i = m_Directions.size();  // <-- wtf
  }


Traditionally most people early-terminate a for loop using a break statement...

Edit: Here are the results of my tests: COMMAND_ANIMATE seems to work fine.  Your Blockman sprite has a delay of 4 on each frame, so I did the following:
Code: (c++) [Select]
SetPersonSpriteset('robert', LoadSpriteset('blockman.rss'));
for (i = 0; i < 5; i++) for (j = 0; j < 4; ++j) {
Console.writeLine("Frame: " + GetPersonFrame('robert'));
Console.append("i = " + i);
Console.append("j = " + j);
FlipScreen();
QueuePersonCommand('robert', COMMAND_ANIMATE, false);
UpdateMapEngine();
}


It correctly cycled through all the frames (originally there was some log output here but it was a waste of space).  Sphere 1.5 was somewhat odd as it stayed on frame 0 twice as long the first time around (8 frames instead of 4), but otherwise cycled through all 5 images as normal.

Are you sure your issue wasn't with SetPersonFrame() and not COMMAND_ANIMATE?  Because that was the only difference I could find between 1.6 and minisphere, minisphere's SetPersonFrame wasn't resetting the animation frame counter.

Edit 2: Yeah, it was SetPersonFrame.  Sphere 1.5:
Code: (c++) [Select]
m_Persons[person].frame = frame;


Sphere 1.6:
Code: (c++) [Select]
m_Persons[person].frame = frame;
m_Persons[person].stepping_frame_revert_count = 0;
m_Persons[person].next_frame_switch = p.spriteset->GetSpriteset().GetFrameDelay(p.direction, p.frame);


1.6 resets the frame counter when the frame is set explicitly, 1.5 doesn't.  minisphere follows the 1.6 implementation now.
Title: Re: minisphere 1.0.9
Post by: Fat Cerberus on April 15, 2015, 02:28:51 pm
I just made my first x64 build of minisphere, and it's working great!  There's a good number of warnings due to conversions between int and size_t but other than that no issues that I've noticed so far.  Note that Allegro and every one of its dependencies generated similar warnings; whoever had the bright idea that both int and long should be 32-bit in 64-bit MSVC needs to be shot.

The best part?  The 64-bit build actually seems faster, especially noticeable with games that load a lot of resources upfront. :)
Title: Re: minisphere 1.0.10
Post by: Fat Cerberus on April 16, 2015, 01:45:06 pm
minisphere 1.0.10 is out.  I'm including the 64-bit build as an experimental surprise addition to 1.0.10 so that it can get some real-world testing before it's officially unveiled in minisphere 1.1. :)  Aside from that, this is basically a huge bugfix release to hopefully stabilize the 1.0 engine for real-world use.
Title: Re: minisphere 1.0.10
Post by: Fat Cerberus on April 16, 2015, 11:54:51 pm
So I had my first foray into 64-bit debugging in MSVC.  It was a simple 10-second fix for a null dereference, but boy was the exception dialog (shown below) disorienting.  I've been debugging 32-bit C/C++ apps for years, so I'm used to seeing this dialog, but all the extra digits in the memory addresses... wow.  It took me a good 20 seconds I think to recover from the shock, it was dizzying. :P
Title: Re: minisphere 1.0.10
Post by: Fat Cerberus on April 18, 2015, 01:52:02 am
Anyone have any suggestions for what they want to see in minisphere 1.1?  Almost my entire v1.1 checklist has been checked off except for implementing config.exe, so I figure I should solicit feature requests now. :)
Title: Re: minisphere 1.0.10
Post by: Radnen on April 18, 2015, 04:04:05 am
How do we check if we are running a game in minisphere? GetVersion() and GetVersionString() might have to take a parameter... not sure what though, here's the deal:

1. You can't overwrite the functionality of these functions because games check against them for compatibility, so they should return the API complacency. (v1.5 for the string and 1.5 for the number).
2. You can't pass 'true' to them to get minisphere's version since in SSFML, I could also return it's unique version too.
3. You pass a string, 'minisphere', to get minisphere's version. It returns nothing if you don't use minisphere. Trouble is, Sphere 1.5 will still return it's version number.

So... I guess the only way to detect sphere version is by feature detection. Namely we can use the features/apis function... whatever it was named.
Title: Re: minisphere 1.0.10
Post by: Fat Cerberus on April 18, 2015, 09:08:56 am
Check whether GetExtensions exists.  If it doesn't, that's stock Sphere.  If it does, call it and check if 'minisphere' is included in the extensions list.  That's why I added that function, and why I also added it to SSFML recently as well.

That said, do note that GetVersionString() in minisphere returns a string like this:
Code: [Select]
v1.5 (compatible; minisphere 1.0.10)


I've been doing that since minisphere's inception and haven't had a game break because of it yet.
Title: Re: minisphere 1.0.10
Post by: Fat Cerberus on April 18, 2015, 10:50:27 am
Just implemented a bunch of new APIs for follower management for 1.1.  FollowPerson was one of those dark corners of the Sphere map engine that really needed some love; heck, the only way to get a person's leader was through engine-provided metadata returned by GetPersonData, and the rest of the info was just unavailable.  minisphere 1.1 will add the following APIs:



I have to thank DaVince for pointing out deficiencies in the Sphere implementation, or it never would have received these enhancements.  You can now write a handler, for instance, that condenses follower chains when a person in the middle of the chain is destroyed:
Code: (javascript) [Select]
SetDefaultPersonScript(SCRIPT_ON_DESTROY, function() {
var person = GetCurrentPerson();
var distance = GetPersonLeader(person) != "" ? GetPersonFollowDistance(person) : 0;
Link(GetPersonFollowers(person)).each(function(name) {
FollowPerson(name, GetPersonLeader(person), distance);
});
});
Title: Re: minisphere 1.0.10
Post by: Radnen on April 18, 2015, 12:33:03 pm

That said, do note that GetVersionString() in minisphere returns a string like this:
Code: [Select]
v1.5 (compatible; minisphere 1.0.10)


I've been doing that since minisphere's inception and haven't had a game break because of it yet.


I guess my fear there is someone is checking against the string. So far there hasn't been an issue tho. Yes, GetExtensions was what I was thinking about, I guess it's the only reliable solution.
Title: Re: minisphere 1.0.10
Post by: Fat Cerberus on April 18, 2015, 12:38:45 pm
Yeah, I would have changed the string back by now if there were a compatibility issue.  From what I've observed, games that want to detect version level use GetVersion() instead, which returns 1.5 as always.  Which makes sense, since then you can use comparison operators on it:

Code: [Select]
if (GetVersion() < 1.5) {
  Abort("Unsupported engine version!");
}
Title: Re: minisphere 1.0.10
Post by: DaVince on April 18, 2015, 01:50:30 pm


That said, do note that GetVersionString() in minisphere returns a string like this:
Code: [Select]
v1.5 (compatible; minisphere 1.0.10)


I've been doing that since minisphere's inception and haven't had a game break because of it yet.


I guess my fear there is someone is checking against the string. So far there hasn't been an issue tho. Yes, GetExtensions was what I was thinking about, I guess it's the only reliable solution.

Even if there is, it's their problem to solve. They wrote the game for Sphere 1.5, and it's pretty obvious that not every single stock 1.5 game works out of the box with minisphere (for example, any using the const keyword, or any using MP3 files).
Title: Re: minisphere 1.0.10
Post by: Radnen on April 18, 2015, 02:30:43 pm

Even if there is, it's their problem to solve. They wrote the game for Sphere 1.5, and it's pretty obvious that not every single stock 1.5 game works out of the box with minisphere (for example, any using the const keyword, or any using MP3 files).


Yeah, I guess you're right. New games shouldn't have that problem. I already modified Blockman to run in minisphere, I guess old games are just stuck with old engines.
Title: Re: minisphere 1.0.10
Post by: Flying Jester on April 18, 2015, 05:18:26 pm
I suggest adding SetTileName(). I added that to my map engine just because I thought it was odd it was missing, and it was trivial to add.
Title: Re: minisphere 1.0.10
Post by: Fat Cerberus on April 18, 2015, 05:19:58 pm
Yeah, that would be trivial to add.  Is there a valid use case for it though?  I try not to add APIs just for the sake of it, trying to minimize perceived bloat.
Title: Re: minisphere 1.0.10
Post by: Flying Jester on April 18, 2015, 05:39:43 pm
I'm not sure it has a proper need, but every other method that has a Get also has a Set. I added it just for consistency.
Title: Re: minisphere 1.0.10
Post by: Radnen on April 18, 2015, 05:46:21 pm

Yeah, that would be trivial to add.  Is there a valid use case for it though?  I try not to add APIs just for the sake of it, trying to minimize perceived bloat.


GetTileName() is impossible otherwise, keep that in mind too.

Actually, if you want to reduce bloat, then it'd be nice to make a method where you get a POJO (plain old javascript object) of the map and it's tileset. You can then modify said POJO, re-update the map, and see the changes.

We can create Sphere 1.5 complacent wrappers around that POJO. This will ad 2 new calls to the map engine and literally remove anywhere between 20 and 50 API calls from Sphere.

Going one step further, it'd be neat to store the map POJO as JSON anyways. It has the added benefit of removing the need for analogue/persist for good (because you can modify the map state and save it into a separate save file with little-to-no effort).

That way, we can create either an in-engine way of handling save games, or someone can make an efficient, and easy to use save system for your games (person entities, maps, etc. are stored as POJO). I say in-engine since many new programmers struggle with saving a game and if we had a small API that's also very powerful, it could aid in bringing people to use minisphere.
Title: Re: minisphere 1.0.10
Post by: Fat Cerberus on April 18, 2015, 05:50:10 pm
While it's a neat idea, I think it's outside the scope of minisphere 1.x.  I might consider it for 2.0, however. :)

Also: you don't need SetTileName for GetTileName to work, can't you set tile names in the editor?  I'll implement it anyway though, it'll literally take about 30 seconds.
Title: Re: minisphere 1.0.10
Post by: Flying Jester on April 18, 2015, 05:53:45 pm

Actually, if you want to reduce bloat, then it'd be nice to make a method where you get a POJO (plain old javascript object) of the map and it's tileset. You can then modify said POJO, re-update the map, and see the changes.

We can create Sphere 1.5 complacent wrappers around that POJO. This will ad 2 new calls to the map engine and literally remove anywhere between 20 and 50 API calls from Sphere.

Going one step further, it'd be neat to store the map POJO as JSON anyways. It has the added benefit of removing the need for analogue/persist for good (because you can modify the map state and save it into a separate save file with little-to-no effort).


This is exactly what my map engine does anyway since it is in script, and I can tell you it really is the way to go. More than half of the code by lines of my map engine is 1.5 functions, and even then I condensed them.
Doing the same for tilesets, spritesets, and persons in particular is a really good idea, too.

Of course, I think the map engine is best done in script anyway...but even so, I suspect just having the 1.5 functions in script at least would go a long way to simplifying the implementation.

This would also encourage the idea of setting up a map object and then running it, instead of weirdly spooling objects, scripts, and persons. I believe this is the ugliest part of the map engine.
Title: Re: minisphere 1.0.10
Post by: Fat Cerberus on April 18, 2015, 07:42:36 pm
I used to hate the Sphere map engine with a passion, but it's odd--reimplementing it from scratch, I've developed a certain fondness for it.  It's elegant, in a "diamond in the rough" kind of way.

I think my only real issue with the way the map engine is set up, is the unnecessary dichotomy between "map engine running" and "outside the map engine" caused by the fact that MapEngine() runs its own update loop.  Every other issue (API, etc.) is merely cosmetic in my eyes.

Really though, I've begun to see the legacy API as Sphere's biggest strength (we've made it this far with it, after all, haven't we?).  Some of the things it does seem... off to a seasoned JS coder (referencing persons by name, loose coupling between persons and map, etc.) but are nonetheless intuitive to someone who just wants to get a project off the ground quickly.  Certainly more so than the morass of objects necessitated by the Pegasus spec.

That's not to say I view Pegasus as worthless, of course--quite the opposite, it's very much a step in the right direction.  I just don't think we need to write off the legacy API as a second-class citizen--it's quite valuable in its own right.
Title: Re: minisphere 1.0.10
Post by: Flying Jester on April 18, 2015, 08:31:58 pm
Well, I originally wanted to remake the map engine so that the demo would look like this:

Code: (javascript) [Select]
function game(){
    var aegis = new Person("Aegis", false);
    var map = new Map("map.rmp");
    map.addPerson(aegis);
    MapEngine(map, 60);
}


It wouldn't be too hard I think to allow this, too, though:

Code: (javascript) [Select]
function game(){
    /* Rather than `MapEngine(60);' */
    while(RunEngine(60));
}


I still think that style would be better. Being able to call up the list of persons, or just get a person by name, would still be a reasonable thing to do using that style.
It wouldn't even be too difficult to allow passing in a name string optionally instead of a person object.

I agree that the Pegasus spec still needs work. A lot of it overly complex. I also agree that the old API is basically a good design. That's why I've only removed the old old drawing API in TurboSphere. The only major changes I'm really sold on so far is namespacing the API and adding basic OOP to it. Not anywhere near the OOP madness that Pegasus has, just small things, things that should really be properties instead of getters like RawFile.getSize(), and using real constructors.
Title: Re: minisphere 1.0.10
Post by: Radnen on April 18, 2015, 09:17:51 pm
The way I see it, the Sphere 1.5 API is perfect in every step of it's existence, but if you think about it, it doesn't need to be implemented in the engine. Rather, only a few API calls ever need to be exposed and that's the direct interaction with each file type and input/output method. So really you only need like a couple dozen API calls.

1. Maps/People/Spritests/etc. are full JS objects that you can create the Get/Set API from, script side.
2. All objects become normal JS constructors, which you can make the Load*() API calls from.
3. All graphics are ran through a vertex/shape API that you can make the primitives and images API from.
4. All input is handled by global singletons for that game instance, where you can make the input API from (keyboard, mouse, joystick).
5. All files use 1 IO API which you can make all LogFile/RawFile/File API's from.

If you really think about it you only need to expose like 12 to 20 actual, hard coded, necessary API calls to sphere in order to run 90% of the rest of the API. Graphics, persons + maps, IO, input just have to use the few objects exposed to code and that's it.

It'll truly 'unlock' Sphere. It's great because you can then do cool things like:
Code: (javascript) [Select]

// we may have an issue here: how do you attribute people to maps not yet loaded?
function CreatePerson(name, ss, destroy) {
    var p = new Person(name, ss, destroy);
    _current_map.addPerson(p);
    return p;
}

function SetPersonX(name, x) {
    _current_map.people[name].x = x;
}

var p = CreatePerson("fred", "fred.rss", false);
p.items = [];
p.coins = [];

// what a naive implementation of Sphere File Object looks like:
function LoadFile(filename) {
    var p = new File(filename); // basically a raw file, and the only file type ever.
    p.write = function(key, value) { this.writeLine(key + '=' + value); }
    p.read = function(key, default) { // naive method
        var l = this.readLine(); // returns null if EOF
        while (l) {
            var data = l.split('=');
            if (data[0] == key) {
                if (typeof default == 'number') return Number(data[1]);
                if (typeof default == 'string') return data[1];
                if (typeof default == 'boolean') return Boolean(data[1]);
            }
            l = this.readLine();
        }
        return default;
    }
}

// easiest method ever to saving a person
var file = LoadFile("save.txt");
file.write("fred", JSON.stringify(p));
file.close();


TurboSphere is headed this way with it's Sphere 1.* shim. This is really a good idea. Having very few Sphere API calls also increases the fact you get more 'freedom' from the engine. I used to think you could never make a game without Sphere MapEngine... oh how wrong was I. It was just that since it was there, you had access to it and since there was this huge API around it, it made it hard to give the illusion of freedom, but it's there, you had a lot of freedom, but the API never always showed it. Especially when you hit brick walls like enumerating the fields of an image, adding a property to an image, or heck, even getting the dang filename of an image.
Title: Re: minisphere 1.0.10
Post by: Fat Cerberus on April 18, 2015, 09:31:31 pm
Haha, I love that comment on the CreatePerson() function.  From a purely theoretical standpoint, the Persons API doesn't seem to make much sense, does it?  That is, until you actually go to implement it.  Maps and persons in Sphere are actually very loosely coupled, which is big part of what makes the system so flexible.  The tendency I think is to always want to view persons as being associated with a given map, when in fact they NEVER are, the map engine just happens to conveniently destroy some of them for you when switching maps.
Title: Re: minisphere 1.0.10
Post by: Radnen on April 18, 2015, 09:55:11 pm

Haha, I love that comment on the CreatePerson() function.  From a purely theoretical standpoint, the Persons API doesn't seem to make much sense, does it?  That is, until you actually go to implement it.  Maps and persons in Sphere are actually very loosely coupled, which is big part of what makes the system so flexible.  The tendency I think is to always want to view persons as being associated with a given map, when in fact they NEVER are, the map engine just happens to conveniently destroy some of them for you when switching maps.


That just goes to show just how much was hidden behind the scenes, the person manager, the command queue, the way edge scripts are detected(!), and the camera, and the player input. Bringing these hidden areas to the forefront can increase productivity, these can be safely exposed in an extended API. Older games just wouldn't know to call these extended functions, but newer games can, and take full advantage of them. I'm still impressed to this day FBNil's ability to know how sphere operates behind the scenes to take advantage of person scripts, delay scripts, etc. in his lithonite engine.
Title: Re: minisphere 1.0.10
Post by: Fat Cerberus on April 18, 2015, 10:04:59 pm
That's what made getting the Lithonite demo fully working in minisphere such an awesome moment.  minisphere's map engine implementation was as much reverse engineering and extrapolation as it was directly studying Sphere's code.  Which ultimately was a good thing--I can only take so much of the latter activity before it starts to wear on my sanity.  Read the post at the top of page 22 for just one of the many reasons why that is. :P 

But yeah, I was able to extrapolate a lot of the map engine's inner workings from studying Lithonite's tricks.  It was quite fun, actually. :D
Title: Re: minisphere 1.0.10
Post by: Fat Cerberus on April 19, 2015, 02:22:09 am
Quick warning to anyone using minisphere for production use: Don't try to to pass a function to SetPersonScript, it will crash.  I accidentally passed a Duktape context to the internal set_person_script function instead of a person object, so it ends up overwriting Duktape state and everything goes to hell.  SetPersonScript() with a code string works fine, though, so I won't put out a hotfix for it.  It'll be fixed in 1.1.
Title: Re: minisphere 1.0.10
Post by: casiotone on April 19, 2015, 05:00:25 am
How about a DoesFileExist function? Not sure why it wasn't added with the other file/directory listing functions.
Title: Re: minisphere 1.0.10
Post by: DaVince on April 19, 2015, 08:39:08 am
^ This. I have severely missed this several times while making games.
Title: Re: minisphere 1.0.10
Post by: DaVince on April 19, 2015, 08:42:32 am
Really liking this recent discussion. :)


Yeah, that would be trivial to add.  Is there a valid use case for it though?  I try not to add APIs just for the sake of it, trying to minimize perceived bloat.

I can think of good use cases for SetTileName(). First off, of course there's the fact that once you save a map it'll have this changed tile name data in it. But what about tiles in your game that you want to change the behavior on? For example, tiles with the name "hazard" all behaving like hazards until you tell some tiles they no longer have this name and thus no longer are hazards.

I'm sure there are more not-quite-straight-forward use cases. It's nice that this has been implemented now, anyway.
Title: Re: minisphere 1.0.10
Post by: Fat Cerberus on April 19, 2015, 09:10:04 am

How about a DoesFileExist function? Not sure why it wasn't added with the other file/directory listing functions.


Already done.  In fact it should be in 1.0.10 already.  I ended up adding it after looking through the commit log on the old sourceforge CVS repo (when I was trying to get the 1.5 source to fix that animation bug) and seeing it.  I think it might not have actually been exposed to script though?  Anyway, yeah, minisphere has DoesFileExist() already. :)
Title: Re: minisphere 1.0.10
Post by: Fat Cerberus on April 19, 2015, 01:30:10 pm
Just added "proper object constructors" to the to-do list for 1.1.  :D
Title: Re: minisphere 1.0.10
Post by: casiotone on April 19, 2015, 02:51:41 pm
Awesome stuff. A way to enable filtering for images would be good.
Title: Re: minisphere 1.0.10
Post by: Fat Cerberus on April 19, 2015, 03:05:13 pm

Awesome stuff. A way to enable filtering for images would be good.

Not sure what you mean by this, you'll need to clarify.
Title: Re: minisphere 1.0.10
Post by: casiotone on April 19, 2015, 04:34:06 pm
https://www.allegro.cc/manual/5/al_set_new_bitmap_flags

ALLEGRO_MIN_LINEAR and ALLEGRO_MAG_LINEAR. It improves image scaling a lot.
Title: Re: minisphere 1.0.10
Post by: Fat Cerberus on April 19, 2015, 04:39:54 pm
Ah, bilinear filtering for scaling.  That'd be easy enough to add an API function or two for.
Title: Re: minisphere 1.0.10
Post by: Fat Cerberus on April 20, 2015, 01:33:14 am
I just started working on adding constructors for Sphere objects.  I posted an issue on GitHub to track the progress of the implementation.
Title: Re: minisphere 1.0.10
Post by: Flying Jester on April 20, 2015, 05:22:09 pm
I thought of two other things that I find useful additions to the API. These are additions I added for use by my map engine, so I have an actual use for them as opposed to SetTileName.

RawFile.read(), with no argument, reads the entire file.
RawFile.readString() works the same as read, but returns a string. This can save on memory usage, when otherwise an ArrayBuffer or ByteArray would have to be garbage collected. Until then, you have at least two entire copies of the read in memory.
Title: Re: minisphere 1.0.10
Post by: Fat Cerberus on April 20, 2015, 05:25:27 pm

I thought of two other things that I find useful additions to the API. These are additions I added for use by my map engine, so I have an actual use for them as opposed to SetTileName.

RawFile.read(), with no argument, reads the entire file.
RawFile.readString() works the same as read, but returns a string. This can save on memory usage, when otherwise an ArrayBuffer or ByteArray would have to be garbage collected. Until then, you have at least two entire copies of the read in memory.


RawFile.readString I probably would have done myself at some point.  I already did that for sockets, in fact.  :D  I like the idea of .read() with no args slurping the whole file, it saves the step of getting the length first.  Thanks!

As for garbage collection, do note that that's not as big an issue in minisphere as Duktape's primary GC method is refcounting.  It only resorts to mark and sweep in case of circular refs.
Title: Re: minisphere 1.0.10
Post by: Fat Cerberus on April 20, 2015, 08:11:10 pm
Let me just say how awesome it is to be able to do this:

Code: [Select]
var red = new Color(255, 0, 0);
Abort(red instanceof Color);  // true!


You have no idea how much and how often I wished to be able to do that in Sphere.  Instead all we got was the clunky toString() methods for type checking.

;D

instanceof works with the old-style methods too!
Title: Re: minisphere 1.0.10
Post by: DaVince on April 21, 2015, 06:02:40 pm
So I noticed a missing effect in the Sir Boingers intro screen: the backgrounds are supposed to fade in and out to and from black, but they're not. They're scrolling and a new background is shown without any transition whatsoever.

The fade effect is performed by overlaying a fullscreen black rectangle that changes its opacity - code at line 465-481 in start.js. For some reason this doesn't seem to render in minisphere (and I made sure to compile the latest version - works full speed even on an old laptop, good work!)
Title: Re: minisphere 1.0.10
Post by: Fat Cerberus on April 21, 2015, 06:06:25 pm
Thanks for the report, I'll look into it. :)
Title: Re: minisphere 1.0.10
Post by: Fat Cerberus on April 22, 2015, 02:33:08 am
Well, this has been a massive undertaking, but definitely worth it.  In minisphere 1.1, all Sphere objects will have proper constructors and, where applicable, actual properties in addition to the old-style get/set methods.  I even took some cues from TurboSphere when implementing a few of the constructors. :D  Amazingly, the engine executable hasn't grown much, if at all.  The 32-bit engine is still 1.5MB and 64-bit 1.75MB.  Pretty awesome.

I'll be honest though, if I had tried to implement things this way from the start, I can guarantee it would have been a failure.  minisphere 1.0 had to be what it was, a drop-in Sphere 1.5 replacement, legacy warts and all.  It gave me something to work towards, the entire existing Sphere catalog.  If I had gone for the modern approach right out of the gate, it wouldn't have been compatible with anything and would have gotten very boring very fast since the only thing I would have had is, at best, a bunch of contrived tests.  But now that I have that compatibility, I can freely build on it to create something great. ;D
Title: Re: minisphere 1.0.10
Post by: Fat Cerberus on April 22, 2015, 02:55:22 am

So I noticed a missing effect in the Sir Boingers intro screen: the backgrounds are supposed to fade in and out to and from black, but they're not. They're scrolling and a new background is shown without any transition whatsoever.

The fade effect is performed by overlaying a fullscreen black rectangle that changes its opacity - code at line 465-481 in start.js. For some reason this doesn't seem to render in minisphere (and I made sure to compile the latest version - works full speed even on an old laptop, good work!)


Apparently the copy of Sir Boingers I have doesn't have this effect?  I have the one from the Downloads repo, and the lines in question look like this:
Code: (javascript) [Select]
      while (AreKeysLeft()) key = GetKey();

      if (key != undefined)
      {
        if (key == KEY_BACKSPACE)
          playername = playername.slice(0, playername.length-1);
        else if (key == KEY_ENTER && !lastpressed && playername != "")
          break;
        else if (playername.length <= 20)
          playername += GetKeyString(key, shift);
      }

      key = "";

      if (IsAnyKeyPressed()) lastpressed = true;
      else lastpressed = false;
      if (IsKeyPressed(KEY_SHIFT)) shift = true;


Input code.  I did a search for all Rectangle() calls in start.js too, they all used a constant color.  No ApplyColorMask() calls either.  This effect must be a recent addition.

That said, drawing a full-screen translucent rectangle should definitely work, short of a regression in the primitives code, which I don't think I've touched in quite a while...
Title: Re: minisphere 1.0.10
Post by: DaVince on April 22, 2015, 06:02:37 am
Oh! I never noticed that Boingers 2.0/2.1 isn't on the repo. I'll post it soon. The game's expanded a fair bit!
Edit: now on the repo and http://boingers.tengudev.com/

Edit: also, lines 459-473. 472 especially. I referenced line numbers from my WIP next version, silly me.
Title: Re: minisphere 1.0.10
Post by: Fat Cerberus on April 22, 2015, 09:47:04 am
Yeah, I see the Rectangle() call.  I added some prints before the primitive call and used a debug build of minisphere (which shows the console window), the alpha values are correct, but the Rectangle apparently isn't being rendered.  Definitely something weird going on here.
Title: Re: minisphere 1.0.10
Post by: Fat Cerberus on April 22, 2015, 11:59:05 am
So I took a closer look at the print() output and figured out the issue: The alpha values on your mask rect are negative.  minisphere clamps colors to [0-255].  Sphere modulo's them, which I chose not to emulate because it screws up color tweening.  You can fix the effect by changing the alpha math to ensure the alpha is always in the range of [0-255].  It's not a bug, it's a feature! ;)

Also, tip: If you put a 32x32 icon.png in the project root, minisphere will use it for the game's taskbar icon. :)
Title: Re: minisphere 1.0.10
Post by: Fat Cerberus on April 22, 2015, 02:03:51 pm
So, um... anyone want to take 1.1 out for a test drive? ;)  I just posted minisphere 1.1b1.
Title: Re: minisphere 1.0.10
Post by: DaVince on April 22, 2015, 02:25:18 pm

So I took a closer look at the print() output and figured out the issue: The alpha values on your mask rect are negative.  minisphere clamps colors to [0-255].  Sphere modulo's them, which I chose not to emulate because it screws up color tweening.  You can fix the effect by changing the alpha math to ensure the alpha is always in the range of [0-255].  It's not a bug, it's a feature! ;)

Yeah, I've sometimes made use of the fact that you can go beyond 255 and the color just loops.
I'm not sure I even realized the number was going into the negative back when I coded that. Maybe I did. Anyway, I'll have to figure it out. Maths is not my strong point. :(

Quote
Also, tip: If you put a 32x32 icon.png in the project root, minisphere will use it for the game's taskbar icon. :)

Will do! For the next version, though, this one was just a bug fix release!
Title: Re: minisphere 1.1b1 (stable: 1.0.10)
Post by: Fat Cerberus on April 22, 2015, 02:48:46 pm
Admittedly it was a clever trick--send the alpha into negative to "reverse polarity" so to speak-- (-1) = 255, (-255) = 0.  Unfortunately it won't work in minisphere. :P. I'll only go so far in the name of compatibility!
Title: Re: minisphere 1.1b1 (stable: 1.0.10)
Post by: Fat Cerberus on April 22, 2015, 10:36:33 pm
@DaVince: Let me just say I love the snarky remarks Boingers 2.0 gives when you die.  The new levels were too hard for me, so I started playing the "old" level set - my favorite had to be 6 levels and about 20 deaths in, it told me "Well done" when I died and I cracked up. ;D  The game seems very stable on 1.1b1, no crashes, errors or anything.

Oh, by the way:
Code: (javascript) [Select]
if (imgtime < 48) mask.alpha = 255-(imgtime/48)*255;
if (imgtime > imgmaxtime-48) mask.alpha = 255-((imgmaxtime-imgtime)/48)*255;


As for minisphere, I've been debating a slight name change to "miniSphere".  You know, seeing as people seem to want to call it that anyway. ;)  Everyone's thoughts?
Title: Re: minisphere 1.1b1 (stable: 1.0.10)
Post by: Radnen on April 22, 2015, 10:54:04 pm
minisphere all lowcase shows it to be a light weight C built app. miniSphere sounds like a method to a JS function, and MiniSphere sounds like a legacy C++ or .NET app. :P
Title: Re: minisphere 1.1b1 (stable: 1.0.10)
Post by: Flying Jester on April 23, 2015, 12:15:46 am
miniSphere looks weird to me...

mini.js would be catchy, even if it didn't reflect the Sphere lineage.
Title: Re: minisphere 1.1b1 (stable: 1.0.10)
Post by: Fat Cerberus on April 23, 2015, 12:42:03 am

miniSphere looks weird to me...

mini.js would be catchy, even if it didn't reflect the Sphere lineage.


Nah, too much JS-related stuff uses the .js nomenclature (Node.js immediately comes to mind), it's a dumb fad as far as I'm considered.  It would be like me calling minisphere 'minisphere.c'.  Admittedly that works better if it were actually all in one .c file (I used to do that way back in the day too :P), but...

But yeah, miniSphere does seem odd.  I'll keep the name as minisphere.
Title: Re: minisphere 1.1b1 (stable: 1.0.10)
Post by: Flying Jester on April 23, 2015, 02:03:20 am
I got the idea from node.js...

But I agree. Node.js has a really dumb name, I think. I expect it to be written in JS with a name like that! It's like how when something is cname, I expect it to be written in C, like cpython.
Title: Re: minisphere 1.1b1 (stable: 1.0.10)
Post by: Fat Cerberus on April 23, 2015, 02:20:09 am
So I've been thinking about the config tool I'm planning to add in 1.1, and it strikes me that almost no existing Sphere game actually uses the key mappings set using it (i.e. the GetPlayerKey() function).  Thinking about why that would be, it strikes me that the likely reason is this: Sphere's config tool is, quite frankly, an atrocity.  You have the engine for normal gameplay, but if you want to change keys, plugins, etc., you have to close the engine, run config, and then run the game again.

This whole state of affairs is a shame, as one of the many great things about Sphere is how much tedium it offers to handle for you without getting in your way if you want to do things differently.  So me, not one to let a useful engine convenience go to waste, I came up with the following idea: An in-engine configuration screen.  I could even make it a little pulldown strip at the top of the screen so you can change settings without interrupting gameplay.  I could even allow per-game config this way!
Title: Re: minisphere 1.1b1 (stable: 1.0.10)
Post by: Radnen on April 23, 2015, 02:38:39 am

This whole state of affairs is a shame, as one of the many great things about Sphere is how much tedium it offers to handle for you without getting in your way if you want to do things differently.  So me, not one to let a useful engine convenience go to waste, I came up with the following idea: An in-engine configuration screen.  I could even make it a little pulldown strip at the top of the screen so you can change settings without interrupting gameplay.  I could even allow per-game config this way!


I agree. +1
Title: Re: minisphere 1.1b1 (stable: 1.0.10)
Post by: DaVince on April 23, 2015, 06:50:16 am
Always so much new stuff every day I check the thread. :)


@DaVince: Let me just say I love the snarky remarks Boingers 2.0 gives when you die.  The new levels were too hard for me, so I started playing the "old" level set - my favorite had to be 6 levels and about 20 deaths in, it told me "Well done" when I died and I cracked up. ;D  The game seems very stable on 1.1b1, no crashes, errors or anything.

Oh, by the way:
Code: (javascript) [Select]
if (imgtime < 48) mask.alpha = 255-(imgtime/48)*255;
if (imgtime > imgmaxtime-48) mask.alpha = 255-((imgmaxtime-imgtime)/48)*255;


Thanks! And ha, yeah, that's exactly what I did. Thanks though! :)

Quote
So I've been thinking about the config tool I'm planning to add in 1.1, and it strikes me that almost no existing Sphere game actually uses the key mappings set using it (i.e. the GetPlayerKey() function).  Thinking about why that would be, it strikes me that the likely reason is this: Sphere's config tool is, quite frankly, an atrocity.  You have the engine for normal gameplay, but if you want to change keys, plugins, etc., you have to close the engine, run config, and then run the game again.

This whole state of affairs is a shame, as one of the many great things about Sphere is how much tedium it offers to handle for you without getting in your way if you want to do things differently.  So me, not one to let a useful engine convenience go to waste, I came up with the following idea: An in-engine configuration screen.  I could even make it a little pulldown strip at the top of the screen so you can change settings without interrupting gameplay.  I could even allow per-game config this way!

Yes please! And it'd be even nicer if you exposed some of the config settings through the API too, like the key bindings.

Also, input is kind of a complex beast. I was writing a long post asking for more full keymapping support that is analogous to modern gamepads, but thinking about it, this would NEED to come with a way to save the configuration in the game folder itself (and include it as a config in game.sgm or a config.ini in the same folder or something). Because some games have mappings where WASD moves you and the arrow keys do other stuff (or you need to use the mouse) while others would use the arrow keys.

It's probably a good idea to have the global config file which saves things like window scale and filter, and the game-specific section saves stuff relevant for only this game (like the input). I also think you can drop/not implement some stuff like disabling sound, because honestly, OSes just support disabling sound on individual apps now.

Oh! And sometimes you could expect different behavior from the keyboard and mouse compared to gamepads. You will want to stick with the raw keyboard input then. Sir Boingers is set up so that it both accepts the joystick API and keyboard input, but the keyboard input is all done with Sphere's keyboard-related functions because the game simply behaves differently when played with a keyboard. For example, on a keyboard, "up" makes you float, while with a controller it uses other buttons because that's easier.
However, I consider this a "don't worry about it" case as I've set up the game to check both the keyboard and gamepad anyway, and so should anyone else with controls that aren't the same on different controllers. They're more specialized cases.
Title: Re: minisphere 1.1b1 (stable: 1.0.10)
Post by: Fat Cerberus on April 23, 2015, 10:14:54 am

Yes please! And it'd be even nicer if you exposed some of the config settings through the API too, like the key bindings.

They kind of are though?  That's what GetPlayerKey() is, but nobody uses it because the current config.exe is clunky (and huge--take a look at a Sphere 1.5 distro some time--config.exe is literally the biggest thing there, even bigger than the editor! :o).  Unless you mean an API to set the mappings, in which case... eh.  I think at the point your game wants to do that, it means you're already exposing your own configuration UI anyway, so might as well go all the way and manage the settings yourself.  Let's not invite scope creep here. :)

Quote

Also, input is kind of a complex beast. I was writing a long post asking for more full keymapping support that is analogous to modern gamepads, but thinking about it, this would NEED to come with a way to save the configuration in the game folder itself (and include it as a config in game.sgm or a config.ini in the same folder or something). Because some games have mappings where WASD moves you and the arrow keys do other stuff (or you need to use the mouse) while others would use the arrow keys.


The current config GetPlayerKey() mappings are already based on a gamepad (an SNES pad, to be specific: a single D-pad with four face buttons and a Start button--Select is MIA for some reason), so it would be easy enough to expand the mappings.  The thing is though, again, Sphere's design is set up primarily for making retro games, so the conveniences provided by the engine reflect that.  Anything more advanced, in my opinion, should be done in script.  This kind of thing is why the File API exists (referring to the .ini-style File object, not RawFiles), after all.

Quote

It's probably a good idea to have the global config file which saves things like window scale and filter, and the game-specific section saves stuff relevant for only this game (like the input). I also think you can drop/not implement some stuff like disabling sound, because honestly, OSes just support disabling sound on individual apps now.

Oh! And sometimes you could expect different behavior from the keyboard and mouse compared to gamepads. You will want to stick with the raw keyboard input then. Sir Boingers is set up so that it both accepts the joystick API and keyboard input, but the keyboard input is all done with Sphere's keyboard-related functions because the game simply behaves differently when played with a keyboard. For example, on a keyboard, "up" makes you float, while with a controller it uses other buttons because that's easier.
However, I consider this a "don't worry about it" case as I've set up the game to check both the keyboard and gamepad anyway, and so should anyone else with controls that aren't the same on different controllers. They're more specialized cases.


I actually don't like the window scaling being global.  It's one of my biggest peeves with Sphere 1.5--I generally keep 2x scale on because the majority of Sphere games are 320x240, but if I happen to come across one that uses 640x480 (or higher--T&E is 800x600!), the window is bigger than the screen and then I have to reconfigure it, which shrinks all my 320x240 games in the process.

Oh, and speaking of Sir Boingers, I'm actually not a big fan on the new control setup in v2.  The 2010 version's setup was better, I think (Ctrl to bounce).  A big issue with the new controls I've had is that, when bouncing and trying to move left and float at the time, the Up input gets ignored because of simultaneous-key limitations on cheaper keyboards (the keyboard on my Core i3 2-in-1 laptop, for example).  This makes a few areas almost impossible and cost me a good number of avoidable deaths.  I think this is why old console emulators used to use Ctrl and Alt for the face buttons, actually, since modifier keys don't contribute to the 3-key limit.
Title: Re: minisphere 1.1b1 (stable: 1.0.10)
Post by: mezzoEmrys on April 23, 2015, 10:22:42 am
From what I'd expect, all to almost all of the configuration options should be in a built in menu bar of some kind, like when using Visual Boy Advance, so you can change all those options on the fly. It makes a lot more sense to me, but I'm not sure how feasible it would be to change which graphics and audio plugins you're using on the fly.
Title: Re: minisphere 1.1b1 (stable: 1.0.10)
Post by: Fat Cerberus on April 23, 2015, 10:24:44 am

From what I'd expect, all to almost all of the configuration options should be in a built in menu bar of some kind, like when using Visual Boy Advance, so you can change all those options on the fly. It makes a lot more sense to me, but I'm not sure how feasible it would be to change which graphics and audio plugins you're using on the fly.


Yeah, that's what I was planning here, ability to change the configuration without stopping the game you're playing.  Plugins aren't an issue as minisphere's backend isn't customizable--it's always Allegro. :)
Title: Re: minisphere 1.1b1 (stable: 1.0.10)
Post by: Fat Cerberus on April 23, 2015, 12:53:10 pm
Well, I decided on a whim that 1.1 doesn't represent a big enough evolution and am now going to implement the Sapphire API from TurboSphere.  After looking at the method signatures and such, it seemed like low-hanging fruit to me. :)

If minisphere 1.1 doesn't end up being the most awesome Sphere implementation ever after this... well, I don't know what to tell you. :D
Title: Re: minisphere 1.1b1 (stable: 1.0.10)
Post by: Flying Jester on April 23, 2015, 12:53:46 pm

From what I'd expect, all to almost all of the configuration options should be in a built in menu bar of some kind, like when using Visual Boy Advance, so you can change all those options on the fly. It makes a lot more sense to me, but I'm not sure how feasible it would be to change which graphics and audio plugins you're using on the fly.


Hmm....HMMMMM!


Well, I decided on a whim that 1.1 doesn't represent a big enough evolution and am now going to implement the Sapphire API from TurboSphere.  After looking at the method signatures and such, it seemed like low-hanging fruit to me. :)

If minisphere 1.1 doesn't end up being the most awesome Sphere implementation ever after this... well, I don't know what to tell you. :D


I wonder if my map engine would run in minisphere then.
Title: Re: minisphere 1.1b1 (stable: 1.0.10)
Post by: Fat Cerberus on April 23, 2015, 01:17:19 pm


From what I'd expect, all to almost all of the configuration options should be in a built in menu bar of some kind, like when using Visual Boy Advance, so you can change all those options on the fly. It makes a lot more sense to me, but I'm not sure how feasible it would be to change which graphics and audio plugins you're using on the fly.


Hmm....HMMMMM!


Yeah yeah, plugin support, I can take a hint. ::)  I'll get there eventually... maybe.  Honestly it's just not that important to me and adds complexity that's just not needed for most use cases.  Maybe I'll do it when I run out of features to steal from other engines. ;)

As for Sapphire, I just need some clarification: Can a shape be created with a Surface as texture, or does it have to be an Image?  With the way the engine is set up right now I could both (surfaces and images are the same under the hood), but I'm trying to be compliant here.
Title: Re: minisphere 1.1b1 (stable: 1.0.10)
Post by: Flying Jester on April 23, 2015, 01:44:13 pm
In TurboSphere, a Shape must be constructed using an Image.

I wasn't bugging you for plugins...I was just thinking...
TurboSphere could actually unload and load plugins on the fly, but the only issue with that would be that any objects constructed using a plugin that is then unloaded couldn't be used anymore, and when they are finalized bad things would happen...but it's an interesting idea.
Title: Re: minisphere 1.1b1 (stable: 1.0.10)
Post by: Fat Cerberus on April 23, 2015, 01:56:37 pm
I'm assuming UV is normalized [0-1], but what of coordinates?  Are X/Y resolution-dependent or are they normalized too?  And where is the origin (0,0) relative to the screen?

I'm probably going to change a few names here and there in any case (Shape:image->Shape:texture among others), so it won't be a fully compatible implementation, but the general API structure should be identical.
Title: Re: minisphere 1.1b1 (stable: 1.0.10)
Post by: DaVince on April 23, 2015, 03:55:06 pm
Quote
Unless you mean an API to set the mappings, in which case... eh.  I think at the point your game wants to do that, it means you're already exposing your own configuration UI anyway, so might as well go all the way and manage the settings yourself.  Let's not invite scope creep here. :)

That's what I meant, though. Setting options. But yeah, if you're going to have a menu bar it's not going to be needed. :)

Quote
Oh, and speaking of Sir Boingers, I'm actually not a big fan on the new control setup in v2.  The 2010 version's setup was better, I think (Ctrl to bounce).  A big issue with the new controls I've had is that, when bouncing and trying to move left and float at the time, the Up input gets ignored because of simultaneous-key limitations on cheaper keyboards (the keyboard on my Core i3 2-in-1 laptop, for example).  This makes a few areas almost impossible and cost me a good number of avoidable deaths.  I think this is why old console emulators used to use Ctrl and Alt for the face buttons, actually, since modifier keys don't contribute to the 3-key limit.

It's set up so you can use the Z key too. In the end I moved away from ctrl because it felt less natural for modern games, but I can bring it back easily enough.
Title: Re: minisphere 1.1b1 (stable: 1.0.10)
Post by: Fat Cerberus on April 23, 2015, 04:03:34 pm
You can now do this in the latest build of minisphere:

Code: (javascript) [Select]
var image = new Image('texture.png');
var shape = new Shape([
{ x: 0, y: 0, u: 0.0, v: 0.0 },
{ x: 10, y: 0, u: 1.0, v: 0.0 },
{ x: 10, y: 10, u: 1.0, v: 1.0 },
{ x: 0, y: 10, u: 0.0, v: 1.0 }
], image);
var group = new Group([ shape ], GetDefaultShaderProgram());

// vvv this requires access to the Specs Threader, though...
Threads.doWith(group, function() { return true; }, function() { this.draw(); });


Gangnam TurboSphere style!  It draws a little 10x10 textured square at the top left of the screen. ;D

I feel like I should change the order of the arguments for the Shape and Group constructors though... it feels clunky tacking the image/shader onto the end of the array literal like that, it would be more natural as the first argument I think.
Title: Re: minisphere 1.1b1 (stable: 1.0.10)
Post by: Flying Jester on April 23, 2015, 05:03:19 pm
The default shader returned from GetDefaultShaderProgram must guarantee raster coords and have the origin in the upper left, just like how Sphere does it.

UV is normalized, but giving a number greater than 1 causes tiling just like how OpenGL and (or so I've heard) DirectX do it. UV is also automatically assigned to the order you gave if it is not present in the vertices. Triangles use the same coords, but just the first three. Same with lines and points.

I don't think it would be more natural with the Image/Shader first...for the primitives in Sphere, coords and parameters come first, colors and attributes come last. That's why I set it up this way, anyway.

I'll be curious to see how you tackle drawing text using Galileo/Sapphire. That's kind of a thorny spot so far. It works, but I think it could be handled better.
Title: Re: minisphere 1.1b1 (stable: 1.0.10)
Post by: Fat Cerberus on April 23, 2015, 05:10:40 pm

The default shader returned from GetDefaultShaderProgram must guarantee raster coords and have the origin in the upper left, just like how Sphere does it.

UV is normalized, but giving a number greater than 1 causes tiling just like how OpenGL and (or so I've heard) DirectX do it. UV is also automatically assigned to the order you gave if it is not present in the vertices. Triangles use the same coords, but just the first three. Same with lines and points.

I don't think it would be more natural with the Image/Shader first...for the primitives in Sphere, coords and parameters come first, colors and attributes come last. That's why I set it up this way, anyway.


When I said more natural, I meant the syntax.  If a function is likely to be called with a multi-line array or object literal as argument, as here, it's awkward to have to add arguments after the literal.  See the code sample above, especially the Shape initialization, for what I mean.

I'm curious about the automatic UV assignment... how does that work?  Right now UV defaults to zero for all vertices in my implementation, which is pretty useless.  Maybe I should take a closer look at the TS source...

As for that shader, that's a vertex shader, right?  I wasn't entirely clear on whether it was that or a fragment/pixel shader.
Title: Re: minisphere 1.1b1 (stable: 1.0.10)
Post by: Flying Jester on April 23, 2015, 05:46:07 pm

I'm curious about the automatic UV assignment... how does that work?  Right now UV defaults to zero for all vertices in my implementation, which is pretty useless.  Maybe I should take a closer look at the TS source...


If you are curious:
https://github.com/FlyingJester/TurboSphere/blob/master/src/plugins/Sapphire/script.cpp#L608-L679 (https://github.com/FlyingJester/TurboSphere/blob/master/src/plugins/Sapphire/script.cpp#L608-L679)
I check the number of vertices against a lookup table with default UV numbers. As I iterate the vertices, I check if they have U, V, and Color properties, and override the defaults if they do.

That way, to blit an image you don't need explicit U and V, you just need the corner locations. This is pretty convenient, I find. It also allows overriding the color mask, but defaulting to full masking.



As for that shader, that's a vertex shader, right?  I wasn't entirely clear on whether it was that or a fragment/pixel shader.


So, this is what it would look like if TurboSphere had full shader support:

Code: (JavaScript) [Select]


var fragment_shader = new FragmentShader(frag_shader_source_string);
var vertex_shader = new VertexShader(vert_shader_source_string);
var shader = new ShaderProgram(fragment_shader, vertex_shader);

/*...*/
var group = new Group(some_shape_array, shader);


There are other things I could do, too. Maybe add the ability to specify GLSL version in the fragment and vertex constructor and inject that into the shader source? That would be nice if I also added a way to query valid GLSL versions. When the ShaderProgram constructor exists, I will add GetDefaultVertexShader and GetDefaultFragmentShader, so that you can use only a single part of the defaults. Then you'd really need to know the GLSL version.

You need both vertex and fragment shaders in OpenGL 3.2+ and 4. Since that's also valid for 2, that's how I did it. I never got much into shaders for OpenGL 2, maybe it's necessary there to?

Adding Geometry shader passes would also be a very cool extension. I don't really want to get into Compute shaders since that is an aborted feature.

But that's the gist of how I imagine the shader system.
Title: Re: minisphere 1.1b1 (stable: 1.0.10)
Post by: Fat Cerberus on April 23, 2015, 07:56:14 pm
I think Allegro might actually support shaders... I should try experimenting with it. :)

Is Sapphire (I'm assuming Sapphire is the frontend and Galileo the backend...) part of the Pegasus spec by any chance?  It's actually been a while since I've looked at that repo and I don't remember if anything like this was specified in it.
Title: Re: minisphere 1.1b1 (stable: 1.0.10)
Post by: Flying Jester on April 23, 2015, 08:52:58 pm

I think Allegro might actually support shaders... I should try experimenting with it. :)

I wanted shaders to really be optional just because I didn't want the engine to necessarily use OpenGL. GLSL shaders would be an extension to Pegasus.


Is Sapphire (I'm assuming Sapphire is the frontend and Galileo the backend...) part of the Pegasus spec by any chance?  It's actually been a while since I've looked at that repo and I don't remember if anything like this was specified in it.

Sapphire is the name of TurboSphre's implementation (well, the whole TurboSphere graphics plugin). Galileo is the name of the API.

The spec is in the api/ts directory of Pegasus. I just updated a week or so ago, based on what TurboSphere actually implements.
Title: Re: minisphere 1.1b1 (stable: 1.0.10)
Post by: Fat Cerberus on April 23, 2015, 08:59:46 pm
Oh, good to know.  I will rename the extension to "galileo-api" then.  :)
Title: Re: minisphere 1.1b1 (stable: 1.0.10)
Post by: Fat Cerberus on April 23, 2015, 10:57:57 pm
Wow, just took a look at the Galileo spec and it really is a ridiculously simple API.  I imagine it could be deceptively powerful in the right hands, though.

My only real gripe is with the way Vertices are treated.  It specifies a full constructor for what is ultimately just data.  And what's up with Shapes not being able to share a Vertex?  That's just silly. :P
Title: Re: minisphere 1.1b1 (stable: 1.0.10)
Post by: Flying Jester on April 23, 2015, 11:12:34 pm
Shapes are sort of passed by value. In TurboSphere, there isn't even a true vertex constructor, they are just objects. When a Shape is constructed, the data of all the Vertices is copied.

Shapes can 'share' a Vertex, but changes to the Vertex do not affect the Shape.
Title: Re: minisphere 1.1b1 (stable: 1.0.10)
Post by: Fat Cerberus on April 24, 2015, 02:12:39 am
Well, not even 24 hours later, my Galileo implementation is almost finished (sans shaders, of course--that'd be getting a bit too ambitious for 1.1, although Allegro 5.1 *does* have the functionality). :D  It'll be a fully Pegasus compliant implementation and its existence is reported by GetExtensions() as "sphere-galileo".  Allegro 5 truly is awesome.

The only thing I really have left to implement is the automatic U/V assignment and modifiable vertex and shape lists for Shapes and Groups, respectively.  Shouldn't be too much more work.

minisphere 1.1 will be a sight to behold once it's released.  Best of all: You get all this new stuff, and it STILL runs old Sphere games! ;D
Title: Re: minisphere 1.1b1 (stable: 1.0.10)
Post by: Flying Jester on April 24, 2015, 02:30:03 am
That's good. Galileo is meant to be close to how the lower level APIs work in concept, so it's pretty easy to actually implement. Reimplementing it in OpenGL 2.1 only took me a couple hours, most of the work was making it selectable between that and OpenGL 4 and ensuring I had not broken the OpenGL 4 stuff.
Title: Re: minisphere 1.1b1 (stable: 1.0.10)
Post by: Fat Cerberus on April 24, 2015, 10:38:01 am
Just for the hell of it I tried to run TurboSphere's map engine in minisphere, and upon RequireSystemScript'ing turbo/map_engine.js I got this back from Duktape:
Code: [Select]
RangeError: C call stack depth limit


Apparently there's some infinite recursion somewhere and I have no clue why.

Edit Figured it out.  I had minisphere set up to update the RequireScript inclusion tracking info only after executing the script, which is useless in case of mutual inclusion.  Surprising that this bug didn't bite me until now...

Of course, sadly it turns out it doesn't work.  I get a "not callable" error in segment.js line 6.

Hm, interesting.  The issue seems to be that the Turbo object created in each script is localized to that evaluation.  It's not actually being created in the global scope, apparently.  I added an Abort call immediately after the format.js inclusion in segment.js to print out the value of Turbo, and got back 'undefined'.  No idea what's up with that.  If I RequireSystemScript 'turbo/format.js' directly, Turbo is not undefined, so...
Title: Re: minisphere 1.1b1 (stable: 1.0.10)
Post by: Flying Jester on April 24, 2015, 01:15:13 pm
Bear in mind it's possible that TurboSphere's map engine has some stuff in it that doesn't work on a language level in Sphere 1.5 or similar.

There is one other issue to running the map engine. I escape "#~" in paths to be the system directory. I had intended to just put the format JSON files into a local directory to use the map engine with other engines.
Title: Re: minisphere 1.1b1 (stable: 1.0.10)
Post by: Fat Cerberus on April 24, 2015, 05:36:44 pm
It looks like the biggest obstacle to minisphere being able to use the Turbo runtime right now is Duktape's lack of ArrayBuffers.  He's working on it right now (milestone of 1.3.0 listed on the relevant GitHub issue), but it seems to be slow going.
Title: Re: minisphere 1.1b1 (stable: 1.0.10)
Post by: Flying Jester on April 24, 2015, 06:08:24 pm
Can you see where it properly needs one? I tried to allow it to use ByteArrays as well (or any object that has a `[]' operator). I may have left in a couple evil engine calls, though, like making surfaces directly out of ArrayBuffers.
Title: Re: minisphere 1.1b1 (stable: 1.0.10)
Post by: Fat Cerberus on April 24, 2015, 06:47:51 pm

Can you see where it properly needs one? I tried to allow it to use ByteArrays as well (or any object that has a `[]' operator). I may have left in a couple evil engine calls, though, like making surfaces directly out of ArrayBuffers.


I haven't looked particularly hard, but I did find this:
Code: (javascript) [Select]
Turbo.LoadSystemScheme = function(name){

    var scheme_file = new RawFile("#~/formats/"+name);
    var scheme_buffer = scheme_file.read(scheme_file.size);
   
    var scheme_byteview = new Uint8Array(scheme_buffer);
    var scheme_bytearray = ByteArrayFromTypedArray(scheme_byteview);

    return JSON.parse(CreateStringFromByteArray(scheme_bytearray));
}


Which is the most schizophrenic piece of code I've ever seen. :P  You go from a ByteArray (returned by RawFile:read) to a Uint8Array, back to a ByteArray again, and finally to a string before parsing it as JSON.  Were you just stress-testing the ByteArray stuff on purpose or what?

Also, bytearray.js RequireSystemScript's arraybuffer_bytearray.js without checking to see if a native ByteArray already exists.
Title: Re: minisphere 1.1b1 (stable: 1.0.10)
Post by: Flying Jester on April 24, 2015, 07:20:06 pm

Which is the most schizophrenic piece of code I've ever seen. :P  You go from a ByteArray (returned by RawFile:read) to a Uint8Array, back to a ByteArray again, and finally to a string before parsing it as JSON.  Were you just stress-testing the ByteArray stuff on purpose or what?


It's an extremely cheap operation to convert between ByteArrays and TypedArrays in TurboSphere. It just sets a couple properties of the TypedArray to be compatible methods for a ByteArray.

Previously, read() always returned an ArrayBuffer, and ByteArrayFromTypedArray has wavered between only handling TypedArrays and ArrayBuffers. Now it's able to handle either.
So you're completely right, that code is just too much, making up for issues that don't even exist anymore.

Edit:
Ah, I see. The whole file reader system needs a file reader for ByteArrays.
Title: Re: minisphere 1.1b1 (stable: 1.0.10)
Post by: Fat Cerberus on April 25, 2015, 10:39:47 am
Last night I did a massive reorganization of the minisphere directory.  It's now set up like a real cross-platform C app instead of the MSVC-generated structure it had before.  Source and headers are in 'src', the MSVC project files are in 'msvc', and the engine is built in 'bin'.  A small thing, but at least now it doesn't look like cross-platform support is an afterthought. ;)

@DaVince and @casiotone: Could you guys check that it still builds on Linux and OS X using SCons?  I updated the build scripts to reflect the new structure but as SCons won't build it for me on Windows, I can't test that everything is working properly.
Title: Re: minisphere 1.1b1 (stable: 1.0.10)
Post by: DaVince on April 25, 2015, 12:12:26 pm
Yep, still builds here. I encounter a segfault when dying in Sir Boingers though.
Code: [Select]
fish: Job 1, "./msphere ~/Dropbox/projects/sphere/boingers2.2/startup/" terminated by signal SIGSEGV (Address boundary error)

(I use fish instead of bash so the segfault message looks a bit different.)
Title: Re: minisphere 1.1b1 (stable: 1.0.10)
Post by: Fat Cerberus on April 25, 2015, 12:22:56 pm
Is the segfault reproducible?  I know I encountered a few myself with recent builds, but they were always in the Vorbis code so I didn't know what to do about it.
Title: Re: minisphere 1.1b1 (stable: 1.0.10)
Post by: DaVince on April 25, 2015, 12:34:42 pm
Happens every time I kill myself.

I think it chokes on the dying screen, as my new version uses the original IT files now and this is one that should play only once. I can hear about 0.2 seconds of the music before it segfaults.
Curiously, the win screen does function, even though it also calls a non-looping IT file... (It loops anyway which isn't right though.)

I'll send you the version I'm messing around with.
Title: Re: minisphere 1.1b1 (stable: 1.0.10)
Post by: DaVince on April 25, 2015, 12:42:32 pm
I also have a request: could you make minisphere check if there's only one game in the games folder and just run it if that's the case? I don't want to put my game into a startup folder because that makes it more of a hassle to package the game without the engine.
Title: Re: minisphere 1.1b1 (stable: 1.0.10)
Post by: Fat Cerberus on April 25, 2015, 12:50:01 pm
Yeah, the looping thing is a bug in Allegro that's fixed in the latest build but hasn't been released yet.  There's nothing I can do on minisphere's end to work around it, unfortunately.  It does work properly on Windows because I compiled Allegro myself and included the appropriate fix. :). I actually had no choice, because there are no pre-built x64 MSVC binaries for Allegro, or at least I haven't found any...
Title: Re: minisphere 1.1b1 (stable: 1.0.10)
Post by: DaVince on April 25, 2015, 12:52:20 pm
Yeah, I noticed it works fine on Wine. Will wait for the next Allegro version then.

I also noticed that in Windows the file selector defaults to My Documents instead of the working directory. Might want to make the default path either minisphere's directory, or the games subdirectory (when found). :)
Title: Re: minisphere 1.1b1 (stable: 1.0.10)
Post by: Fat Cerberus on April 25, 2015, 12:58:55 pm

Yeah, I noticed it works fine on Wine. Will wait for the next Allegro version then. :)


Now that you mention it, I remember that there was another bug that was fixed along with the looping: a buffer overrun in the module streaming code. So that's probably where your segfault is. :)

...and in case there was any doubt, I'm the one that discovered it. ;)
Title: Re: minisphere 1.1b1 (stable: 1.0.10)
Post by: DaVince on April 25, 2015, 01:26:07 pm
Yep, I remember when it all transpired. Just thought that the included version of Allegro was your fixed version, so I thought "hm, maybe it's not fixed after all". Until you clarified that just now.
Title: Re: minisphere 1.1b1 (stable: 1.0.10)
Post by: Fat Cerberus on April 27, 2015, 12:27:37 am
I've decided what I want to do for the configuration editor.  The config tool will be written in JS and run by minisphere as any other Sphere game.  config.exe will be a tiny stub that simply defers to the engine and points it at the location of the config "game" game.sgm.

Unfortunately this does mean that key mappings won't be able to be changed while in-game, but after a short-lived experiment trying to implement a graphical config on the native side (the only way to implement such a thing without interrupting the currently running game), I gave up.  C--or any purely procedural langauge, really--just isn't suited for writing a GUI.  It'd much less painful in an OO language like JavaScript.  Besides, as with Sphere's old config.exe, it's really just meant to be a convenience; the preferred option will always be to implement your own config in-game to ensure UI consistency and whatnot.

On a sidenote, my other attempt at a config tool was in C++ using wxWidgets for a Sphere 1.5-style tool, but 1) wxWidgets is horrendously bloated (it took me 10-15 minutes to compile all the libraries on a 5th-gen Core i3--note that this is a CPU that can run the Dolphin emulator!) and 2) It very quickly reminded me why I hate C++.  So yeah, that was a failure too.
Title: Re: minisphere 1.1b1 (stable: 1.0.10)
Post by: Radnen on April 27, 2015, 12:40:39 am
So it has become like the startup game, but also like a library that you can add to your game. Neat!
Title: Re: minisphere 1.1b1 (stable: 1.0.10)
Post by: Flying Jester on April 27, 2015, 12:41:02 am
Just my opinion, having had a long time to wonder about what GUI toolkits to use...

You should take a look at fltk. It is kind of intended for what you describe. It's extremely lightweight, and it makes only a very select usage of C++'s features. It is also extremely cross platform, and still provides easy integration with platform tools.

For instance, you could easily use Fl_x.h's stuff to create a new parent window given a Win32, X11, or Cocoa window handle to have as a child. I was considering using that to frame the window SDL2 creates for TurboSphere, so that I could have an SDL2 OpenGL window embedded in an fltk window that has a menu bar for this kind of thing. You could also automatically use the OS X menu bar instead of a separate one by using Fl_Sys_Menu_Bar.

I despise Qt and WxWidgets because they are ridiculously large and solve simple problems in the most complex way imaginable. I don't like GTK because its maintainers have no commitment to backwards compatibility at all. I rather like fltk because it doesn't have any of these issues. It can look a little dated with the default scheme, but that's really the least of what matters to me. The theme is very usable and simple.
Title: Re: minisphere 1.1b1 (stable: 1.0.10)
Post by: Fat Cerberus on April 27, 2015, 01:21:04 am
I do like the GTK+ theme, if I have to use non-native widgets that's the one I'd prefer by far.  But GTK is pretty bloated itself.  The redistributable last I remember was about 20MB and there's no way to static link to it.  No way I'm carrying around that kind of baggage for a config tool that half of Sphere users aren't even going to touch.  I did take a look at fltk, and while I think most of those screenshots are pretty fugly, it does look very lightweight and simple to use.

But I really think the startup-game-style JS config is the way to go here.  This probably sounds odd given my dedication to doing everything in native, but at the end of the day I don't consider this core functionality; it's just a nice extra.  This way if a game doesn't need it--say, because it implements its own configuration menus--config.exe and the config folder can be left out of the distro.  It's a different situation than, say, the map engine, where at least 3/4 of all Sphere games utilize its functionality in some way and so it's beneficial to have it built into the engine. (And I wouldn't have wanted to have to debug that thing in JS anyway--the MSVC debugger was invaluable during its development).
Title: Re: minisphere 1.1b1 (stable: 1.0.10)
Post by: Flying Jester on April 27, 2015, 01:24:42 am

And I wouldn't have wanted to have to debug that thing in JS anyway--the MSVC debugger was invaluable during its development


Fortunately, both SpiderMonkey and V8 can be run so that gdb or lldb can view JS stack frames as though they were native frames :)
Or at least V8 used to be able to. When I was on my way out of the V8 world, it had been broken for some time and there were murmurs of that being removed.

But I found that one major advantage of the map engine in script was simply that it is easier to write something purely behavioural like that in JS. It needs much less debugging because it has fewer bugs in JS.
Title: Re: minisphere 1.1b1 (stable: 1.0.10)
Post by: Radnen on April 27, 2015, 01:52:07 am

But I found that one major advantage of the map engine in script was simply that it is easier to write something purely behavioural like that in JS. It needs much less debugging because it has fewer bugs in JS.


It's also easily adaptable by the community. ;)
Title: Re: minisphere 1.1b1 (stable: 1.0.10)
Post by: Fat Cerberus on April 27, 2015, 01:57:34 am


But I found that one major advantage of the map engine in script was simply that it is easier to write something purely behavioural like that in JS. It needs much less debugging because it has fewer bugs in JS.


It's also easily adaptable by the community. ;)


That's true, but also remember that, as discussed in this very thread, due to subtle, easy-to-take-for-granted design choices (such as that infamous edge script triggering double-snafu I hit) it's already pretty extensible as-is.  Your Blockman game is proof of that. :D  And Lithonite...
Title: Re: minisphere 1.1b1 (stable: 1.0.10)
Post by: Radnen on April 27, 2015, 02:59:26 am

That's true, but also remember that, as discussed in this very thread, due to subtle, easy-to-take-for-granted design choices (such as that infamous edge script triggering double-snafu I hit) it's already pretty extensible as-is.  Your Blockman game is proof of that. :D  And Lithonite...


Well that's because of SetUpdateScript and SetRenderScript. Basically it let's you "have at it", that coupled with the copious number of getters and setter available to you, there's little that can stand in your way. That said it's still not 100% flexible and even Lithonite would have been easier to code / maintain if it knew to hook into certain areas of the engine easier. There's a lot of hack code too, as a result of Sphere's map API. But it is rather open.

I mean, most maps are indeed very simple structures. You have tiles, layers, entities, zones & triggers. Some objects have obstruction, some tiles have animations, some layers move or parallax. It really covers everything.

That said there currently is no way to exclusively draw a map wherever you want. It'd be nice to treat maps like a standalone object, such that you can muck with it's properties after loading, and draw portions of you choice of the map, wherever, whenever. That's quite hard in Sphere since you are limited to one map per screen. There are double camera tricks, but it can only happen on the same map... unless you write your own map loading call.

I want an engine where I can load up and string maps end to end, with some dynamic calls. Allocate some maps, and deallocate those of which that are out of screen, and then reload them when you are near again. I used this tactic in other game engines to create 'infinite' maps. Maps without borders, but are loaded by stringing maps end-to-end dynamically. The performance benefit is obvious here since you aren't loading a 999x999 sized map all at once.
Title: Re: minisphere 1.1b1 (stable: 1.0.10)
Post by: DaVince on April 27, 2015, 05:57:18 am
If the config tool is contained within a single script, game devs could opt to run it within the game itself too, like

Code: (javascript) [Select]
RequireScript("sphere-config.js");
SphereConfigMenu();


And even customize it to their own likings if they really wanted. :)
Title: Re: minisphere 1.1b1 (stable: 1.0.10)
Post by: Fat Cerberus on April 27, 2015, 09:28:00 am

If the config tool is contained within a single script, game devs could opt to run it within the game itself too, like

Code: (javascript) [Select]
RequireScript("sphere-config.js");
SphereConfigMenu();


And even customize it to their own likings if they really wanted. :)


That's actually a really good idea, I'll have to include the config core as a system script now. :). I was thinking it would look something like the Xrossbar menu on the PS3, with an optional game-specific background taken from the game.sgm root, similar to how icon.png is now.  This way if a dev chooses not to make their own config, the default one won't completely clash with whatever they make.
Title: Re: minisphere 1.1b1 (stable: 1.0.10)
Post by: Fat Cerberus on April 27, 2015, 12:20:08 pm

That said there currently is no way to exclusively draw a map wherever you want. It'd be nice to treat maps like a standalone object, such that you can muck with it's properties after loading, and draw portions of you choice of the map, wherever, whenever. That's quite hard in Sphere since you are limited to one map per screen. There are double camera tricks, but it can only happen on the same map... unless you write your own map loading call.

I want an engine where I can load up and string maps end to end, with some dynamic calls. Allocate some maps, and deallocate those of which that are out of screen, and then reload them when you are near again. I used this tactic in other game engines to create 'infinite' maps. Maps without borders, but are loaded by stringing maps end-to-end dynamically. The performance benefit is obvious here since you aren't loading a 999x999 sized map all at once.


See, if I were writing an engine like Sphere from scratch (i.e. without a base to work from), I almost certainly would have done the map engine in script and included it as a system script (I probably wouldn't have chosen JS though, Lua would have been my first choice I think).  But, knowing what I do now, I'd want a default map engine of some sort built into the engine.  An additional RequireScript() doesn't sound like much to you or me, but let me just say from experience, it's a big deal for someone just learning Sphere.  The first time I used Require/EvaluateScript in a game was something of a rite of passage; it was like I was graduating from "Sphere novice" to "advanced Sphere guy". :P  Don't underestimate the value of being able to do a ton of stuff without importing a single external script--it's empowering and is, in large part, what's made Sphere so approachable over the years.

Moving on: Regarding your ideas, let me just tell you a story.  Everyone thinks they want an object-oriented map engine, but I actually wrote one years ago in C++ and I hated using it.  NPC management was a pain in the ass, and just in general, putting together a working game required a bunch of tedious micromanagement of entity objects.  This wasn't a fault of the map engine itself--it was quite powerful--but simply that encapsulation isn't well suited to managing a map engine with all its various interconnected components.  In minisphere for instance there is very much a circular dependency between the map engine and persons manager that makes it hard to fully componentize.

What it basically comes down to is that OOP relies on the assumption that, as long as someone, somewhere, holds a reference to an object, that object remains valid.  So now, assume for the sake of argument that you do this:
Code: (javascript) [Select]

var townMap = new Map('MarketTown.rmp');
if (/* some condition that triggers this guy being there */) {
  var traveler = new Person("Some Guy", "TravelingSalesman.rss", map);
  // or maybe: townMap.createPerson(...)
}
// some more code and somewhere along the way, a reference to the traveler object is stored
// and persists past map destruction


The problem is, if `townMap` gets unloaded somewhere along the way, `traveler` is implicitly disposed and it's no longer safe to use any references to it.  Even though the object that holds the reference may have no way of knowing that.  This is why I like Sphere's system of decoupling persons from maps and referencing them by name: If all you have is a name, there are no assumptions that the person exists at any given moment, and it's then natural to call DoesPersonExist() first to check.  `person.doesExist()` is more awkward is totally against the OOP philosophy: The fact I have a reference at all and haven't explicitly disposed it should automatically mean it exists.

The alternative, of course, is to make Person objects completely independent from Map objects.  But at that point we're essentially back where we started, just with some fancy constructors tacked on.  And it's *still* not safe for the map engine to automatically destroy them since even in this case, object references are being passed around.

Being able to load and chain together multiple maps via independent objects would be nice, of course, I'm just not sure it's worth all the headaches.
Title: Re: minisphere 1.1b1 (stable: 1.0.10)
Post by: Fat Cerberus on April 27, 2015, 03:37:20 pm
@DaVince: I added some console output to the latest builds, including what you suggested, printing out the error message (and file/line) for uncaught JS exceptions.  It also logs loading and unloading sounds, which I'm not sure whether that's being too verbose or not...

Mainly I'm just afraid that too many printf's will be a performance issue.
Title: Re: minisphere 1.1b1 (stable: 1.0.10)
Post by: Flying Jester on April 27, 2015, 04:42:40 pm

@DaVince: I added some console output to the latest builds, including what you suggested, printing out the error message (and file/line) for uncaught JS exceptions.  It also logs loading and unloading sounds, which I'm not sure whether that's being too verbose or not...

Mainly I'm just afraid that too many printf's will be a performance issue.


It really can be on Windows. The console is silly slow there. Everywhere else, the slow part is the format string parsing.
Title: Re: minisphere 1.1b1 (stable: 1.0.10)
Post by: Radnen on April 27, 2015, 09:18:39 pm
LordEnglish: Hey, all I can say is OOP maps is a solved problem, the way we deal with entities may have to change. That said Sphere's API really does simplify a lot, but it will always be an amateur API in my mind.

That said even if you don't go OOP on maps you can still have a system where you load up a map and draw potions of it on screen, because I know that is a hard problem to solve in Sphere presently.

Code: (javascript) [Select]

// basically you can only call this inside a MapEngine context
// it loads the map, puts it's characters into the same entity batch as the map engine,
// then draws it's tiles and obstructions starting from the specified offset (in this case 640x0)
// functions like DoesPersonExist are still preserved and you still can't make assumptions on the existence of entities.
var map = LoadMap("map.rmp", 640, 0);


The camera is the hardest part to figure out, because now we are giving freedom as to where you put the map. It's easier in fact to tell Sphere to instead, put the map on the edge of another map, moving or removing the edge script and making the camera realize there is in fact more to scroll to.

Code: (javascript) [Select]

// what it looks like using positional constants, which is very much a Sphere-like thing to do:
var map = LoadMap("map.rmp", MAP_EAST);

Title: Re: minisphere 1.1b1 (stable: 1.0.10)
Post by: Fat Cerberus on April 27, 2015, 10:12:22 pm
Now that I think about it some more, splicing maps together like this actually seems like a hack.  It's essentially an optimization to avoid loading the whole map into memory at once, right?  Which makes sense, but wouldn't it be better--and simpler--to solve the problem in the map engine itself (whether in script or native, OO or otherwise), where if you have a huge map, the engine can automatically load and unload pieces of it on demand, just like how, when you have a huge, multi-gigabyte file, opening it in hex editor is instantaneous because it only loads a few KB at a time.

Essentially we'd be letting the map engine "stream" the map, while still allowing you to work on it as one huge world in the editor.
Title: Re: minisphere 1.1b1 (stable: 1.0.10)
Post by: Flying Jester on April 27, 2015, 11:01:54 pm
It's not all that difficult to make a basic OOP map engine that is fairly simple to use. I did it, or at least got the rough outline of it as the core of the TurboSphere map engine. It's all object based, and it works pretty easily.

I did make persons belong strongly to maps. It's not that bad a thing to do, it works fairly well.

You don't need to make a doesExist method. You just need to maintain an array of persons for the map. If the person is not in that array, they aren't on that map.

But I also believe that the map engine does not belong as a native, core part of the engine. It's one thing to include one, but it's not a core function. Chad Austin came to this realization before Sphere 1.0 was even released. He decided it would be better to expose a simple but well thought out scene graph and scene manager rather than a rigid map engine.

Both those components are a part of Pegasus. I disagree with some others on the necessity of the scene manager. I think it's fine for this:

Code: [Select]

function game(){
    while(true){}
}


to hang the engine. If we subscribe to a Mozilla-style view of JavaScript, where it is the C or Assembly of the web or our games, we need to trust it with tasks we trust C with. Even like managing the event loop.
Title: Re: minisphere 1.1b1 (stable: 1.0.10)
Post by: Fat Cerberus on April 27, 2015, 11:44:20 pm

It's not all that difficult to make a basic OOP map engine that is fairly simple to use. I did it, or at least got the rough outline of it as the core of the TurboSphere map engine. It's all object based, and it works pretty easily.

I did make persons belong strongly to maps. It's not that bad a thing to do, it works fairly well.

You don't need to make a doesExist method. You just need to maintain an array of persons for the map. If the person is not in that array, they aren't on that map.

But I also believe that the map engine does not belong as a native, core part of the engine. It's one thing to include one, but it's not a core function. Chad Austin came to this realization before Sphere 1.0 was even released. He decided it would be better to expose a simple but well thought out scene graph and scene manager rather than a rigid map engine.

Both those components are a part of Pegasus. I disagree with some others on the necessity of the scene manager. I think it's fine for this:

Code: [Select]

function game(){
    while(true){}
}


to hang the engine. If we subscribe to a Mozilla-style view of JavaScript, where it is the C or Assembly of the web or our games, we need to trust it with tasks we trust C with. Even like managing the event loop.


Totally agree on that last part.

As for the object-oriented maps, let's consider a scenario:
* As you describe, there is an array of entities that each map exposes.
* Someone takes a reference to an entity from that array, and it gets passed around to a bunch of functions.
* The entity reference is ultimately saved somewhere for later use, despite its volatility.
* The map the entity came from gets unloaded. The entity goes with it.
* The object holding the reference has no idea the entity has disappeared and attempts to call methods on it.
* Game goes kaboom due to unexpected, and therefore uncaught, exception ("entity has been destroyed").

This can of course be dealt with by someone knowledgeable in OOP (don't pass around borrowed references), but let's not fool ourselves into thinking a good deal more vigilance is required.  I myself have made mistakes like what I described above.  This is the kind of thing that's likely to scare off novices, which is something we definitely DON'T want.

I don't know, I'm starting to feel like I have a totally different view of "what Sphere is" compared to everyone else here.  Either that or I'm just better at remembering what it was like to be a novice...  Either way, I'm leaving the Sphere 1.x map engine as part of minisphere.  The entire engine is less than 2MB anyway, so it can hardly be considered bloat.  Ultimately what it comes down to is that I'm a fan of "useful defaults": If someone wants to step outside the box that's fine, but sometimes it helps to know where the box is in the first place. ;)

Maybe some day I'll write a replacement map engine for Sphere in JS.  But I'll be perfectly honest, I haven't yet felt the need to do so.

As for the stage manager: I honestly have no clue what the thing is.  I saw it when I was perusing the Pegasus repo and even read the code, but I still have no idea what it's supposed to do.
Title: Re: minisphere 1.1b1 (stable: 1.0.10)
Post by: Flying Jester on April 28, 2015, 12:01:33 am
I'm not saying that I don't think we should include a default map engine. Just that, for TurboSphere, I want it to be implemented in terms of the engine's API, and not exist as a direct part of that API.



As for the object-oriented maps, let's consider a scenario:
* As you describe, there is an array of entities that each map exposes.
* Someone takes a reference to an entity from that array, and it gets passed around to a bunch of functions.
* The entity reference is ultimately saved somewhere for later use, despite its volatility.
* The map the entity came from gets unloaded. The entity goes with it.
* The object holding the reference has no idea the entity has disappeared and attempts to call methods on it.
* Game goes kaboom due to unexpected, and therefore uncaught, exception ("entity has been destroyed").

This can of course be dealt with by someone knowledgeable in OOP (don't pass around borrowed references), but let's not fool ourselves into thinking a good deal more vigilance is required.  I myself have made mistakes like what I described above.  This is the kind of thing that's likely to scare off novices, which is something we definitely DON'T want.



I guess to me I don't really see why this would be all that different than if you used the name of a person that had been destroyed in a previous map in the 1.5 API.
Title: Re: minisphere 1.1b1 (stable: 1.0.10)
Post by: Fat Cerberus on April 28, 2015, 12:15:53 am

I guess to me I don't really see why this would be all that different than if you used the name of a person that had been destroyed in a previous map in the 1.5 API.


It might just be my pragmatism kicking in.  If all I have is a primitive type (string, integer, whatnot) for a reference, I fully expect the thing it references to be pulled out from under me and I'm more likely to remember to check for existence at critical moments as a result.  Object references I treat as essentially being the object they reference, so I don't expect it to suddenly disappear without my knowing about it.

Maybe I'm just weird. :P
Title: Re: minisphere 1.1b1 (stable: 1.0.10)
Post by: Flying Jester on April 28, 2015, 12:32:23 am
In that respect, though, the person does still exist. If they are no longer attached to a map, they could be placed back on a map, and it would work fine. It's just that you can't be sure if they are on a map unless you know what map they should be on. Since there can be a lot more to a person than what the faux-constructor exposes, this is a chief strength of this approach.

But in this scenario, you would be expressly drawing and updating certain maps. So you do know which maps are active and when, and you could find out pretty easily if the person was a part of an active map.

In my implementation, they could also (probably to some bad effect) be in multiple maps at once. But I haven't considered the issue of really drawing and updating multiple maps yet, other than seeing it's possible. Perhaps at that point, recursive map/person objects would be better? Or to only have a person reference their map and not the other way around? I have no idea.

Doing it as you do, making persons not attached directly to maps works better with this, then, since there is just a single list of persons that are active and updated with maps. If you were to reference the person's owning map from the person, too, that would (I suspect) be a simple way to support multiple simultaneous maps.
Title: Re: minisphere 1.1b1 (stable: 1.0.10)
Post by: Radnen on April 28, 2015, 02:02:13 am

Now that I think about it some more, splicing maps together like this actually seems like a hack.  It's essentially an optimization to avoid loading the whole map into memory at once, right?  Which makes sense, but wouldn't it be better--and simpler--to solve the problem in the map engine itself (whether in script or native, OO or otherwise), where if you have a huge map, the engine can automatically load and unload pieces of it on demand, just like how, when you have a huge, multi-gigabyte file, opening it in hex editor is instantaneous because it only loads a few KB at a time.


I know what you mean, my Sphere Studio does that fast loading (well, technically it stores the integers into memory but that's far cheaper than the grid of tiles. I create these buffer zones, totally inspired by Google Map and I draw those on screen only when they come into view, but they always keep a weak reference to the tiles that belong to them).

That said, yes I am in support of better map streaming, but I still think that you are getting messy with sprites on far corners of the map, and managing huge obstruction grids, but to be perfectly honest I don't know how bad the performance drain really is. I just wonder if you can reference an entity by name and they better exist, even if they hadn't been loaded in yet since technically they are on the far side of the map and not yet "streamed in". This is why performance might be na issue which is why I wanted to go with the cell-like structure that even 3D games like Morrowind used when loading neighboring maps. With the programmer managing the cells there's no illusion to their existence, you'd know if you streamed them in.

I mean Morrowind had to deal with the same issues: referencing an entity on the far end of a map and then waiting until they suddenly deallocate. I've seen this happen and maybe it's a partial cause to the Crash to Desktop people witness. But most of the time even though the reference to the object goes away most classes seem to handle it just fine (damage does nothing, arrows pass through them, minimap indicators disappear, etc.) but then again you may also be right that it could be due to discipline.

And you are right again in that Sphere should be easy to learn. But many things are easy to learn and difficult to master (take StarCraft for instance). I think we can add a more advanced OO API in addition to a functional API like we have, that's all.

In fact, I have made an OO implementation of Sphere person's by wrapping all the get/set method.

[gist=563ba8a4bc6c199877a9][/gist]

I'll say the gist feature is my #1 favorite feature of these forums.

I'll also add that since entities are names I use a cache table in addition to the above so I can always reuse the API without creating more classes (though in reality this is very lightweight).
Title: Re: minisphere 1.1b1 (stable: 1.0.10)
Post by: Fat Cerberus on April 28, 2015, 02:10:01 am
That's why I think the streaming should be handled in the map engine itself rather than the user splicing them together manually from outside.  The map engine is in a much better position to handle difficult cases such as you describe (entities outside the current "load window", etc.) as it has more complete information.  Anything done from outside involves a lot more guesswork.

That said, the Sphere map engine is very lightweight: a map is essentially just an array of integers, a tileset (usually not a huge image) and some entity data.  Even a 1000x1000 map is about 4MB worth of tile indices per layer and a single tileset.  There's basically no benefit to streaming it from disk when you have multiple gigabytes of ram to work with.
Title: Re: minisphere 1.1b1 (stable: 1.0.10)
Post by: Radnen on April 28, 2015, 02:27:32 am

That said, the Sphere map engine is very lightweight: a map is essentially just an array of integers, a tileset (usually not a huge image) and some entity data.  Even a 1000x1000 map is about 4MB worth of tile indices and a single tileset.  There's basically no benefit to streaming it from disk when you have multiple gigabytes of ram to work with.


Yes I know it's no much but I guess I'm more concerned that a bigger map means someone out there will attempt to update 3000 entities simultaneously. But then I guess that's on them then. ;)

Then the only thing I'll add by saying I liked the cell approach better than streaming it all in is because you can grow your maps infinitely in any direction. With one large static map, you kind of pigeon-hole yourself into that size. But I guess maps can always be grown to the right and bottom if needed.
Title: Re: minisphere 1.1b1 (stable: 1.0.10)
Post by: Fat Cerberus on April 28, 2015, 02:34:06 am
The main advantage to the cell approach that I can see is its potential for dynamism: splicing in a different map depending on different factors.  SMB1 World 7-4 type stuff.  So it's not entirely without merit. :D
Title: Re: minisphere 1.1b1 (stable: 1.0.10)
Post by: Radnen on April 28, 2015, 02:38:25 am
Celled maps also give a team project benefit, I mean try merging someone's 1000*1000 sized map with your edits. This can be facilitated with a merge tool, but it can be tricky to pull off.
Title: Re: minisphere 1.1b1 (stable: 1.0.10)
Post by: Fat Cerberus on April 28, 2015, 11:46:16 am
@DaVince Just tried the latest version of Sir Boingers that you sent me via PM, I see you upped the framerate to 60.  This made the gameplay very smooth, but apparently had a subtle effect on the jump physics that makes it harder to control.  But no crashes.  So yeah, it must just be that you have a stock version of Allegro on Linux that still has the buffer overflow bug.  Apparently Allegro 5.1.10 is coming out soon, though. :)
Title: Re: minisphere 1.1b1 (stable: 1.0.10)
Post by: DaVince on April 28, 2015, 01:12:36 pm
Good to know. And yeah, the physics are a thing to be fixed, the first thing I needed to fix was setting a sane framerate though. :P
Title: Re: minisphere 1.1b1 (stable: 1.0.10)
Post by: Fat Cerberus on April 28, 2015, 01:45:55 pm
What would be a good thing in the engine to be able to configure?  Right now all I can think of is the key/button bindings, which hardly seems worth the effort.  I need more stuff to be able to work up the ambition to do it. :P
Title: Re: minisphere 1.1b1 (stable: 1.0.10)
Post by: DaVince on April 28, 2015, 04:54:26 pm
Fullscreen mode and screen multiplication size would be nice. Also video filter, if you ever implement something like that anyway.
Title: Re: minisphere 1.1b1 (stable: 1.0.10)
Post by: Fat Cerberus on April 29, 2015, 02:08:38 am
It's not a config tool, but... I just implemented automatic U/V coordinate assignment for Shapes, and it's working great. ;D

@FlyingJester: Want to see a neat trick?  I assign default U/V coords like this:
Code: (c) [Select]
bounds = get_shape_bounds(shape);
width = bounds.x2 - bounds.x1;
height = bounds.y2 - bounds.y1;
for (i = 0; i < shape->num_vertices; ++i) {
delta_x = shape->vertices[i].x - bounds.x1;
delta_y = shape->vertices[i].y - bounds.y1;
shape->vertices[i].u = width > 0 ? delta_x / width : 0.0;
shape->vertices[i].v = height > 0 ? delta_y / height : 1.0;
}


Essentially I calculate the shape's bounding box, and then do a bit of linear interpolation on the vertices to get the U/V values.  This works for any number of vertices with no predefined lookup tables needed. :)

There is a downside, of course: If you accept the defaults, the texture basically becomes a decal.  This is the one upside of TS's method: If your 4-cornered shape is something other than a rectangle (a rhombus, say), the texture map remains rectangular (0,0)-(1,1) and the image is properly distorted.

Edit: So, new method, still works for any number of vertices but allows the texture to distort (note: assumes clockwise winding starting from top left):
Code: (c) [Select]
static void
assign_default_uv(shape_t* shape)
{
double phi;

int i;

for (i = 0; i < shape->num_vertices; ++i) {
phi = 2 * M_PI * i / shape->num_vertices - M_PI_4 * 3; // counterclockwise offset 135 degrees
shape->vertices[i].u = (cos(phi) * M_SQRT2 + 1.0) / 2.0;
shape->vertices[i].v = (sin(phi) * M_SQRT2 + 1.0) / 2.0;
}
}


Essentially what I'm doing is circumscribing the UV space--which conveniently happens to be a unit square!--and then setting UV to points on that circle.

Edit2: Correction, clockwise winding.  Trig functions are canonically CCW, but the inverted Y axis reverses the winding.
Title: Re: minisphere 1.1b2 (stable: 1.0.10)
Post by: Fat Cerberus on April 30, 2015, 02:26:24 pm
New beta posted. ;D
Title: Re: minisphere 1.1b2 (stable: 1.0.10)
Post by: Fat Cerberus on May 01, 2015, 01:40:07 pm
I'm presently in the process of updating the Specs Threader.  I'm going to include with minisphere 1.1 as a system script. 8)

It's like an OO version of hook-list.js:
Code: (javascript) [Select]
Threads.initialize();
// ...
var tid = Threads.create(obj);
// obj has .update() and optional .render() called once per frame


It's also a bit like pthreads in that you can do this:
Code: (javascript) [Select]
var worker = Threads.create(obj);
// do some stuff, and then later, perhaps during an update:
Threads.join(worker); // block until worker terminates

...and it will only block the current thread (if any).

For what it's worth I think it might be a good idea to implement some sort of NuGet-type system, where external dependencies such as Link and this can be declared in a the game's metadata and be automatically retrieved.  That's a project for another time, though.
Title: Re: minisphere 1.1b2 (stable: 1.0.10)
Post by: Radnen on May 01, 2015, 08:10:58 pm

For what it's worth I think it might be a good idea to implement some sort of NuGet-type system, where external dependencies such as Link and this can be declared in a the game's metadata and be automatically retrieved.  That's a project for another time, though.


http://forums.spheredev.org/index.php/topic,1262.msg5934.html (like bower)
Title: Re: minisphere 1.1b2 (stable: 1.0.10)
Post by: Fat Cerberus on May 01, 2015, 08:15:52 pm
Is t that just about a way to load modules that already exist in the engine's search path, whatever that happens to be?  I guess it could be extended to search the Internet or something, but I didn't get the feeling that was what it was about.  That's more about modularizing stuff to avoid name clashes.
Title: Re: minisphere 1.1b2 (stable: 1.0.10)
Post by: Radnen on May 01, 2015, 08:48:28 pm

Is t that just about a way to load modules that already exist in the engine's search path, whatever that happens to be?  I guess it could be extended to search the Internet or something, but I didn't get the feeling that was what it was about.  That's more about modularizing stuff to avoid name clashes.


Well, it's kinda both. Dependency management, name clashes and a tool like bower that you can use to pull dependencies automatically from a server (which is what NuGet is like, or NPM).

But this is more like an editor feature if anything. Unless you want to go the node route and inherently work with modules (meaning we must change the way in which we program and expose the code to all of our games going forward).
Title: Re: minisphere 1.1b2 (stable: 1.0.10)
Post by: Fat Cerberus on May 01, 2015, 08:52:25 pm
Right, which is what the Pegasus spec currently advocates.  Everything is a module, even built-in engine functions.  Personally I hate that model myself, though I can see the appeal.
Title: Re: minisphere 1.1b2 (stable: 1.0.10)
Post by: Flying Jester on May 02, 2015, 12:20:16 am
One aspect that I find appealing is that, under the plugin model of TurboSphere, you can run dedicated servers for networked games. In the case of TS, you can actually lose the libraries you don't want. The distro becomes smaller. Of course, the flip side is that it is a more complex setup in the first place.

Being able to remove any portion of the engine is important to me. Should someone find the audio plugin unsuitable, for instance, they could write their own or use an alternative, but not lose the other plugins. A Linux model, as opposed to a BSD model, if you will.

But of course, this is an aspect that is rather different in philosophy than Sphere 1.5. It just so happens you can recreate a Sphere-like environment while still working this way.
Title: Re: minisphere 1.1b2 (stable: 1.0.10)
Post by: Fat Cerberus on May 02, 2015, 12:29:39 am
True, I just don't feel, with minisphere being ~1.75MB for a complete 64-bit Sphere 1.x implementation (okay, so some stuff is missing like the Animation API, sue me :P) that works out of the box, plus all the extras it offers, it's worth adding the overhead of plugins (this is why I preferred the monolithic Allegro build before I switched to static linking--use more than about 2 Allegro components and the monolith DLL is actually smaller than the individual ones).

With TurboSphere the plugin model makes more sense, since it's designed for maximum flexibility.  minisphere I see more as a "download it and have a ball" deal.

By the way you might want to update the note about minisphere in the TS readme--I don't think minisphere can be considered in "early development" anymore. ;)
Title: Re: minisphere 1.1b2 (stable: 1.0.10)
Post by: Fat Cerberus on May 02, 2015, 01:20:57 am
I give to you: minithreads!  This is a generic adaptation of the threader I'm using in my game Spectacles: Bruce's Story.  It only works out of the box in minisphere, but would probably work in Sphere 1.5 with some tweaking.

[gist=0d2a95dcbbccf9a5ebb1][/gist]

Usage:
Code: (javascript) [Select]
// note: the below calls SetUpdateScript(); and SetRenderScript() intrinsically:
Threads.initialize();

// if `obj` is an object with .update() and .render() methods:
var threadID = Threads.create(obj);

// or perhaps to encapsulate a threaded thing:
this.threadID = Threads.create(this); // on construction
Threads.kill(this.threadID); // on disposal

// to create a makeshift thread for any object:
var vertices = [ /* ... */ ];
var texture = new Image("myTexture.png");
var shape = new Shape(vertices, texture);
var group = new Group([ shape ], shader);
Threads.createEx(group, {
    update: function() { return true; },
    render: function() { this.draw(); }
});

// to block until a thread finishes:
// (it is safe to call .join() in a thread updater--that thread will block
// but other threads will continue happily humming along!)
Threads.join(threadID);
Title: Re: minisphere 1.1b2 (stable: 1.0.10)
Post by: Fat Cerberus on May 02, 2015, 10:24:07 am
And here's a polyfill for another minisphere 1.1 feature: the RNG object.  Of particular note: RNG.fromNormal(). 8)

[gist=779ddef439c8b93f393b][/gist]
Title: Re: minisphere 1.1b3 (stable: 1.0.10)
Post by: Fat Cerberus on May 03, 2015, 01:37:53 am
minisphere 1.1b3 is now up and available to download. Tons of new features in this one (and a couple more bug fixes too)!  The RNG object is one I'm particularly proud of.  It's based on MT19937 (AKA Mersenne Twister), has a bunch of different generation methods, and allows manual seeding unlike JS's Math.random().  See the included API documentation for full details on it, it's pretty awesome.

I also took yet another leaf from TurboSphere's book and started on a JS-based "minisphere Runtime", previewed in this beta.  1.1b3 includes minithreads and minidelegate, the functionality of both of which have been invaluable during development of Spectacles and which I imagine will be useful in many, many games.  I'm thinking the final 1.1 release will also include a version of Scenario as part of the runtime as well.  These scripts can be used like this:

Code: (javascript) [Select]
RequireSystemScript('mini/threads.js');
RequireSystemScript('mini/delegate.js');


Also, minisphere is now officially BSD-licensed.  I figured it was about time I added a proper license file to the repo. :P


@DaVince:
1.1b3 fixes the BindKey() bug you reported on GitHub. :D
Title: Re: minisphere 1.1b3 (stable: 1.0.10)
Post by: Radnen on May 03, 2015, 03:50:03 pm
There are three things I want to see fixed sometime before I can even use this engine.

1. Fix the windowstyle bug for windows that have edge widths/heights less than 16 pixels. (See attached).
2. Make GetPixel() much faster so all code I have written that incorporates pixel perfect collision can make my game playable. It's too slow right now.
3. Fix a weird blit bug. (See attached). Things are offset by half the width of an image, but in other engines that's not the case. Like the hp bar, it's offset wrong. What do you get from image.width/2?

Edit: I will say that I'm impressed. You've really made it work on many games. :) Sometimes it's down to a single feature that a game doesn't run, so good you've got most features implemented.
Title: Re: minisphere 1.1b3 (stable: 1.0.10)
Post by: Fat Cerberus on May 03, 2015, 05:15:24 pm
That rotation bug was a known issue at one point... Then I forgot about it. :P  I think Allegro's treatment of the origin during rotation blits is off or something.  Either that or more likely, I interpreted it wrong.

The dashed windowstyle... Funny story about that.  I didn't really do much testing of Blockman in Sphere 1.5, I was too determined to get it running in minisphere.  As a result, I thought that was what it was SUPPOSED to look like.  If I had to guess, I'm thinking Allegro is padding out small bitmaps to be 16x16 under DirectX, as the windowstyle oddities doesn't happen with an OpenGL build of Allegro.

And the GetPixel() optimization I keep forgetting to get around to.  Thanks for the reminder!

And yes, I was VERY dedicated to making it compatible early in development.  I spent literally half a day trying to figure out a bug that caused Aquatis to crash on the opening credits.  It turned out to be a stupid refcounting error. :P
Title: Re: minisphere 1.1b3 (stable: 1.0.10)
Post by: Fat Cerberus on May 04, 2015, 01:52:42 am
I fixed the Image:rotateBlit() issue.  It was user error, as I suspected: Allegro treats the X/Y for a rotated blit as the center of rotation, whereas Sphere apparently aligns it to the top-left.  It should have been fixed a long time ago, but I forgot all about it once I started working on the map engine.

Moving on... I added pixel caching for Surface:getPixel().  It definitely helped, but it's still ungodly slow.  It might help if you stopped creating a surface anew with each collision check.  Allegro stores all bitmaps on the GPU, so each time you call Image:createSurface(), a new texture has to be uploaded.  Not only that, but it's putting a lot (and I mean A LOT) of stress on the garbage collector: I added some logging for images, and... well, let the console output speak for itself:

Code: (text) [Select]
Last 4 lines after entering test map:
[image 4731] Cache miss!
[image 4731] Creating new pixel cache
[image 4731] get_image_pixel() using pixel cache
[image 4731] Dropped pixel cache

Last 4 lines after ONE attack:
[image 5868] get_image_pixel() using pixel cache
[image 5885] get_image_pixel() using pixel cache
[image 5868] get_image_pixel() using pixel cache
[image 5885] get_image_pixel() using pixel cache


So during processing of a single attack, the game created (and possibly destroyed, depending on how aggressive Duktape's GC decided to be) over 1,000 bitmaps.  The thing died right away, so my guess is a few attacks got coalesced due to lag, but still: 1,000+ bitmaps!  That's insane.  That's literally insane.  No amount of pixel caching I can do is going to help that.  I honestly have no idea why--or HOW--it works so well in Sphere.

HOWEVER, full disclosure--I don't think this is the only issue.  What exactly goes on under the hood when you swing the sword?  I'm consistently able to drop the framerate to 30-40 fps on my i3 just by slashing at thin air, but I get no log entries that a pixel cache was created during this.

The last thing I have to fix is that windowstyle glitch.  I'm not sure how to deal with that yet.  I may end up switching to an OpenGL build of Allegro.  The only thing that worries me is that OpenGL tends to be slow on Windows, certainly slower than D3D.  But it would fix the windowstyle issue, so....

Edit: Yep, same issue with the slashes--simply slashing at thin air creates and destroys nearly 100 bitmaps.  Sorry to say, this game is VERY poorly optimized. :(  If it were me, what I would do is call .createSurface() once for each relevant sprite frame and then cache those somewhere.  This way you can just pull them from the cache and do .getPixel() on them with impunity.  As long as the surface contents never change (which they shouldn't), you'll never get a pixel cache miss and Allegro won't have to upload hundreds of textures for every attack.
Title: Re: minisphere 1.1b3 (stable: 1.0.10)
Post by: Radnen on May 04, 2015, 02:53:04 am

Edit: Yep, same issue with the slashes--simply slashing at thin air creates and destroys nearly 100 bitmaps.  Sorry to say, this game is VERY poorly optimized.


I'm a bit unnerved, really. I honestly don't know what to say. But I'll get to that in a sec, first an explanation. I'll be gentle, don't worry.

So I have no idea how thin air slashing does that. I mean it's just COMMAND_ANIMATE frames. I mean, I did nothing outside the bounds of the map engine for the action system (except the pixel collision detector). I use Pythagorean distance first to check if there are frames to collide with before this whole hundred-sprite-creation thing begins to happen

Are you saying this, on thin air creates and destroys 100 bitmaps?
Code: (javascript) [Select]

        // search and return a list of enemies in a 16 pixel radius at the front of the character. This is Attack()
        var list = this.getNearest(16, player.xv*16, player.yv*16);
        while (i--) {
            enemy = list[i];
            if (this.check(this.input, enemy.name)) { // call the check method
                //...
            }
        }


Thin air slashing ought to put the sword well away from the nearest enemy sprite. And how on Earth could it create a hundred to a thousand frames? Look at the code and think about it. I call the attack script only once on frame change.

Code: (javascript) [Select]

            // search for and add functions to certain frames.
            dir = "attack" + dirs[i];
            for (var n = 0; n < 7; ++n) {
                if (n == 4)
                    this.actionmanager.addFrameCall(dir, n, Cut);    // frame 4: cut
                else
                    this.actionmanager.addFrameCall(dir, n, Attack); // all others: check collision on Attack (see above)
            }

// later on in actionmanager:
// LOOK at it. It only does actions on frame switch: (because a sprite frame can last up to 8 screen frames)
var frame = GetPersonFrame(this.attached);
if (this.frame != frame) {
var index = GetPersonDirection(this.attached) + ":" + frame;
if (this.framecalls[index]) this.framecalls[index]();
this.frame = frame;
}


Technically my code only has to create bitmaps 2 times per frame (your source and the opponent source). I mean, I'm sure it'll create no more than 10 bitmaps max. I think your engine needs some work here. I mean, there are at least 100 to 1000 pixels to zip through on a dead collision check call, if it occurs. Are you telling me that each time I get a pixel your engine must create and destroy a bitmap? You have power over that my friend, not me. Especially if blank calls to COMMAND_ANIMATE does it. Well, technically running in your engine I can try to mitigate that, but at this point I'm not sure what's possible. I can cache the 2 bitmaps, but then I'm saving these 10 creations each time, the enemy constantly changes, mind you. So I could cache the payer. But if it's really each time a pixel is returned...I'm not sure. I don't want to have to lug around huge caches of enemies and players, or heck, maintain a cache pool if I can help it.

The "unoptimized section"
Code: (javascript) [Select]

        var ss = GetPersonSpriteset(player);
        var dir = ss.directions[GetDirectionNum(ss, GetPersonDirection(player))];
        var frame = dir.frames[GetPersonFrame(player)];
        var image = ss.images[frame.index].createSurface();
       
        // person B:
        ss = GetPersonSpriteset(who);
        dir = ss.directions[GetDirectionNum(ss, GetPersonDirection(who))];
        frame = dir.frames[GetPersonFrame(who)];
        var image2 = ss.images[frame.index].createSurface();


Above surfaces are created but only 2. Only 2 new bitmaps are created per call of check. Per the frames it's called on. Which is precisely frames 1 through 6 except 4. So 5 frames, which is no more than 10 bitmaps being created and thrown away. I check in SSFML, and yep, only 10 bitmaps. There is no lag. I usually don't try to optimize if there's nothing too crazy to optimize.  The code I use here is also industry standard (using pythos first, then making sure you only check an intersection of bounding boxes. In fact I doubt more than 256 pixels are ever checked!!). It's really industry leading. It's quite good, my friend of friends. Assuming of course bitmap creation is relatively cheap. If it's not, I can fix this, and you're right about it being unoptimized, but I'd say only slightly so. Because it's either this or cache pooling, and do I really want to do that if this works well enough? I mean each frame the enemy and player changes, and then each direction, for each enemy. There are so many states each bitmap can be in at any given time I'd rather reconstruct than cache, especially if reconstructing like it is in SSFML and Sphere1.5 is as dang fast as it is.

Because...

I only optimize code I've profiled for, looking for bottlenecks. ;) It's really what any sensible programmer would do. You saying the game is not very optimized kinda stings since I strive for that, but only in areas where I needed it. I say your engine is what's unoptimized here buddy since my SSFML handles this even better than Sphere's. The difference being I've used SW bitmaps. Now, I've moved on to HW sprites and noticed compositing was really fast but simple things like updating and creating new bitmaps as well as getting pixels was really slow. So I'm moving back to SW for good even if it means it's "slower".

Edit:
I profiled getPixel in SSFML and between 6000 to 2000 pixels are checked. Which is fine. Worst case scenario is 48*48*10 which is 23000ish pixels. Swinging empty air does nothing. No pixels, no bitmaps, nada.
Title: Re: minisphere 1.1b3 (stable: 1.0.10)
Post by: Fat Cerberus on May 04, 2015, 08:51:23 am
Sorry, I didn't mean to offend you--the game itself really is awesome, and the thousand bitmaps shocked me, too.  I'm only able to go by what the few logging calls I've added, but I honestly have no idea why it's creating so many.  Hell, I can just walk around aimlessly and get about 5-10 "created image via clone" log entries per second.  It makes no sense, because this doesn't happen in Specs or any other Sphere game I've tested.  Just yours.  Blockman is doing something differently but I don't know what yet.  I don't doubt the issue is on my end, though.

What's weird is that it's NOT generating multiple images for the actual pixel check--a successful attack generates a long string of pixelcache hits on the same two images.  It's just that it seems to be creating a lot of them in-between each check.  Weird.

Totally agreed on not making premature optimizations, don't take that the wrong way.  I myself advocate the "don't do it" school of optimization--it's the reason minisphere's codebase is still so clean. :D  I admit I jumped to conclusions when I said the game was unoptimized, but as I said, this is literally the ONLY game I've tested that causes so many images to be generated in such a short timeframe.  Out of probably a hundred games, both big and small.  "Engine bug" was naturally the last thing I would have considered.

So yeah, I thank you for clarifying the under the hood operation--I will now run the MSVC profiler to figure out where all the images are being generated.
Title: Re: minisphere 1.1b3 (stable: 1.0.10)
Post by: Fat Cerberus on May 04, 2015, 12:18:43 pm
So, I found part of the problem.  Take a look at this line in clone_spriteset():
Code: (c) [Select]
if ((clone->images[i] = clone_image(spriteset->images[i])) == NULL) goto on_error;


Spriteset bitmaps are never written to (only replaced wholesale), so the image cloning was completely unnecessary.  I changed the offending clone_image() call to ref_image() and that sped things up a ton.  My bad! :-[

Now, if you're wondering why I'm cloning spritesets at all, well, this calls for some background: As you know, I strive for compatibility, and the semantics of Get/SetPersonSpriteset() in Sphere are... odd, to say the least.  If you call GetPersonSpriteset() and change stuff around (replacing images, directions, etc.), the changes aren't reflected immediately--you have to call SetPersonSpriteset() to commit the changes.  And then, if you make further changes after that, you have to set it again.  This is ridiculous and completely counterintuitive, but I have to emulate it to remain compatible in odd corner cases (Aquatis was a wonderful source of these), and doing so means cloning the spriteset every time someone calls either function.  And since you use GetPersonSpriteset() a lot... yeah.

One thing I still notice, even with this change, is that I get a lot of this when just walking around aimlessly:
Code: (text) [Select]
[image 5416] Read 16 x 16 image from file
[image 5417] Read 16 x 16 image from file
[image 5418] Read 16 x 16 image from file
[image 5419] Read 16 x 16 image from file
[image 5420] Read 16 x 16 image from file
[image 5421] Read 16 x 16 image from file
[image 5422] Read 16 x 16 image from file
[image 5423] Read 16 x 16 image from file
[image 5424] Read 16 x 16 image from file
[image 5425] Read 16 x 16 image from file
[image 5426] Read 16 x 16 image from file
[image 5427] Read 16 x 16 image from file


To clarify, those are direct reads of an embedded image from an open file (such as happens when loading a tileset or spriteset).  Not sure what's up with that, probably something else stupid I'm doing somewhere.

There is a silver lining, of course... I guess it's a sign of a mature project when you to get to the stage of having to deal with low-level issues like this. :)
Title: Re: minisphere 1.1b3 (stable: 1.0.10)
Post by: Flying Jester on May 04, 2015, 01:09:01 pm

Moving on... I added pixel caching for Surface:getPixel().  It definitely helped, but it's still ungodly slow.  It might help if you stopped creating a surface anew with each collision check.  Allegro stores all bitmaps on the GPU, so each time you call Image:createSurface()


This is why Surfaces are meant to be totally in software. They are supposed to be relatively quick to create, destroy, and manipulate, much faster than Images.
Title: Re: minisphere 1.1b3 (stable: 1.0.10)
Post by: Fat Cerberus on May 04, 2015, 01:18:30 pm


Moving on... I added pixel caching for Surface:getPixel().  It definitely helped, but it's still ungodly slow.  It might help if you stopped creating a surface anew with each collision check.  Allegro stores all bitmaps on the GPU, so each time you call Image:createSurface()


This is why Surfaces are meant to be totally in software. They are supposed to be relatively quick to create, destroy, and manipulate, much faster than Images.


It would be literally trivial for me to have Allegro create surface bitmaps in memory... but wouldn't blitting Images to Surfaces then be SLOW since you're crossing the hardware boundary?  I guess I should do some tests, thanks for the tip.

Edit: Yep, that did the trick!  No pixel caching needed! ;D (scratch that, the pixel caching is still needed even with s/w surfaces--apparently al_get_pixel() is slow no matter what.

@Radnen: In case it wasn't clear, your getPixel() woes are fixed in the latest build.  Now I just have to tackle that windowstyle issue...
Title: Re: minisphere 1.1b3 (stable: 1.0.10)
Post by: Flying Jester on May 04, 2015, 02:48:50 pm

It would be literally trivial for me to have Allegro create surface bitmaps in memory... but wouldn't blitting Images to Surfaces then be SLOW since you're crossing the hardware boundary?  I guess I should do some tests, thanks for the tip.


Drawing Surfaces is OK to be slow. It's notably slower drawing Surfaces than Images in Sphere 1.5.
That is one of the tradeoffs of Surfaces, and why they are different than Images. Surfaces should be quick to read and write and cheaper to manage, Images should be fast to draw. Other performance aspects are generally irrelevant.
Title: Re: minisphere 1.1b3 (stable: 1.0.10)
Post by: Fat Cerberus on May 04, 2015, 04:56:26 pm
@Flying Jester
I knew there had to be a fundamental difference between the two (surface and image) beyond the superficial "you can write to one but not the other".  I just couldn't figure out what until you specifically pointed it out.  Luckily the way Allegro is set up, it was trivial to have it allocate surfaces in system memory instead of on the GPU.  Internally it's still an image_t structure, just that the underlying bitmap is created with different flags.

Honestly I'm pretty dumb for not figuring this out sooner.  There's a reason there are methods to convert between the two types!
Title: Re: minisphere 1.1b3 (stable: 1.0.10)
Post by: Radnen on May 04, 2015, 08:11:07 pm

but as I said, this is literally the ONLY game I've tested that causes so many images to be generated in such a short timeframe.  Out of probably a hundred games, both big and small.


I'm glad it was a good test case then. :) My game is really the only mature Sphere ARPG. Other games even Aquatis and T&E use separate views for their battles (take place in turn based arenas) so spriteset related action based things might not happen in the same manner. And I doubt they use pixel perfect collision to the degree that I do.

BTW Lord English I do understand in Sphere and am willing to accept that drawing surfaces and converting to surfaces is expected to be slow and is on the users end to mitigate those calls with their own crafty solutions. But creating a few surfaces here and there ought not to be slow. The next test in Blockman is entering a cave and seeing if the fullscreen darkness "shader" plummets the fps. I'm not the only game to do this since I used SDHawk's (blast from the past) advice on it.

Edit: BTW, running around in Blockman does create dust plumes under his feet, these can be what triggers those surface creations when walking around. Though I don't know why surfaces are created... It does load a new spriteset each time rather than reuse one. It's a stupid Sphere thing since CreatePerson forces you to load a spriteset per entity. I cache spritesets in SSFML, but it has the issue that perhaps each entity can share modifications made against them. Though I haven't seen that in the games I've tested, most games usually copy or reload from file a new spriteset via LoadSpriteset() whenever they modify a users sprite.
Title: Re: minisphere 1.1b3 (stable: 1.0.10)
Post by: Fat Cerberus on May 04, 2015, 09:26:28 pm
They aren't surfaces created, they are images, read as raw RGBA data from an open file.  Three things do this: load_tileset(), load_spriteset() and load_windowstyle().  So yeah, thanks for the tip on the dust plumes, I hadn't noticed those.  :)  There is a way you can avoid recreating new entities every time, just use SetPersonVisible and reuse them... But I agree it's pretty dumb that it doesn't let you pass in a Spriteset object to CreatePerson().  I think I'll go implement that now.
Title: Re: minisphere 1.1b3 (stable: 1.0.10)
Post by: Radnen on May 05, 2015, 12:16:21 am

There is a way you can avoid recreating new entities every time, just use SetPersonVisible and reuse them...


Neat idea, but you can have more than 2 dust plumes on screen so I'd have to craftily cycle anywhere between 2 to 4 them and that's a kind of complexity I didn't want to do. It seems that there is one pervasive issue with Sphere's API. Without client-side pooling and caching most calls to the Sphere API copy and clone data with reckless abandon. It's either you trust the underlying engine does a good job handling that for you, or you write lots of boilerplate whenever you need some simple effect.


... it's pretty dumb that it doesn't let you pass in a Spriteset object to CreatePerson().  I think I'll go implement that now.


That's a good step in the right direction. Oftentimes and in most other game engines many duplicates of objects like bushes, grass, footsteps in sand or snow, coins, etc., reuse the same asset to reduce the memory footprint. So, being able to directly tell Sphere that we intend to reuse the same spriteset in any number of entities can really aid in speeding things up. Creating and destroying entities is usually a cheap thing to do, I mean it really only encodes a few properties (mainly positional, nothing a matrix can't solve, really).

Also, imagine drawing to screen 30 entities with the same sprite atlas. You'll have sped drawing up considerably since you aren't changing the source texture each time. Games like DaVince's Sir Boingers can be sped up with this technique.

Now, I'm not sure here but Sphere has to cache Spritesets like my SSFML does. I can't imagine loading the same spriteset 300 times in a giant room with lots of coins in it. But who knows? It might do that? I'm not sure, I'll have to profile a demo.
Title: Re: minisphere 1.1b3 (stable: 1.0.10)
Post by: Radnen on May 05, 2015, 12:50:00 am
Results of my test:

Loading a map with 50 non-trivial entities. Same spriteset!
1. SSFML (30ms, then 5ms repeatedly)
2. Sphere1.5 (6ms, then 4ms repeatedly)
3. Minisphere (300ms then, 190ms repeatedly)

With 1 entity:
1. SSFML (30ms, then 5ms repeatedly)
2. Sphere1.5 (6ms, then 4ms repeatedly)
3. Minisphere (10ms, then 5ms repeatedly)

I say the hit with our engines is any sprite batching, vertex mapping, or texture appropriations due to HW acceleration methods.

Edit
With 2 different spritesets the numbers went up linearly initially. Only adding different spritests did Sphere 1.5 take longer to load. Repeating the same spriteset added no time.
Title: Re: minisphere 1.1b3 (stable: 1.0.10)
Post by: Fat Cerberus on May 05, 2015, 01:04:58 am


... it's pretty dumb that it doesn't let you pass in a Spriteset object to CreatePerson().  I think I'll go implement that now.


That's a good step in the right direction. Oftentimes and in most other game engines many duplicates of objects like bushes, grass, footsteps in sand or snow, coins, etc., reuse the same asset to reduce the memory footprint. So, being able to directly tell Sphere that we intend to reuse the same spriteset in any number of entities can really aid in speeding things up. Creating and destroying entities is usually a cheap thing to do, I mean it really only encodes a few properties (mainly positional, nothing a matrix can't solve, really).


Done.  It a rather simple change, actually.  Just some additional bookkeeping, and even that wasn't really an issue either as spritesets are already refcounted internally.

While we're on the subject of profiling and performance, you know how Blockman takes an coon's age to load fonts under minisphere on startup?  I fixed it.  Turns out the reason it was so painfully slow was because I was locking and unlocking each individual subimage (fonts are atlased) when loading characters.  That's 256 lock/unlock cycles, meaning data has to be uploaded to GPU every single time.  Now I lock the entire atlas ONCE, load all the glyphs, and then unlock it.  That's only one GPU upload.  The "Loading Fonts" text goes by so fast now you can barely even see it. ;D

Now those slow map loads have me wondering...

Edit: Okay, map loads are much faster now too, after an edit to the tileset loader.  It was the same issue as with fonts, the issue was just less pronounced as most tilesets don't have 200+ tiles in them and even then, you're only loading one at a time.  I should make a similar change the spriteset loading code, but it will be more difficult as spritesets aren't atlased.  At the time, it didn't seem worth it to atlas them since you're only usually drawing one image from a spriteset at a time.  But I might just do it anyway now to speed up map loading...
Title: Re: minisphere 1.1b3 (stable: 1.0.10)
Post by: Fat Cerberus on May 05, 2015, 08:25:08 am
I just refactored minisphere's image locking.  It's safe to nest locks, any lock requests past the first just reuse the existing lock, which is refcounted.  Allegro would just outright refuse to lock the bitmap a second time, which is how my atlased loaders ended up so slow.  Now I can lock the atlas at the beginning of the loader, and the individual read_subimage() calls will just reuse the existing lock.

This is awesome, as now I can easily implement spriteset atlasing. :D

Edit: Not only have I implemented sprite atlasing, but I also went ahead and added a spriteset caching feature.  Radnen, could you run your map load tests again on the latest source?  I'd be curious to see the results.
Title: Re: minisphere 1.1b3 (stable: 1.0.10)
Post by: Fat Cerberus on May 05, 2015, 08:08:06 pm
@Radnen
Figured out your windowstyle issue.  It's an Allegro limitation, and unfortunately, it's not a bug.

From Allegro 5.1.9 ogl_bitmap.c:
Code: (c,7,8) [Select]
   /* This used to be an iOS/Android only workaround - but
    * Intel is making GPUs with the same chips now. Very
    * small textures can have garbage pixels and FBOs don't
    * work with them on some of these chips. This is a
    * workaround.
    */
   if (true_w < 16) true_w = 16;
   if (true_h < 16) true_h = 16;


Unfortunately this means windowstyles can't be tiled in hardware--I have to do it manually and take the performance hit.

Alternatively, I could comment out those two lines and see what happens.  I have an Intel GPU laptop (Core i3), so I'll know if anything's amiss.
Title: Re: minisphere 1.1b3 (stable: 1.0.10)
Post by: Radnen on May 05, 2015, 08:18:52 pm

Unfortunately this means windowstyles can't be tiled in hardware--I have to do it manually and take the performance hit.


Tile it in hardware anyways. If you witness sizes less than 16, switch to manual. But anyways 16 was the sphere windowstyle default. I usually use that size and larger, but sometimes things slip through.
Title: Re: minisphere 1.1b4 (stable: 1.0.10)
Post by: Fat Cerberus on May 05, 2015, 11:49:37 pm
v1.1b4 is out, boasting more bug fixes, massively improved performance, OpenGL rendering on Windows and one of my famous subtle-but-awesome changes:

RequireSystemScript() now searches <game_dir>/scripts/lib for scripts first, before the system scripts directory.
Title: Re: minisphere 1.1b4 (stable: 1.0.10)
Post by: Radnen on May 06, 2015, 01:17:00 am
So I did a stress test in Sphere 1.5, SSFML 0.9.0, and minisphere 1.1b4

This is running at 26fps with 500 entities in SSFML
https://www.dropbox.com/s/cnaylep3xytgqdl/stress-ssfml.png?dl=0

This is running at 21fps with 250 entities in Minisphere
https://www.dropbox.com/s/8p9u3kzejhu8nvv/stress.png?dl=0

This is running at 17fps with 250 entities in Sphere 1.5 in SphereGL
https://www.dropbox.com/s/4nflt2g7cg4mkgc/stress-sphere15.png?dl=0

All fps's are +/- 5.

And well... Sphere 1.5 couldn't do 50 on Standard32. This test was on Intel Core i5 3.3@3.6ghz, with an Nvidia GTX970, 8GB 1066@800Mhz ram. I think it's the JS logic that's bottlenecking the two good engines, and the graphics plus the logic for Sphere 1.5. In SphereGL I got by no different than minisphere, which is telling. You are not taking advantage of the hardware on the computer, it tells me you're still mostly drawing in immediate mode which is what kinda plagued SphereGL and Sphere in general. I know this since I know your JS engine is faster in most cases to Sphere 1.5.

My max target for the space game is 300 enemies on screen. But this rest is more of a curiosity. In the game you never see more than 20 anyways, unless there's a giant space battle programmed into it. But I think the stress test is still neat. No engine crashed BTW.

Ok, so... minisphere 1.1b4 loaded blockman much faster! The combat was also nice and smooth. :) But it did crash after playing for a while when I swung my sword at an enemy. So there's something there, maybe a get pixel call out of bounds?
Title: Re: minisphere 1.1b4 (stable: 1.0.10)
Post by: Fat Cerberus on May 06, 2015, 01:35:32 am
I could speed up the windowstyle loading too if I atlased them, but then hardware tiling doesn't work.  The main loading bottleneck was fonts and spritesets (and maps), which have been speed up a ton not only due to atlased loading in 1.1b4, but also spriteset pooling.

But yeah, most of the drawing is done in immediate mode because for some strange reason, Allegro doesn't always honor transformations when using batched mode.  This is needed because I use a transform to scale up the window for 320x240 games.  I'd rather take the performance hit than end up with dodgy rendering.

I assume you noticed your windowstyles render properly now?  I bit the bullet and compiled Allegro with the 16x16 texture clamping commented out.  So far I haven't had any issues, so... *crosses fingers*

As for those crashes, I've seen a few of them myself, but I haven't tracked down the cause yet.  Hence why minisphere 1.1 is still in beta. ;)
Title: Re: minisphere 1.1b4 (stable: 1.0.10)
Post by: Radnen on May 06, 2015, 02:50:10 am
You might want to stay in immediate mode for now. I'm taking a small risk batching everything. I'm meaning to create a small batching API to make it explicit. But I have found through my testing that even implicit batching is decent enough, and really only helps when you have much of the same sprite, like the above where the enemies and particles and bullets were the same 3 textures.

I guess if you stay in the map engine, implicit batching really is not needed since sprite atlasing covers that. The implicit batching I do to speed up the space game only really works when I program knowing that this behavior exists and that I can draw images in a custom engine rather than use spritesets in the map engine. There is a slight speedup drawing names on their own layer rather than in an A/B pattern. But it's minimal.
Title: Re: minisphere 1.1b4 (stable: 1.0.10)
Post by: Fat Cerberus on May 06, 2015, 03:12:25 am
So it didn't make it into 1.1b4, but I just added a console and BGM manager to the mini runtime, both originally coded for Specs.

The console is output-only (for now), but optionally lets you log output to a file, and because it uses minithreads, lets you pull up the console at any time during gameplay.  This little tool has been invaluable in debugging Specs glitches, and is generic enough that I thought it'd make a good addition to the runtime. :)

The BGM manager right now is a bit of a fixer-upper, but the intent is to turn it into a simple stack-based music switcher.  You push to change the song, and pop to return to the previous one (perhaps resuming where that one left off).  I might also add a "layer 0" as well for field music, which can be changed in place but only plays when there are no other tracks on the BGM stack.

That puts the minisphere runtime at 6 components:
- Core (provides delegates)
- Link
- minithreads
- miniscenes (Scenario)
- miniconsole
- miniBGM

Quite a nice set of tools it's shaping up to be, methinks.
Title: Re: minisphere 1.1b4 (stable: 1.0.10)
Post by: Fat Cerberus on May 06, 2015, 03:45:46 pm
So I got bored and implemented basic command support in miniconsole.  It's a very easy-to-parse command format--e.g. battle rsb2 for a test battle in Spectacles.  So now anyone that wants to implement a basic console in their game will have one ready to go!

Usage:
Code: (javascript) [Select]
RequireSystemScript('mini/Console.js');

mini.initialize({
    logFile: "consoleLog.txt",
    consoleLines: 10,
    consoleBuffer: 1000
});

mini.Console.register('bear', {
    'munch': DestroyPerson
});


Then the player could pull up the console and type in:
bear munch lauren

And the map person named "lauren" would get eaten by the bear and disappear.  How it is parsed is, the first token is the object name (bear) as passed to mini.Console.register(), the second token is the command name (munch), and the remaining tokens are passed as string parameters to the relevant method.  The actual call is also wrapped in a try/catch to try to prevent game crashes due to bad console input.

Fixed tt tag ~radnen
Title: Re: minisphere 1.1b4 (stable: 1.0.10)
Post by: Fat Cerberus on May 08, 2015, 03:01:56 am
minisphere 1.1 is going to be delayed by a bit, it seems.  I apparently broke something when adapting Scenario and now it locks up sometimes during scene execution.  I haven't been able to track down the cause.  It's odd, the game seems to completely lock up, but closing the minisphere window works, which means FlipScreen is being called.

I suspect a bad interaction between the Scenario threader and minithreads is causing a deadlock.  I didn't even think that was possible with cooperative threading (making a distinction between a deadlock and an infinite loop, before anyone calls me on it), but...
Title: Re: minisphere 1.1b4 (stable: 1.0.10)
Post by: Fat Cerberus on May 09, 2015, 01:53:20 am
So I think I'm going to end up releasing minisphere 1.1 without the runtime.

As it stands right now, all runtime components rely heavily on threads.  And as I've just found out, minithreads has a rather massive design flaw: Because join is emulated with recursion, joins don't always do what you expect: Assuming two simultaneous joins, satisfying the first one is--by definition of recursion--necessarily contingent on the second one returning.  Even if the first join would otherwise be satisfied first, in practice it can't be because one further down the rabbit hole is still blocked.  Sometimes--aw, who am I kidding, way too often--this can even cause a deadlock.

For whatever the reason, as long as I've been using this threader in Specs, this never bit me before now.  I guess Specs alone just didn't tax the system enough to flush it out--it wasn't until I tried to reimplement Scenario in terms of joins that it showed up, and struck HARD as Scenario absolutely requires reliable concurrency.  What sucks is that it took me all day to figure it out, after many exhausting hours of misguided hacking trying to fix what couldn't be fixed.

Curious how I finally figured it out?  I added two GetSeconds() calls to Scenario's tween scenelet, one in start and another in finish.  And lo and behold, one particular tween that was supposed to take half a second... didn't finish up until 12 seconds later.  I puzzled for a bit, and then it dawned on me what was going on... and I felt like a complete idiot. :-[
Title: Re: minisphere 1.1b4 (stable: 1.0.10)
Post by: Radnen on May 09, 2015, 02:04:52 am

Curious how I finally figured it out?  I added two GetSeconds() calls to Scenario's tween scenelet, one in start and another in finish.  And lo and behold, one particular tween that was supposed to take half a second... didn't finish up until 12 seconds later.  I puzzled for a bit, and then it dawned on me what was going on... and I felt like a complete idiot. :-[


That's not being an idiot, sometimes sanity checks once and a while help. Now, how are you going to solve it, that's the question. Deadlocks usually arrive because of a lack of concurrency handling, every threaded system has mutex locks, semaphores even busy-wait loops, you just need to pick solution(s) that work.

But I don't think this is a deadlock. It might be a race condition since after 12 seconds it finished rather than .5... a deadlock is most usually... dead! A race condition means things are vying for cycles and other loops/threads get pushed back. In fact I'm sure that 12 seconds is variable. Is it 13 next time, immidiate another, 5 seconds?
Title: Re: minisphere 1.1b4 (stable: 1.0.10)
Post by: Fat Cerberus on May 09, 2015, 02:24:51 am
Me being an idiot wasn't referring to the sanity check, it was that, knowing how recursion works, this eventuality never even crossed my mind.

But the 12-second tween indeed wasn't a deadlock.  However, deadlocks most certainly can (and DO) happen with this setup.

Here's the implementation of join():
Code: (javascript) [Select]
mini.Threads.join = function(threadIDs)
{
threadIDs = threadIDs instanceof Array ? threadIDs : [ threadIDs ];

if (!this.isInitialized)
Abort("mini.Threads.join(): must call mini.initialize() first", -1);
var isFinished = false;
while (!isFinished) {
this.doFrame();
isFinished = true;
for (var i = 0; i < threadIDs.length; ++i) {
isFinished = isFinished && !this.isRunning(threadIDs[i]);
}
}
};


Note that it loops until the requested thread(s) finish.  This works well enough--if there is only one outstanding join.  Trouble is, Scenario is often waiting on many things at once.  At this point, the recursive system breaks down.

Let's simplify things a bit and say we have four running threads, call them A, B, C and D.
* A joins B, which prevents A from being updated until B terminates.  So far so good.
* .join() is running its own loop, so B, C, and D keep updating.
* At some point (A is still waiting on B to finish), C joins D.
* B terminates.  A's join now can't be satisfied because, by definition of recursion, it is itself blocked by C's join.  D may not terminate until some way down the line, which means it's unintentionally holding up the works.

And yes, this system can give rise to a deadlock very easily.  In the simplest case, this will do it:
* A joins B.
* B joins A.

In practice, such cycles will be (and were!) much more roundabout and therefore difficult to debug.

Note that, due to the way the system is designed, the effects of this may not be immediately obvious as other threads will continue to update (just like preemptive threading!).  However, if what A is trying to accomplish is necessary for the game to continue (hence why B wanted to wait on it in the first place), this will put the game in an unrecoverable state.
Title: Re: minisphere 1.1b4 (stable: 1.0.10)
Post by: Fat Cerberus on May 09, 2015, 11:40:15 am
Speaking of sanity checks, I added Assert yesterday.  The API signature:
Code: (javascript) [Select]
Assert(condition, errorText[, stack_offset]);


I made the error text mandatory instead of optional to encourage meaningful asserts.  If an assert fails (the condition is false), the specified error text will be displayed in a modal popup allowing the user to choose whether to continue or terminate.  As with Abort(), the optional stack offset is used to blame the failure on a function earlier in the call stack.

Hm... now that I think about it, Assert should probably behave differently in the console vs. release engines.  In a release build (engine.exe, engine64.exe), a failed Assert should terminate the engine unconditionally (without giving you the yes/no options), while the Console build (console.exe, console64.exe) would log the assert to stderr and give you the option to try to continue.

As for that threader issue, what I think I'm going to do is modify the semantics of join.  Rather than block the caller directly, it will store the joined tids in the calling thread's "join list", and that thread will not get any further update() calls until all the joined threads have terminated.  This will require a few architectural changes to Specs, but so be it.  I'll definitely miss the blocking .join() though.  It almost perfectly emulates Pthreads join, but that "almost" turned out to be the killer.
Title: Re: minisphere 1.1b4 (stable: 1.0.10)
Post by: Radnen on May 09, 2015, 05:26:21 pm
I have found out that in our engines, SSFML and minisphere, this causes a considerable speedup to getPixel:

Code: (javascript) [Select]

function SurfaceWrap(image, hold) {
this.surface = image.createSurface();
this.width = image.width;
this.height = image.height;

var pixels = [];

this.update = function() {
var w = this.width, h = this.height;
for (var x = 0; x < w; ++x) {
pixels[x] = [];
for (var y = 0; y < h; ++y) {
pixels[x][y] = this.surface.getPixel(x, y);
}
}
}

if (!hold) this.update();

this.getPixel = function(x, y) {
return pixels[Math.floor(x)][Math.floor(y)];
}

this.rotate = function(r, s) {
this.surface.rotate(r, s);
this.update();
}

//... other methods...
}


I think it has to do with the domain bounds, between script engine and native execution because even with native side pixel caching, engine based caching is faster to retrieve from. The only downside to the above is, notice the rotate, I have to call the update method each time to get a fresh list. But my code only rotated the image once. The speedup isn't huge, though. Testing on 500 static images, the engine used to halt entirely in our engines. With this addition there is no visible halting, everything is just slow, like 10-17fps slow, but consistent which says this is much faster. Though in practice it may be slower, especially if you modify the surface a lot with rotations and other methods (I only wrapped the rotate method).

In Sphere1.5 the above errors with an out of memory error, after about 40 entities.
Title: Re: minisphere 1.1b4 (stable: 1.0.10)
Post by: Fat Cerberus on May 09, 2015, 07:21:02 pm
This makes sense.  When calling getPixel() directly, even though the engine is caching it, you still have the overhead of a function call per pixel.  In Duktape, a JS->C call is identical to a JS-JS call except for the last step (call into native instead of bytecode)--in fact it may even be faster because some of the call setup can be skipped (arguments object creation, etc.).  But the fact remains that calling a function in JS is a lot more expensive than in native.  Caching the pixels locally avoids that, as then the JS engine just has to retrieve values from an array, which is trivial.

By the way, the out of memory errors in 1.5... You will see those a lot.  It only allocates 5MB to the JS context!
Title: Re: minisphere 1.1b4 (stable: 1.0.10)
Post by: Fat Cerberus on May 11, 2015, 03:35:30 pm
I just added a new API: DoAsync().  This queues a script to be executed on the next FlipScreen.  It's like what setTimeout(fn, 0) does in a browser.  I added this mostly because of minipact, since according to the Promises/A+ spec, promise resolution must be asynchronous, outside the usual program flow.

I'm sure this has other uses, though... :)
Title: Re: minisphere 1.1b4 (stable: 1.0.10)
Post by: Fat Cerberus on May 12, 2015, 03:48:02 pm
So using promises for minithreads turned out to be inadequate.  They work well enough for Scenario which creates a bunch of one-off threads and runs them in parallel, only occasionally stopping to resync timelines.  But for more complex threading, like waiting on a menu thread during a battle, things get awkward because the battle thread still updates in the meantime.

What I'm going to do is change the semantics of join().  It will still return a promise, but it will ALSO exclude the calling thread from further update() calls until the threads being waited on finish.  This way join() would still work mostly like it does in Pthreads without holding up the works with recursive event loops, and the promise would take care of post-join logic (such as queuing a move, etc.)

Edit: On second thought, I'm not even going to do that.  Blocking join works fine for 90% of use cases, it's only interlacing joins that cause issues.  I'll just make a note not to do that in the documentation. :)
Title: Re: minisphere 1.1b4 (stable: 1.0.10)
Post by: Fat Cerberus on May 13, 2015, 02:00:13 am
@Radnen
I figured out the Blockman crashes.  The getPixel calls were fine, none were out of range--though I added bounds checking anyway, since Sphere also checks it (an out of range getPixel() will throw in 1.5).  The crash was here:

Code: (c) [Select]
void
update_persons(void)
{
bool is_sort_needed = false;

int i;

for (i = 0; i < s_num_persons; ++i) {
if (s_persons[i]->leader != NULL)
continue;  // skip followers for now
update_person(s_persons[i]);
is_sort_needed |= has_person_moved(s_persons[i]); // <-- CRASH HERE
}
if (is_sort_needed) sort_persons();
}


As part of update processing for persons, they can end up being deleted (if a command generator script destroys one, say), which is exactly what happened here.  Once I reproduced the crash, I checked the variables.  i = 3 and s_num_persons = 3, which meant one was deleted, but it was still trying to access the person structure, causing a crash.  Should be an easy fix.
Title: Re: minisphere 1.1b5 (stable: 1.0.10)
Post by: Fat Cerberus on May 13, 2015, 02:45:03 am
1.1b5 is out.  A couple bug fixes in this one, as well as two new APIs: Async() (required for promise compliance, see changelog) and Assert(), very useful for debugging.  This will be the last beta ahead of 1.1, now I want to concentrate on finishing up the API documentation before release, and maybe write that config tool...
Title: Re: minisphere 1.1b5 (stable: 1.0.10)
Post by: Fat Cerberus on May 16, 2015, 02:43:24 am
I decided to go in a different direction with the customizable key mappings.  I added a new API, SetPlayerKey(), to change the key mappings at runtime; any such changes are then saved out to disk on shutdown.  What I'm thinking is, I will add commands to miniconsole so that any game using the minisphere Runtime can have its keymap changed by the player through the console.  miniconfig as a separate thing will still exist, of course, but its scope will be enlarged: Allowing key mappings to be changed for any game minisphere has previously run or otherwise knows about.

This will allow me to work on miniconfig at my own pace, rather than having to rush it to make the 1.1 release.  I can release it separately when it's ready. :-)
Title: Re: minisphere 1.1b5 (stable: 1.0.10)
Post by: Radnen on May 16, 2015, 02:58:04 am
I like the idea. I've always wanted many config related options to be game specific. Hence why I never used the config.exe tool to set up key mappings, that and having the ability to set them and save them in game is always nice.
Title: Re: minisphere 1.1b5 (stable: 1.0.10)
Post by: Fat Cerberus on May 16, 2015, 11:52:23 am
See the screenshot below.  Any games using miniconsole will get these commands by default. :D
Title: Re: minisphere 1.1
Post by: Fat Cerberus on May 17, 2015, 02:07:26 am
It's been a long ride, but minisphere 1.1 is finally ready for primetime! ;D  So um... go download it!  See the changelog in the OP for all changes since 1.0.x, but the highlights are:


The download is a lot bigger this time (as in over 7 MB) not only because of the new Console engine but also because it includes a new Spectacles battle engine demo to show off the power of miniRT. :D
Title: Re: minisphere 1.1
Post by: Fat Cerberus on May 18, 2015, 12:11:51 pm
@Radnen
So I finally got around to implementing gradient circles, and was therefore able to test out the cave lighting effect in Blockman.  Results: Success!  Not only does the effect look great, but it runs at full speed.  See screenshot below. ;D
Title: Re: minisphere 1.1
Post by: Fat Cerberus on May 19, 2015, 05:22:50 pm
So, um... I got animation support working. Which means the KR intro now works! ;D

Damn is libmng bloated though.  It added about 200KB to the engine executable size.
Title: Re: minisphere 1.1
Post by: DaVince on May 19, 2015, 06:01:59 pm
Amazing and awesome. KR is a buggy mess that likes to not work properly on some versions of Sphere, so it might be an interesting test case for minisphere. :P
Title: Re: minisphere 1.1
Post by: Flying Jester on May 19, 2015, 08:17:46 pm
Did you add your own mng support, or was it in Allegro?


Damn is libmng bloated though.  It added about 200KB to the engine executable size.

;D
Title: Re: minisphere 1.1
Post by: Fat Cerberus on May 19, 2015, 08:19:27 pm
No, I had to do it myself using libmng and loading the frames into locked surfaces.  You'd think Allegro would have it, but nope.  Luckily I was able to use the Sphere source as a reference again, to lessen the learning curve a bit.

Edit: It's funny, I wasn't originally going to do it, I was just going to have some stub APIs in place to allow games using the functions to get by, but once the stubs were in place, I said ah, why not.  I'm used to the hassles of compiling dependencies on Windows by now, so what's another library? :P

Edit 2: I got the 64-bit Windows build of minisphere back down to under 1.7MB by rebuilding everything optimizing for size instead of speed. :D  I don't appear to have taken a visible performance hit by doing so, but time will tell...
Title: Re: minisphere 1.1.1
Post by: Fat Cerberus on May 20, 2015, 12:33:50 am
minisphere 1.1.1 is up.  This adds the animation support and finally fixes GradientCircle, which I've been too lazy to fix up until now.  Also, the windowstyle rendering should be fixed on all platforms as I added a workaround (i.e. tile in software) for images < 16x16.

I've decided to go to an Allegro-style "tick-tock" versioning cycle for minisphere: Even-numbered versions (e.g. 1.0) are stable and only receive bugfixes, while odd versions (e.g. 1.1) are considered WIP and can get new features (or have them removed) at any time.  I like this setup because it allows more public testing to be done on new features before they get committed to a genuine Stable release.
Title: Re: minisphere 1.1.1
Post by: Fat Cerberus on May 21, 2015, 11:42:49 pm
Just added shader support today.  :D

Code: (javascript) [Select]
var shader = new ShaderProgram('pixel.glsl', 'vertex.glsl');  // this might be changed to take an object argument
var image = new Image('ScottSucks.png');
var shape = new Shape([
{ x: 10, y: 10 },
{ x: 110, y: 10 },
{ x: 110, y: 110 },
{ x: 10, y: 110 },
], image);
var group = new Group([ shape ], shader);


Initial tests are promising!
Title: Re: minisphere 1.1.2
Post by: Fat Cerberus on May 23, 2015, 02:03:23 am
minisphere 1.1.2 out now, now with GLSL shaders!

You know, I'm beginning to think I'm releasing these faster than anyone can test them... :P  Good thing my own in-house tests are very thorough!
Title: Re: minisphere 1.1.3
Post by: Fat Cerberus on May 25, 2015, 02:23:14 am
1.1.3 has been posted.  Just a maintenance release, nothing groundbreaking this time. ;)

At this point it seems the only thing I'm really missing is a particle engine.  Sphere 1.6 had one from what I understand, and that's one thing that would definitely benefit from being implemented natively, I think.  It can be done in script, but I'd imagine it might be slow then.
Title: Re: minisphere 1.1.3
Post by: Fat Cerberus on May 25, 2015, 10:37:43 pm
Look what I got running! ;D

It was a pain because a lot of the map scripts included extended characters, which confused Duktape (it expects valid UTF-8 always), so I had to have the engine re-encode the embedded scripts on load.
Title: Re: minisphere 1.1.3
Post by: DaVince on May 26, 2015, 07:19:24 am
Amazing. Great work. I need to try this out right away. When the new release is out. Heh.
Title: Re: minisphere 1.1.3
Post by: Fat Cerberus on May 26, 2015, 01:00:40 pm

Amazing. Great work. I need to try this out right away. When the new release is out. Heh.


You got your wish--1.1.4 is posted, with a few other nifty fixes.

As for KR, it's a very interesting testcase indeed.  You can get it to run, but it requires a bunch of minor edits all over the place.  You'll find that there are a lot of lines like this:
Code: (javascript) [Select]
SetPersonLayer('turtletrainer', '3');


Which of course breaks in minisphere, and probably Sphere 1.6, because both support named layers.  If this were consistent, I could write it off as the game making misguided assumptions about the underlying engine... but then I see just as often:

Code: (javascript) [Select]
SetPersonLayer('roofus', 3);


A correct invocation.  And this kind of thing happens EVERYWHERE.  I'm beginning to think Keith had a weird sense of humor and did this kind of thing on purpose just because he could.
Title: Re: minisphere 1.1.4
Post by: DaVince on May 26, 2015, 02:16:15 pm
Considering how the code is full of jokes (like new retard()), that wouldn't surprise me. Then again, he also told me that he was shitty at coding. KR was the project that helped him learn, and he didn't fix old code. That really turns things into a mess.

And thanks a lot for the new release. ;D

Edit: yep, this game is pretty broken. After fixing a line of SetPersonLayer() and saving a PNG camouflaged as a BMP as an actual BMP, the game runs, but there are lots of problems. Can't enter most doors, can't talk to most people. I'm just impressed it's working this well besides those problems.
Title: Re: minisphere 1.1.4
Post by: Fat Cerberus on May 26, 2015, 03:04:57 pm
Did you notice the cleanup I did on the error screen?  The error location is now set off from the message, which should make it easier to see the location of an error at a glance. :)
Title: Re: minisphere 1.1.4
Post by: Fat Cerberus on May 27, 2015, 12:12:25 am

Edit: yep, this game is pretty broken. After fixing a line of SetPersonLayer() and saving a PNG camouflaged as a BMP as an actual BMP, the game runs, but there are lots of problems. Can't enter most doors, can't talk to most people. I'm just impressed it's working this well besides those problems.


Actually, on further testing... I think I broke something.  Person-person collision is screwy.  I definitely remember being blocked by those NPCs on my initial playtests, but now you can walk right through most of them...  which also means you can't talk to them because the engine does a collision check to find persons to talk to.

Edit: Ah ha!  I figured it out.  This is a long-standing engine bug that it took this horrendously buggy game to uncover.  I must have been mistaken about the collision working before, that was probably one of my Sphere 1.5 tests before I got minisphere to run the game.  Anyway, the bug is that minisphere doesn't normalize the spriteset base.  Sphere does, and it seems KR has several spritesets with degenerate bases where x1 > x2 and/or y1 > y2.  This causes the obstruction checks to fail.

It took me forever to figure this out because I was operating on the assumption this was a layering bug.  Not even close! :P

See, this is what's made minisphere what it is: no matter how broken my test game is, I work on the basis that, if it works properly in Sphere but not in minisphere, then the issue must be on my end (I was perhaps too hard on Blockman earlier, but regardless, this applied there as well).  I'm still very dedicated to compatibility. :)  Of course, there are two cases where I draw the line: I won't relax type checking for API arguments (you're calling into C code, the engine has every right to police it), and I won't emulate bugs.
Title: Re: minisphere 1.1.4
Post by: Radnen on May 27, 2015, 02:35:46 am
But if a bug means a game can be playable... It's a tricky situation. You want a clean version of Sphere with no bugs in it, but if you have to incorporate a bug to make a game work... it's not always straightforward isn't it? But then again I guess you could call those bugs "features". :P
Title: Re: minisphere 1.1.4
Post by: Fat Cerberus on May 27, 2015, 02:58:13 am
It can sometimes be a very fine line to walk, I won't deny that.  For example, the color-cycling trick in Sphere is based on what is technically a bug (namely: byte overflow in color components isn't checked for) and when it was brought to my attention I had to think long and hard whether to emulate it.  Ultimately I chose not to in the name of consistency (CreateColor can reasonably be considered "canon" and that clamps the values), which of course breaks compatibility.  However, it's a trivial enough thing to work around (you can do modulo arithmetic yourself), so I don't consider it a dealbreaker.

I guess this is the reason browsers have quirks modes...
Title: Re: minisphere 1.1.4
Post by: Fat Cerberus on May 27, 2015, 11:58:10 am
Hm, so it appears minisphere's handling of triggers is borked, which is why you can't enter buildings in KR.  Unfortunately this doesn't surprise me, that was one area I didn't do much in-house testing on.  My test map for Specs does include a trigger, but it's only one.  KR tends to cluster them together, and it seems the activation rectangle for individual triggers is so small for whatever reason that they often don't activate at all.

Edit: I did some runs through the debugger.  The issue is a weird race condition between KR's custom movement code (I have to give whoever programmed the movement system credit, they basically independently invented Lithonite) and an optimization in minisphere where I only check for trigger activation if the input person has moved since the last frame.  For whatever reason the person almost always reports as not moving.  I'm not 100% positive yet, but I THINK the root cause is that the game confuses the engine by constantly detaching and attaching input.
Title: Re: minisphere 1.1.4
Post by: Fat Cerberus on May 28, 2015, 01:37:39 am
Going to make a new post for this because I want it to be seen.  This was quite an interesting pursuit.

Got it!  I was right, KR detaching and reattaching input during custom movement throws it off.  Currently minisphere has an optimization (premature, as I now see) where it runs a trigger check if and only if two conditions are met: 1) There is an input person, and 2) that person has moved since the last frame.  In this case, when the engine runs the trigger check, no input is attached because the game reattaches it in a person script.  And that script runs on the frame AFTER all movement has ceased:

Code: (javascript) [Select]
QueuePersonCommand(thePC.name, COMMAND_MOVE_NORTH, false); // <-- is_immediate is false, suspends command execution until next frame
QueuePersonScript(thePC.name, "trigtest(); if (!Kbusy && !climbmode[0]) AttachInput(thePC.name); walking=false; ", false);


Note the trigtest(); in the reattachment script.  This would normally mitigate the issue, but the function is bugged.  Long story short, this game is very, VERY lucky to be playable at all, even in vanilla Sphere.  The ONLY reason it works in vanilla is because Sphere always walks the trigger list on every update, even if the input person is stationary.  It looks like I will have to do the same if I want to support this corner case.

So yes, this game is broken, but the fact that it works in the original engine makes it interesting: In many cases it's hanging on to its stability by a thread, so the smallest difference in engine behavior under the hood can break everything.  If ever there were a testcase to punish premature optimizations and incomplete reverse engineering, this is it. :P
Title: Re: minisphere 1.1.4
Post by: Radnen on May 28, 2015, 02:27:49 am
I'm  not sure trigger checks need this kind of optimization. I'd let it check as often as I want, after all it's hardly a bottleneck. The more I get away with in native, the better.

What I am interested in here is the reattachment of the player. When the input is not attached, triggers are not executable through the engine (I end up calling ExecuteTrigger() or somesuch). If the idea of the above is to trigger a trigger a frame before the input is attached I'm not sure how that goes. I guess it's the re-attachment of the player that suddenly executes the trigger because the check is indeed being made all the time, every frame. Once it sees the input is reattached, bam, it's triggered. I think that's kind of clever, really.
Title: Re: minisphere 1.1.4
Post by: Fat Cerberus on May 28, 2015, 02:34:39 am
Yeah, I'm not sure what the purpose of the trigtest() function is there, it's completely redundant as Sphere will run the trigger anyway post-attach.

And now that I think of it, I don't think it was an optimization after all: the same condition ("did the input person move?") covers zone processing as well.  And there it's 100% necessary, otherwise the zone script will keep firing even if the player stands still.
Title: Re: minisphere 1.1.4
Post by: DaVince on May 28, 2015, 06:22:27 am
Quote
So yes, this game is broken, but the fact that it works in the original engine makes it interesting: In many cases it's hanging on to its stability by a thread, so the smallest difference in engine behavior under the hood can break everything.

This actually explains perfectly why certain segments of the game started breaking randomly on later Sphere versions. For example, I remember the couch moving scene later on in the game sometimes working, sometimes not.

It'd probably be better to fix the game here rather than your code specifically, especially if it means performance regression for all other games. I mean, the game needed some fixes anyway.
Title: Re: minisphere 1.1.4
Post by: Fat Cerberus on May 28, 2015, 10:51:41 am

It'd probably be better to fix the game here rather than your code specifically, especially if it means performance regression for all other games. I mean, the game needed some fixes anyway.


In this particular case it's not a big deal, as you'd incur the performance hit, such as it is, of constant trigger checks anyway as long as the PC is moving (which is why I now suspect it wasn't an optimization at all, just an oversight).  The only speedup to be had from this is when the player is standing still, which truth be told, isn't very useful.

However, in the general case, I agree with the sentiment.  I'm not about to bend over backwards to get this game to run as-is, but if it should uncover what is clearly an engine bug, I do want to try to fix it. :)

Trivia: Technically my trigger implementation isn't fully compatible with Sphere's, as I found out last night when comparing the two engine sources.  Sphere tracks current trigger activation per-person, whereas minisphere only has a single "current trigger" variable.  What this means is that, in Sphere, if the PC steps on a trigger which causes input to be attached to another person, if the input is later returned to the original person, the trigger won't reactivate.  In minisphere it would because trigger activation is tracked globally.

Edit: Yeah, even with the trigger and zone fixes I just committed, there's no way this game is going to run in minisphere without some serious edits.  There's way too much of passing strings to APIs expecting numbers.  Regardless, it looks like I've fixed all of the actual bugs: The game looks like it would be playable if not for all the type errors.
Title: Re: minisphere 1.1.5
Post by: Fat Cerberus on May 28, 2015, 03:50:15 pm
Okay, v1.1.5 has been posted, and with it I've decided to declare minisphere 1.1 stable.  Most of the KR glitches are fixed by this release and outside of that my tests haven't uncovered any showstoppers, so I'm thinking it's time to retire v1.0.  The performance improvements in 1.1 alone are worth the upgrade.  I'll leave 1.0.11 in the downloads repo, but minisphere 1.0 should be considered no longer officially supported and won't receive any more fixes.

Go crazy!

(Note that I didn't bump the version to 1.2, as I was originally going to do for stable releases.  I decided it was an unnecessary formality.)
Title: Re: minisphere 1.1.5
Post by: mezzoEmrys on May 28, 2015, 05:50:52 pm
TechDemo_Lithonite2.0 works perfectly on engine.exe, but crashes engine64.exe after selecting to play it from startup. console64.exe informs me that it reaches "Initializing input" before the crash.

Edit: Just realized I can try to debug it with Visual Studio, which I actually forgot I had on here, because I've never really used it.
Anyway, it had this to say:
Unhandled exception at 0x000000013F997AB9 in console64.exe: 0xC0000005: Access violation reading location 0x0000000000000055.
Title: Re: minisphere 1.1.5
Post by: Fat Cerberus on May 28, 2015, 08:17:31 pm
It crashed at initializing input, interesting.  And this is the 64-bit engine... Hm.  I know that happens on XP, preventing the engine from being used there.  For some reason on some systems it likes to segfault when initializing the Allegro joystick routines, and there's nothing I can do because it's internal to Allegro.

There's no difference between engine and engine64 other than the latter is a native x64 binary and is theoretically faster as a result.  Functionality is the same, so you lose nothing. :)
Title: Re: minisphere 1.1.5
Post by: Fat Cerberus on May 29, 2015, 03:58:22 pm

TechDemo_Lithonite2.0 works perfectly on engine.exe, but crashes engine64.exe after selecting to play it from startup. console64.exe informs me that it reaches "Initializing input" before the crash.

Edit: Just realized I can try to debug it with Visual Studio, which I actually forgot I had on here, because I've never really used it.
Anyway, it had this to say:
Unhandled exception at 0x000000013F997AB9 in console64.exe: 0xC0000005: Access violation reading location 0x0000000000000055.


mezzo, could you redownload 1.1.5 and try engine64 again?  I just uploaded a hotfix that should fix the crash you're seeing.  In theory this should also allow the engine to run on XP...
Title: Re: minisphere 1.1.5
Post by: Flying Jester on May 29, 2015, 05:06:20 pm
...is a native x64 binary and is theoretically faster as a result...


Them's fightin' words! =P
Title: Re: minisphere 1.1.5
Post by: Fat Cerberus on May 29, 2015, 05:14:50 pm
Fighting words?  Why?
Title: Re: minisphere 1.1.5
Post by: Flying Jester on May 29, 2015, 05:52:04 pm
Because so many people disagree on it...
Title: Re: minisphere 1.1.5
Post by: mezzoEmrys on May 29, 2015, 05:54:02 pm

I just uploaded a hotfix that should fix the crash you're seeing.


Doesn't seem to work, the only difference seems to be that the error is occurring at 0x0[zeros]019 instead of 0x0[zeros]055, and as far as I know that could just be a memory shuffling thing.
Title: Re: minisphere 1.1.5
Post by: Fat Cerberus on May 29, 2015, 06:57:38 pm

Because so many people disagree on it...


Hence why I said "theoretically".  ;)
Title: Re: minisphere 1.1.5
Post by: Fat Cerberus on May 29, 2015, 07:04:11 pm


I just uploaded a hotfix that should fix the crash you're seeing.


Doesn't seem to work, the only difference seems to be that the error is occurring at 0x0[zeros]019 instead of 0x0[zeros]055, and as far as I know that could just be a memory shuffling thing.


Huh.  I know there was a bug I found in Allegro where if it fails to initialize XInput it will crash instead of falling back on DirectInput like it's supposed to.  Long story short, it initializes XInput and then doesn't check the return value from the init function.  I fixed it in my own copy of the Allegro source and recompiled, and it got past that step on my XP VM, so maybe I uploaded the wrong file...

Do you have the latest DX runtimes installed?  Contrary to what you'd think, even Win8.1 is missing parts of it out of the box.
Title: Re: minisphere 1.1.5
Post by: mezzoEmrys on May 29, 2015, 07:28:59 pm

Do you have the latest DX runtimes installed?


I think I do, I seem to have 11.1 based on what information I could find. I'm not sure what else I could do from there to ensure I have the latest I can for Win7.
Title: Re: minisphere 1.1.5
Post by: Fat Cerberus on May 29, 2015, 09:07:55 pm
Hm, there definitely shouldn't be any issues under Win7.  Oh well, you said the 32-bit engine (engine.exe) works fine, right?  I guess you'll have to use that.  Like I said, they are both compiled from the exact same code, so you won't lose any functionality.

Let me know of any other issues. :)
Title: Re: minisphere 1.1.5
Post by: Fat Cerberus on May 29, 2015, 11:25:09 pm
So it might not be too long before minisphere gets module support:
https://github.com/svaarala/duktape/issues/201

;D

ArrayBuffer support is also slated for the next release, which is awesome.
Title: Re: minisphere 1.1.5
Post by: Radnen on May 29, 2015, 11:34:05 pm
64bit version IS faster on my machine. :)
Title: Re: minisphere 1.1.5
Post by: Fat Cerberus on May 29, 2015, 11:47:07 pm

64bit version IS faster on my machine. :)


Good to know. :D
Title: Re: minisphere 1.1.6
Post by: Fat Cerberus on May 31, 2015, 01:30:20 am
So I was able to reproduce the crashes mezzoEmrys saw with the 64-bit engine.  Apparently Allegro doesn't appreciate being fully shut down and then reinitialized in the same session, which is what happens when ExecuteGame() is called.  At least for me, the crash doesn't always happen, only sometimes.  I will have to refactor the way ExecuteGame() works (I'll put it on the checklist for v1.2), but for now there shouldn't be any issues outside of startup games.  In general, actual games have no need to call ExecuteGame().

Anyway, minisphere 1.1.6 is up, and with the recent fixes it should now work in Windows XP. 8)  @Defiant, if you are still watching this topic, could you test it for me?
Title: Re: minisphere 1.1.6
Post by: Fat Cerberus on May 31, 2015, 03:09:29 am
I'm just a regular juggernaut with this project, aren't I?  I just implemented module support, slated for minisphere 1.2:
https://github.com/fatcerberus/minisphere/tree/module-support

I converted kh2Bar to a module to test it out and so far it's working as intended.  This is awesome!

At present minisphere loads modules from ~/modules (or failing that, ~#/modules i.e. relative to the engine "system" dir).  I was originally going to use ~/scripts/lib, but as I already used that as a preferred search path for RequireSystemScript, I figured a separate directory was the better option.  That'll make it easier if someone wants to code up a NuGet-style dependency manager, too.
Title: Re: minisphere 1.1.6
Post by: Fat Cerberus on May 31, 2015, 11:39:19 pm
So the more I play around with modules, the more I realize, they're not always a suitable replacement for old-fashioned RequireScript().  For one-off dependencies that are only used in maybe one or two places, e.g. kh2Bar, it makes sense to use a module, but for more pervasive dependencies (Link, miniRT...) I've found that a RequireScript() at the top of the main source file is much clearer than var whatever = require('whatever') (or worse, a bunch of inline require()s littered throughout the source which Pegasus seems to advocate).
Title: Re: minisphere 1.1.6
Post by: Flying Jester on June 01, 2015, 12:49:58 am

So the more I play around with modules, the more I realize, they're not always a suitable replacement for old-fashioned RequireScript().


This is particularly true with smaller libs. What we have right now is much more like a < script > tag, which for many things is more suitable. But we actually go a step further with RequireScript over EvaluateScript.
For something like my 1.5-style map engines, or (I'd suspect) your threader a module would be more suitable. But for my older MJ map engine, it would be silly.

That's kind of why I don't really care too much about module support. I don't really consider the namespacing to be too important, since it's pretty simple to do that yourself (and all modules I've ever seen already do), and we already handle a basic but quite effective form of dependency management.
Title: Re: minisphere 1.1.6
Post by: Fat Cerberus on June 01, 2015, 01:10:14 am
The thing I really love about RequireScript is that, besides providing built-in protection against multiple inclusion, it can also be used to enforce load order in complex libraries.  In miniRT, for instance, the very bottom of miniRT.js has this block:

Code: (javascript) [Select]
// now that everything is in order, we can pull in all the miniRT
// component scripts.
RequireSystemScript('mini/miniBGM.js');
RequireSystemScript('mini/miniConsole.js');
RequireSystemScript('mini/miniLink.js');
RequireSystemScript('mini/miniPact.js');
RequireSystemScript('mini/miniScenes.js');
RequireSystemScript('mini/miniThreads.js');


The components are listed in alphabetical order, however miniThreads actually has to be initialized first, because everything else in the runtime depends on it.  And it indeed does get initialized first because the individual component scripts also have a RequireScript for it, and therefore it gets its initializer registered with the runtime before any other component.  This kind of thing I found is very difficult to do with modules because of the focus on encapsulation.

Nonetheless, this was a trivial addition I could have done ages ago (it's built into Duktape, and even if not it could be polyfilled easily using RawFiles and eval), and implementing it now puts me in a very good position to start work on some form of Pegasus support.
Title: Re: minisphere 1.1.7
Post by: Fat Cerberus on June 01, 2015, 12:35:57 pm
@mezzoEmrys
Could you try the latest release (1.1.7)?  I'm pretty sure I fixed the crash on restart now.
Title: Re: minisphere 1.1.7
Post by: mezzoEmrys on June 01, 2015, 07:30:16 pm
The release download link seems to be not happening. I also have no idea how to build it myself, and I'm not sure I even have the compilers myself. I really need to get on that...
Title: Re: minisphere 1.1.7
Post by: Fat Cerberus on June 01, 2015, 07:40:37 pm
The download doesn't work?  Odd.

You only need VS 2013 to build it. All the dependencies including Allegro static libs are included in the repo.
Title: Re: minisphere 1.1.7
Post by: mezzoEmrys on June 01, 2015, 07:47:56 pm
Your link on the first post is just http://, no actual link body, at least not one that comes through to me.
Title: Re: minisphere 1.1.7
Post by: Fat Cerberus on June 01, 2015, 07:49:05 pm

Your link on the first post is just http://, no actual link body, at least not one that comes through to me.


Oops! :-[

https://docs.google.com/file/d/0BxPKLRqQOUSNX3pTNHU1Uk1tdm8/edit?usp=docslist_api
Title: Re: minisphere 1.1.7
Post by: Fat Cerberus on June 01, 2015, 08:06:29 pm
Okay, download link is fixed.

For future reference, the latest release is always available in the SphereDev download repository.  You know, in case I post a broken link again... :)
Title: Re: minisphere 1.1.7
Post by: mezzoEmrys on June 01, 2015, 08:42:54 pm
Huzzah! All works as expected. I tested both games this time, and everything seems to work as expected.
Title: Re: minisphere 1.1.8
Post by: Fat Cerberus on June 02, 2015, 12:59:07 am
minisphere 1.1.8 is up.  This fixes diagonal movement commands not working as well as the long-standing issue where animation for diagonally-moving persons was too fast due to double-queuing of COMMAND_ANIMATE.

Note that, as a result of the recent changes (the way COMMAND_ANIMATE is handled internally has changed), persons will now keep animating even if they run into something, a la early Pokemon.  Technically this is a bug, but it does have a certain charm to it, so I'm not actually sure I want to fix it. :)  What do you guys think?
Title: Re: minisphere 1.1.8
Post by: Radnen on June 02, 2015, 02:33:28 am

Technically this is a bug, but it does have a certain charm to it, so I'm not actually sure I want to fix it. :)  What do you guys think?


I say the animation is fine, I try to emulate the behavior in my games since I like it. I caution if it affects Lithonite or not.
Title: Re: minisphere 1.1.8
Post by: Fat Cerberus on June 02, 2015, 02:59:03 am
It doesn't seem to, looks like Lithonite still works normally.

Edit: Huh.  That's appropriate--look at my post count. :P  I almost don't want to ever post again now, it's just too perfect. ;D (1025 being 413 + 612 and the date of Cascade, the most epic thing to ever happen in Homestuck)
Title: Re: minisphere 1.1.8
Post by: DaVince on June 02, 2015, 07:32:57 am
Oh, I thought it was 1024, a nice power of 2, and you already posted again since then or something. :P

I haven't had the time to play with the new releases. Once vacation starts, you can bet your ass I'm making a game powered by minisphere though.

Also, do you happen to have documentation for any of the new functionality? Or should I just be checking the older thread posts for now?
Title: Re: minisphere 1.1.8
Post by: Fat Cerberus on June 02, 2015, 08:34:46 am
Check the documentation folder for minisphere-api.txt.  Most of the new stuff should be documented, it's the legacy functions I skimped out on (which you have the 1.5 doc for anyway).  I'm slowly filling those out too as I go along though.
Title: Re: minisphere 1.1.8
Post by: DaVince on June 02, 2015, 10:07:41 am
Okay, thanks a bunch. :)
Title: Re: minisphere 1.1.8
Post by: Fat Cerberus on June 03, 2015, 02:05:05 am
minisphere 1.2 development is officially underway. ;D  The latest commits add the following APIs for Zone management:



Three of these (AddZone, RemoveZone and SetZoneDimensions) look like they were planned for Sphere at some point and experimentally implemented, but were never exposed to script.  AddZone in particular has the entire function commented out in the source. ???  So seeing that, I figured "Why not?" and implemented them.

SetZoneScript was inspired by this thread:
http://forums.spheredev.org/index.php/topic,1194.0.html

And Get/SetZoneSteps were just low-hanging fruit. :P
Title: Re: minisphere 1.2b1 (stable: 1.1.8)
Post by: Fat Cerberus on June 03, 2015, 03:10:19 pm
The first minisphere 1.2 beta is available, go check it out!  This includes the new zone and trigger APIs mentioned above as well as CommonJS support. :)  Oh, and the API documentation has been fleshed out some more.
Title: Re: minisphere 1.2b1 (stable: 1.1.8)
Post by: Fat Cerberus on June 03, 2015, 11:28:09 pm
So out of curiosity, I ran the loop tests I discovered hidden in the Sphere-SFML test game source with all three current engines.  The results are attached as screenshots.

The cliffnotes version: Obviously SphereSFML won because Jurassic is awesome, however one thing shocked me: The huge divide between minisphere and Sphere 1.5.  I'll get to that in a minute, though.  Before I get started, my test rig is an AMD A10-6800K @ 4.1 GHz with 8GB RAM and running Windows 8.1 Pro x64.

As you can see in the screenshots, Sphere 1.5 averaged around 1300ms per test.  The only ones that were under 1000ms were the two that increment twice per iteration.  This pattern shows across all engines, though, so apparently the loop condition check is expensive?

SSFML 0.90: The best result by far was "For i++ in Step", which got 17.2ms(!).  Makes sense, that's the common case for a for loop, so Jurassic optimizes for it.  What's interesting, though, is that Jurassic falters when it hits the i += 1 tests.  If you're JITting, then i += 1 should compile to the same machine code as an increment, right?  But apparently it doesn't.  Weird.  Ignoring the outliers, SSFML averages ~50ms per test, and around 130ms if you include everything.  Very impressive.

Now we get to minisphere (1.2b1).  If this is any indication, Duktape is literally 3-4 times faster than SpiderMonkey 1.5.  I knew it was a highly optimized engine, but this still blew me away.  Here again, though, i += 1 is way slower than a postfix increment for no discernible reason.  It's only a 100ms difference though, so not really an outlier.  Average across all tests: ~385ms.

So the bottom line is, not only is minisphere leagues faster than Sphere 1.5, but it holds up well against a JITted engine as well.  And from what I hear, the Duktape dev is working on even more performance improvements, so that gap should narrow even further in the future.
Title: Re: minisphere 1.2b1 (stable: 1.1.8)
Post by: Radnen on June 04, 2015, 01:17:50 am
It's funny how an engine not necessarily built around speed still out-performs Sphere 1.5. I guess SpiderMonkey team really just focused on getting it to work, not even they focused on optimization.

Jurassic lacks static type JIT optimizations. If you are doing a for loop and it knows you are doing integer adds it should use increment. This was on the table of optimizations to be made but the author never got around to it. I thought the C# JIT would do optimizations for you if you can supply it the MSIL bytecode, but perhaps it comes down to what environment or context you give it and the author hadn't optimized for these cases.

That's raw speed for you though. I've since moved to a different test where I call into a function like CreateStringFromByteArray(), the performance varied greatly. When I ran that in a loop in SSFML it took 400ms to do what Sphere 1.5 did in 20ms. But I found out that there is a way to rewrite the way Jurassic notices the method bindings (rather than letting it guess the methods, you can tell it, which is much faster) and upon doing that to my code, I was able to get it down to 40ms. Sphere 1.6 did the test in 60ms so obviously things got even slower between bindings from 1.5 to 1.6. The for loop test was faster in 1.6, however, making the benchmark rather odd.

So I'd do a benchmark with raw JS (which is this) and JS->native calls like CreateColor() or CreateStringFromByteArray() and just see what they bring to the table. Because, Sphere code will make use of many Sphere API calls in loops and they all ought to run fast or otherwise I'd just do -*everything* in JS and only expose file and input I/O as well as a basic drawing API and have the map engine and everything else live in script to remove the native call overhead. I think for Jurassic this might be the fastest since everything's IL anyways. But it's just the optimizations that it'll lack.
Title: Re: minisphere 1.2b1 (stable: 1.1.8)
Post by: Fat Cerberus on June 04, 2015, 01:27:52 am
Yeah, obviously I knew this benchmark was useless for real-world performance testing, I was just interested in raw performance of the JS engines.  I'll definitely try adding some API calls to the mix at some point though.

I do want to do a JS map engine at some point though, perhaps for minisphere 2.0.  I'll keep the built-in default one in the engine, but I want to try my hand at writing a more OO map system, which JS is far better suited to than C.  Things like SetDefaultPersonScript might be more difficult with objects, though...
Title: Re: minisphere 1.2b1 (stable: 1.1.8)
Post by: Flying Jester on June 04, 2015, 03:37:07 am

So I'd do a benchmark with raw JS (which is this) and JS->native calls like CreateColor() or CreateStringFromByteArray() and just see what they bring to the table. Because, Sphere code will make use of many Sphere API calls in loops and they all ought to run fast or otherwise I'd just do -*everything* in JS and only expose file and input I/O as well as a basic drawing API and have the map engine and everything else live in script to remove the native call overhead. I think for Jurassic this might be the fastest since everything's IL anyways. But it's just the optimizations that it'll lack.


A huge advantage of newer SpiderMonkey is that it is quite capable of this, since it's the stance Mozilla takes with the web now. JavaScript for everything.


Yeah, obviously I knew this benchmark was useless for real-world performance testing, I was just interested in raw performance of the JS engines.  I'll definitely try adding some API calls to the mix at some point though.

I do want to do a JS map engine at some point though, perhaps for minisphere 2.0.  I'll keep the built-in default one in the engine, but I want to try my hand at writing a more OO map system, which JS is far better suited to than C.  Things like SetDefaultPersonScript might be more difficult with objects, though...


You could always check out how I did it. My map engine has fairly complete API coverage (mostly missing FollowPerson stuff), even if it isn't totally accurate, and it is fully object oriented.
Title: Re: minisphere 1.2b1 (stable: 1.1.8)
Post by: Fat Cerberus on June 04, 2015, 08:14:39 am
Yeah, I'll probably take a more in-depth look at the Turbo engine at some point.  I would want an object-oriented API though as well though, not just under-the-hood.  For the most part the 1.5 interface is perfectly serviceable, but there are places where it's... awkward.  Things like Get/SetPersonX/Y and whatnot.

I do have to caution you that the person spooling you do pre-MapEngine() isn't 100% compatible with Sphere's behavior and is likely to catch you off guard at some point.  I know it did for me on multiple occasions during development.  Sphere--and minisphere--actually create a concrete person object (not just metadata) when you call CreatePerson(), and non-transient persons survive a MapEngine cycle.  This latter behavior is where the spooling will break down, I think.
Title: Re: minisphere 1.2b1 (stable: 1.1.8)
Post by: Fat Cerberus on June 04, 2015, 05:05:08 pm
Word of advice: When stubbing things out  during development, particularly lesser-used functions, make sure the stub can't be mistaken for correct functionality. :P This is what I did with font.clone(), and it literally JUST got fixed today.  The stub I wrote for it simply incref'd the original font and returned that.  Since fonts are rarely cloned and the behavior is fairly close to what it's supposed to do, I ended up forgetting about it.  The only, ONLY reason it got fixed was because I was writing the documentation for the Font object and happened to notice it while reviewing the code.

Other bugs fixed today as a result of the review: font.setCharacterImage() not updating the font metrics, font.wordWrapString() not handling whitespace properly and causing crashes under rare circumstances (namely, small wrap widths), and better handling of long stretches of characters with no whitespace.
Title: Re: minisphere 1.2b1 (stable: 1.1.8)
Post by: Fat Cerberus on June 05, 2015, 01:33:52 am
New minisphere 1.2 feature: the Sphere object.  This is an alias for the JS global object and is similar to window in a browser, allowing you to create global variables from strict mode code as well as serving as an optional namespace for built-in APIs if you're so inclined:

Code: (javascript) [Select]
Sphere.isThisAwesome = true;

var key = Sphere.GetKey();

Sphere.FlipScreen();

// etc.
Title: Re: minisphere 1.2
Post by: Fat Cerberus on June 06, 2015, 01:51:10 am
minisphere 1.2 is up.  I've decided to quit with the betas from here on out and just release.  minisphere has been on such a rapid release cycle anyway and I've been very good about fixing bugs, so there's really nothing to gain from pre-releases for this project.

Anyway, 1.2's flagship feature is CommonJS support.  This means require(); now works in minisphere if anyone is so inclined to use it. :)  I've also bumped the reported API version to 2.0.  It's not Pegasus, but between Galileo, CommonJS modules and the object constructors introduced in 1.1, I feel the engine identifying as lowly Sphere 1.5 is a bit disingenuous at this point. :P
Title: Re: minisphere 1.2
Post by: Fat Cerberus on June 06, 2015, 10:23:53 pm
I just discovered a neat trick for determining the correct facing command for a corresponding movement:

Code: (javascript) [Select]
var faceCmd = moveCmd - COMMAND_MOVE_NORTH + COMMAND_FACE_NORTH;


Note that this only works in minisphere.  Sphere is missing the diagonal movement commands, so the values don't line up. :(


Title: Re: minisphere 1.2
Post by: FBnil on June 07, 2015, 08:50:37 am
Congrats on the new release. I took it for a spin. Impressive.
Using Linux with wine. I had Full screen issues, due to the keyboard not binding to the screen, had to alt+tab out and in again.
Very much interested in seeing zones working. (saw a post in march that is was enabled... but 1.2 does not have it?)

About the speed with S1.5. It was build with JS1.4 (or was it JS1.5?). I succesfully tested JS1.6, 1.7 and 1.8rc1 through the years (before that fateful day my laptop blew up) and JS wise, they were faster, and also allowed new JS functions, but did nothing to the FPS of games (unless you were not using the mapengine, but most did), while using up much more RAM. A the moment, the API of JS changed so much (see the releasenotes from JS31) that lots of interface calls have to be rewritten. As Spidermonkey gets up to par with V8, I expect more from it now. But am discouraged, as I am not even getting zlib compiled without errors. (switched to MSVC++2010, God knows where my bought DVD is... never got to use it). Any way, the easiest way was ripping JS from old Firefox distro's. Some required also a NS4 dll, next to JS32.dll and some of those builds were slower.

https://developer.mozilla.org/en-US/docs/Mozilla/Projects/SpiderMonkey/Releases/31

For now, I think spending time on testcases is much more fruitful. I can not even get zlib to compile at the moment...  (zlib\src\contrib\masmx86\inffas32.asm(649): error A2070: invalid instruction operands)... so that is... bad... of course, I got a new MSVC, and do not remember what I required to set up to get it all working again. If somebody can point me to a wiki that works...
Title: Re: minisphere 1.2
Post by: Fat Cerberus on June 07, 2015, 10:07:16 am
Zones definitely work.  The Lithonite tech demo is included with the engine and should be fully functional.  Literally nearly the entirety of the 1.5 API is implemented, the only thing that generally stops a game from working is the stricter argument checking (Boolean arguments aren't automatically coerced, etc).

Check minisphere-api.txt in the documentation folder for full documentation, including all the new stuff. ;D

Not sure what all that was about SpiderMonkey and zlib though.  I'm guessing you're trying to build Sphere 1.x?  Wrong thread for that. :P
Title: Re: minisphere 1.2
Post by: FBnil on June 07, 2015, 10:44:38 am
Somehow... I rechecked the version: 1.2 does contain 2 binaries: 64 bits and 32 bits. Can not run it on VM Windows XP SP3 (64bits is not executable, as expected. and the 32 bits abends with "minisphere was unable to create a display window"). On wine, the 32 bit runs. But zones do not work. Packaged binaries are from Jun  6 01:35

I also detected a problem with layers that move automatically: When next to a map border, the map does not move, but the sprite does, instead of staying in the center of the screen, while the map moves, it is the sprite that moves while reaching a border. In those cases, the layers moves away from the cursor keys, as if the map was still moving. (need a example game for that?)
Title: Re: minisphere 1.2
Post by: DaVince on June 07, 2015, 10:44:51 am
I have a suggestion: would you consider a "global install" version of Sphere? One where you'd put all the games in an App Data folder on Windows or in $HOME/.local/sphere (or $HOME/.sphere) on Linux, and the actual executable in Program Files and /usr/bin? That would be useful for a few reasons:

A) It allows Sphere to become available in package managers, which in turn would attract new users
B) You can just run the command "minisphere" from anywhere that way
C) You separate the binary from the data that can be changed (like the games folder), which means no write access problems

Thinking about it, this is mostly beneficial for Linux. Though point C benefits both Windows and Linux, and probably OS X too.

Quote
Using Linux with wine.

That begs the question... why? The native Linux version functions perfectly fine. :P
Also, good to see you back!
Title: Re: minisphere 1.2
Post by: Fat Cerberus on June 07, 2015, 10:47:16 am
I have no idea why zones aren't working for you, nil.  Did you try the Lithonite tech demo I included with the engine?  That is based heavily on zones obviously, and works fine on my end.

@DaVince: This is a good idea, I'll consider it for the next release. :)
Title: Re: minisphere 1.2
Post by: Fat Cerberus on June 07, 2015, 10:53:32 am
Oh, and yes, I'd like an example game for the layer thing because I have no idea what you're talking about :P.  I assume the zone thing you're doing is some edge case where my behavior differs from Sphere's as well, so I'd like to see a testcase for that too.  I just tested a few games with zones myself and they work fine, so your use case must be different.

Oh, and yes, it won't run in an XP VM, I tried.  I think it can't initialize OpenGL due to lack of hardware acceleration, so Allegro display creation fails.
Title: Re: minisphere 1.2
Post by: FBnil on June 07, 2015, 11:36:54 am

That begs the question... why? The native Linux version functions perfectly fine. :P

Because I was testing minisphere 1.2 (and the zip contains only a windows build?). I am a bit lost though, lots of reading/catching up to do in 1 year. And all interesting posts, so I can not skip along...

Thanks for the welcome back! Good to see you guys again! Hope you are all doing well.

I attached a fog demo. Just run up, and you see the fox moving too fast, then, behave normally once the sprite is centered.

Will try to get it on a windows 7 machine to test it there. For now, no luck getting zones running. Just in case, can you point me again to the binaries... just in case (I grabbed them from the first post, that was updated... but...)
Title: Re: minisphere 1.2
Post by: FBnil on June 07, 2015, 11:38:42 am

Did you try the Lithonite tech demo I included with the engine?

Of course, and also one I had lying around. All I can think of is that I grabbed the wrong zip.
Title: Re: minisphere 1.2
Post by: Fat Cerberus on June 07, 2015, 12:10:04 pm
minisphere 1.2 download link:
https://drive.google.com/drive/folders/0Bw-4UFVty4u1fjJ2RHNUTFNzMVp1WEFVOHlJaFk4STJPd1RMVmFLeGtDQWQ5SVlSSXhEWFk

I've made a few changes since the release in the Git repo, but none that affect the map engine.  So yeah, this is baffling.  I see what you mean about the layer thing though.  I copied the parallax logic pretty much as-is from Sphere 1.x (in my own coding style of course :) ), so I must have screwed something up there.  I'll look into it and fix it and post minisphere 1.2.1.
Title: Re: minisphere 1.2
Post by: Fat Cerberus on June 07, 2015, 12:52:29 pm
Okay, I diagnosed the parallax bug.  Sphere does camera correction before parallax, whereas minisphere currently does it after.  This messes up the offsets when parallax is involved.  I should have caught this in testing, but as not many Sphere games in the wild use parallax and my own tests involved a repeating map (so there are no edges), it didn't show up.

It should be easy enough to fix.  Thanks for the report!
Title: Re: minisphere 1.2
Post by: FBnil on June 07, 2015, 01:47:54 pm
Not only with parallax enabled, if we take sully chronicles, the palmtree leafs on the upperlayer go everywhere too.
Another bug is an offset with the collision box. See image.

I also attach TechDemo_Lithonite2.2 (it has a mirror demo to the topright of the screen, the rest is the same. It has a newer version of Lithonite, 2.2 with a few bugfixes)
Title: Re: minisphere 1.2
Post by: Fat Cerberus on June 07, 2015, 01:58:44 pm
Ah, so it's a regression in GetCurrentZone(), not zone handling specifically.  That used to work (Lithonite was one of my big compatibility targets during development, just so you know :D), but apparently now it doesn't.  Thanks, that screenshot was a huge help!  On my end it ended up reporting it as Zone 769 half the time, which of course broke the mirror demo with an "invalid layer index" error.  I'll look into it.

Do you happen to know where I can get Sully Chronicles?  I don't see it in the Spherical repository.  I'm assuming it has to do with the parallax too though, maybe not parallax specifically but autoscrolling, which is part of the same calculation.
Title: Re: minisphere 1.2
Post by: DaVince on June 07, 2015, 02:06:35 pm
I should still have Sully Chronicles on my computer. Should. Gimme a minute.

Quote
Because I was testing minisphere 1.2 (and the zip contains only a windows build?). I am a bit lost though, lots of reading/catching up to do in 1 year. And all interesting posts, so I can not skip along...

Ah, okay. Basically, you just get the code from Git and compile it yourself - the dependencies are very minimal (only need the Allegro dev libraries and libmng).
Title: Re: minisphere 1.2
Post by: DaVince on June 07, 2015, 02:29:28 pm
Sully is now available in the incomplete/demo games folder: https://drive.google.com/open?id=0Bw-4UFVty4u1UGhwY2dKMFdySlE&authuser=0
Note that this game is VERY incomplete.

I took the liberty to test it out a bit too, though in an older version (on Linux, haven't updated/compiled it in a while). The layers were all screwy, and the mod music isn't playing. Gonna recompile and see how it is with the latest.
(Edit: yep, same deal with latest)
Title: Re: minisphere 1.2
Post by: Fat Cerberus on June 07, 2015, 02:46:33 pm
Yep, I was right, it was the parallax.  For SC, for whatever reason the parallax flag is set on the Foreground layer, so minisphere treats it as a repeating layer, while the map itself is non-repeating.  Since the parallax code didn't do preemptive camera correction like Sphere does (I thought it would be enough to only correct the final offset), this caused parallax layers to scroll out of sync with the rest of the map.  If these had been repeating maps, everything would have been fine.

Both the GetCurrentZone() bug and this issue are now be fixed as of this commit:
https://github.com/fatcerberus/minisphere/commit/3a9498d6daeea5264ecceed17026714071ec2a79

Thanks for the bug reports guys, as always.  :) minisphere 1.2.1 will be up shortly, with both of these fixes included.
Title: Re: minisphere 1.2
Post by: DaVince on June 07, 2015, 02:49:36 pm
It's great to see a game that didn't work correctly only ten minutes ago work correctly now. :P Hope you've noticed the mod music not playing? Because it's not under Linux, for some reason.
Title: Re: minisphere 1.2
Post by: Fat Cerberus on June 07, 2015, 03:05:41 pm
minisphere 1.2.1 is up.  It fixes the bugs discussed above as well as a bug in font.wordWrapString() causing the last word in the text to be lost if it ends on a wrap boundary.
Title: Re: minisphere 1.2.1
Post by: Fat Cerberus on June 07, 2015, 03:24:23 pm
Hm, you're right about the mod music not playing.  I suspect another Allegro bug, I will look into it later after work.
Title: Re: minisphere 1.2
Post by: FBnil on June 07, 2015, 04:40:22 pm
Nice work, thanks!

Quote

Will try to get the git and compile it myself...

Forgot to mention: make sure you get the "unstable" 5.1 version of Allegro. ;)
Title: Re: minisphere 1.2.2
Post by: Fat Cerberus on June 08, 2015, 02:21:15 am
minisphere 1.2.2 is up, which fixes the BGM in Sully Chronicals.  I never bothered to implement map BGM, so that's why it broke.  Nothing to do with the MOD music at all, those work just fine. :)
Title: Re: minisphere 1.2.2
Post by: DaVince on June 08, 2015, 08:09:37 am
Nice work, thanks!

Quote

Will try to get the git and compile it myself...

Forgot to mention: make sure you get the "unstable" 5.1 version of Allegro. ;)
Title: Re: minisphere 1.2.2
Post by: DaVince on June 08, 2015, 09:38:22 am
So I decided to try to make my ancient Pokémon GoldenSky/SilverSea project compatible with minisphere. This was basically my first big project, and where I gained learned the bulk of my scripting experience. And you can tell - the code is a mess all over. :P

Along the way, I noticed a few interesting things:
I declared var Font, var WindowStyle, var Surface. Needless to say, this worked in the original Sphere but minisphere complained because the objects are in use. I got this error, which baffled me until I finally figured out what was going on:
Code: [Select]
JS Error: TypeError: invalid base value


After fixing those (and also converting the used MIDIs to Ogg files), I was pleasantly surprised to see it RequireScript() through my dozen other script without complaining whatsoever. Awesome.

However, now I've stumbled across another difference between Sphere and minisphere: GetKey() is not aware of KEY_CTRL. Either that, or GetKey() doesn't return key codes at all. This means you cannot get past the menus. I filed a bug report. :)
Title: Re: minisphere 1.2.2
Post by: Fat Cerberus on June 08, 2015, 10:11:25 am
Yeah, that "invalid base value" error from Duktape is the bane of my existence.  What it means, specifically, is that you're trying to access a property on a variable which is not object-coercible (only null or undefined, in practice). It could at least tell you the name of the variable you're trying to access (SpiderMonkey does), but instead all you get is a vague "invalid base value".  Nothing I can do, unfortunately.  I'll have to file an issue on the Duktape repo about it.
Title: Re: minisphere 1.2.2
Post by: Fat Cerberus on June 08, 2015, 11:30:21 am

I declared var Font, var WindowStyle, var Surface. Needless to say, this worked in the original Sphere but minisphere complained because the objects are in use.


I have no idea how that ever worked.  By definition when you do that you're overwriting (or at least shadowing) the prototype on the Font constructor, so everything should break.  Yet somehow in Sphere that works normally... very odd.
Title: Re: minisphere 1.2.2
Post by: DaVince on June 08, 2015, 11:58:04 am
Original Sphere never exposed any Font, etc. constructor to the scripting side of things, as far as I'm aware.

...Actually, since my code was crappy, the only thing I did with the Font variable in particular was this:
Code: [Select]
var Font;

Then I proceeded to never use it. So I doubt it had any bearing on the actual existence of var Font.
The others were used, however, and that made it crash. In minisphere, I mean. :P
Title: Re: minisphere 1.2.2
Post by: Fat Cerberus on June 08, 2015, 12:15:35 pm
Speaking of crappy code, I discovered another bug thanks to that "Crap RPG" you posted a while back: minisphere's text rendering didn't handle tabs properly.  It tried to render the tab character directly instead of inserting spaces and didn't even honor it as a word break for purposes of word-wrapping.  It was also fixed in short order. :)
Title: Re: minisphere 1.2.3
Post by: Fat Cerberus on June 10, 2015, 01:17:01 am
minisphere 1.2.3 is out, with a bunch of fixes for bugs found by DaVince.
Title: Re: minisphere 1.2.3
Post by: mezzoEmrys on June 10, 2015, 01:44:49 am
Lots of fairly important bugs fixed, too, especially (for my current project) the hidden layer for obstructions one. I had just settled for fully transparent tiles, now i can actually make them visible in the editor :D
Title: Re: minisphere 1.2.3
Post by: DaVince on June 10, 2015, 05:21:17 am
Nice work. I love how quickly you always manage to fix these. :D

mezzoEmrys: if you find any bugs, please report them? The layer bug could have been fixed earlier if you had filed a bug, I would say. Lord English is really doing a great job with fixing these. :)
Title: Re: minisphere 1.2.3
Post by: Fat Cerberus on June 10, 2015, 08:25:01 am
I just realized I may be able to fix the "invalid base value" issue when variables are declared overwriting Sphere constructors.  I don't actually have to--it's a very bad practice I don't like to condone, but Duktape's error message for it is so obtuse that working around it is actually preferable at this point.

The issue arises because minisphere stores internal metadata properties in the object prototypes.  So when you declare a variable named, say, Font and then call a function which works with Font objects (e.g. GetSystemFont), the engine tries to access the Font prototype (this is why there is no line number--the error happened on the native side), which fails the same as if you did this in script:

Code: (javascript) [Select]
var Font; var foo = Font.prototype;


To elaborate on that: the boundary between native and script in Duktape is very thin.  Duktape's bytecode interpreter internally calls many of the same functions its public API does.  That's the reason why half of the Duktape API is macros and a big reason it can be as fast as it is.

Luckily Duktape also has this thing called the "stash" where you can store JS objects out of band such that they won't be garbage collected but are not otherwise accessible from script.  I could keep the object prototypes in the stash so that, if Font.prototype itself became inaccessible, the engine could still access it internally through the stash.  This would be enough to stop the errors, I think.
Title: Re: minisphere 1.2.3
Post by: Legaia on June 10, 2015, 11:09:34 am
Hey guys, glad to see work being done on new versions of the Sphere engine. I haven't played around with it yet, but does minisphere have all the same built in functions as Sphere has? IE. Can I follow old sphere tutorials or is there a new wiki/tutorial area specific to MiniSphere?
Title: Re: minisphere 1.2.3
Post by: Fat Cerberus on June 10, 2015, 11:12:20 am
minisphere is for all intents and purposes fully compatible with Sphere 1.5.  There may be a few obscure functions missing and the type checking for function parameters is stricter, but other than that anything you can do in one is done the same in the other.

minisphere also has a ton of new functionality not present in Sphere--you will have to look at minisphere-api.txt to find out how to use the new stuff.
Title: Re: minisphere 1.2.3
Post by: Fat Cerberus on June 10, 2015, 01:45:24 pm

I just realized I may be able to fix the "invalid base value" issue when variables are declared overwriting Sphere constructors.  I don't actually have to--it's a very bad practice I don't like to condone, but Duktape's error message for it is so obtuse that working around it is actually preferable at this point.


And... it's fixed as of the latest master commit. ;D
Title: Re: minisphere 1.2.3
Post by: FBnil on June 10, 2015, 04:48:45 pm
continue: FBnil was trying to install from source MiniSphere on his brand new Debian8 upgrade.

Ok, got it running.

Debian installs Allegro in /usr/lib/x86_64-linux-gnu/ and those were 5.0.10 and overruled the 5.1.10, so after a
Code: [Select]
apt-get remove liballegro5.0:amd64
it finally compiled! Checking the fog demo... nice work! However, still buggy. You see, the fog layer also needs to stay in sych with the background layer, so if I move, it is not scrolling in respect of the player, but of the other background.
So starting the fogdemo, when I move left/right, the fog seems to be following the player, instead of following the ground.

MiniSphere Source is clean and understandable. Still need to peruse it to commit an index map into memory. I like what I have seen so far! Kudo's Bruce!

I am impressed with duktape. At under 3Mb uncompressed source, compared to the 20Mb bz2 compressed tarball from spidermonkey.

edit: Also, duktape has been updated: 2015-06-02   duktape-1.2.2.tar.xz   maintenance release (http://duktape.org/download.html)

1.2.2 (2015-06-02)

    Fix harmless MSVC warnings when using DUK_OPT_FASTINT on x86 (GH-172)
    Fix compile error from array fast path when using low memory options (GH-174)
    Fix harmless MSVC warnings for size_t casts on x64 (GH-177)
    Fix potential NULL pointer dereference in duk_is_dynamic_buffer() and duk_is_fixed_buffer() when index is outside of value stack (GH-206)


Oh noes! No ColorMatrix objects!
Title: Re: minisphere 1.2.3
Post by: mezzoEmrys on June 10, 2015, 05:46:47 pm

The layer bug could have been fixed earlier if you had filed a bug, I would say.


To be honest, I didn't realize it was a bug at first, I thought it seemed intuitive enough that it did that. Didn't even think to check it on 1.5, since I was writing a game from scratch targeted at minisphere anyway. It wasn't until I saw your issue that I thought to check it.
Title: Re: minisphere 1.2.3
Post by: Fat Cerberus on June 10, 2015, 05:54:12 pm
 @FBnil
I'm pretty sure minisphere should render the fog the same as Sphere 1.5.  At least it looked that way in my tests.  Are you sure you have the latest master from GitHub?  I'm also already using Duktape 1.2.2.  If the copy in your source is older, you have an outdated minisphere build.

As for ColorMatrix objects, I'll add those to the list for the upcoming 1.3 release.  I knew I was missing something!
Title: Re: minisphere 1.2.3
Post by: DaVince on June 10, 2015, 07:12:22 pm
I haven't been as excited about Sphere in general as I am now. Getting back into the swing of things. Once vacation starts, I'm going to enjoy figuring out those new functions and making a game!
Title: Re: minisphere 1.2.3
Post by: Radnen on June 10, 2015, 10:56:55 pm
What are we doing wrong with OpenGL? I knew there's something messed up about how we are implementing OpenGL, because if you think about it, it can be used to display vast fully-realized high fidelity 3D scenes in 60fps, but we can barely make it all of our engines run more than 20000+ 2D entities on screen at the same time, quickly.

Take for instance this stupid WebGL test, (it's by no mean 'stupid'): http://www.goodboydigital.com/pixijs/bunnymark/

I can render 200000 - two hundred thousand - dancing bunnies and still got 60fps out of the rendering window!! If there are 4 vertex points per object, then we have 800000 verticies, which is still less than a typical 3D scene has on screen. A good PC can handle billions of vertices per second. But, let's say your computer can handle 1 billion verts on screen per second, that makes 800000 verts take only .0008s or .8ms, plenty of room to handle 16.67ms of time per frame. So of course this runs at 60fps. I'm just shocked we can't get this performance out of our native engines. Is Chrome's V8 coupled with WebGL really that damn fast?

I'm doing everything in the book right with my SphereSFML. I'm sending 1 batch of vertices to the pipeline, with a single base texture (atlas, sprite batch, etc.) and I can't get anywhere close to 60000 at 60fps, let alone 200000! And I'm doing some basic logic rather than just dead, simple images (I'm rotate blitting them).
Title: Re: minisphere 1.2.3
Post by: Fat Cerberus on June 10, 2015, 11:33:35 pm
I tested the bunny thing, I got to about 20,000 bunnies before the framerate started dropping off, and it actually started to hiccup before that, around 10,000.  Of course this is with the iGPU in my AMD A10-6800K, so I'm sure I could get more bunnies with an actual graphics card.  Full disclosure: Firefox.
Title: Re: minisphere 1.2.3
Post by: Fat Cerberus on June 10, 2015, 11:36:07 pm

Oh noes! No ColorMatrix objects!


See here:
https://github.com/fatcerberus/minisphere/commit/a14d2b2bd0c6c2648634b141587cc91c5178d93a

Everything is now implemented except for surface.applyColorFX4() because I haven't figured out how to bilinear-interpolate the matrices yet.  I'll have to look at the Sphere 1.6 source again.

Edit: Holy crud, ApplyColorFX4() is a beast of a function, I have no clue what it's even doing!  It does some crazy interpolation not only on the matrices, but on the pixels themselves.  applyColorFX() was easy, but this... well, remember how I said I wouldn't use code I don't understand?  Yeah, this is a perfect example. :P  I will have to study it a bit more, I'm not just going to paste it in.
Title: Re: minisphere 1.2.3
Post by: Radnen on June 11, 2015, 12:48:57 am

I tested the bunny thing, I got to about 20,000 bunnies before the framerate started dropping off, and it actually started to hiccup before that, around 10,000.  Of course this is with the iGPU in my AMD A10-6800K, so I'm sure I could get more bunnies with an actual graphics card.  Full disclosure: Firefox.


On chrome I got 200000(60fps), on Firefox I get 200000(50fps). I notice the test dips more under Firefox, meaning Chromes V8 is indeed faster in a real example or they have a more optimized WebGL context(?). I have a really nice Nvidia GPU, the GTX970 which didn't cost me a whole lot compared to the 980 or the 980ti (which is an inane amt of cash for such little more power1).

It's just weird, that's all. It might be the overhead, and I think it's the Sphere API calls. I think web has a better, leaner link between the OpenGL and the JS.

1. http://www.newegg.com/Product/Productcompare.aspx?Submit=ENE&N=100007709%20600536049&IsNodeId=1&bop=And&CompareItemList=48%7C14-487-087%5E14-487-087-TS%2C14-487-142%5E14-487-142-TS%2C14-487-088%5E14-487-088-TS&percm=14-487-088%3A%24%24%24%24%24%24%24
Title: Re: minisphere 1.2.3
Post by: Fat Cerberus on June 11, 2015, 12:53:18 am
The Sphere API is probably it.  A JS function call is much, much more expensive than a native call no matter how you slice it, for a lot of reasons.  arguments object creation is a big one - this document from the Duktape repo was very enlightening and an interesting read:
https://github.com/svaarala/duktape/blob/master/doc/arguments-object.rst
Title: Re: minisphere 1.2.4
Post by: Fat Cerberus on June 11, 2015, 12:56:25 am
I decided the "invalid base value" fix was too important to hold it back until 1.3 and backported it.  So, well... minisphere 1.2.4 is available for download. :)
Title: Re: minisphere 1.2.4
Post by: FBnil on June 11, 2015, 04:30:28 am
Thanks L.E. did a git pull. Now my techdemo complains that the code is not "strict" enough (back to that then, make all my libs compatible with MS).
And thanks for looking at those ApplyColorFX4() is useful though, as a crud way to emulate lights and shadow.
I do remember there was an explanation for it somewhere. Do you even sleep? I sleep and there are so many messages.

Meanwhile, I used tcc to compile some of the examples of duktape. Then compress them with upx. tcc has its limitations, gcc -os (compile and make the smallest size) is still way better at making smaller files.

"Drunken Wee master" needs BezierCurve .... was that even a function? ... yes... yes it was...
"surface.bezierCurve(c,step,x1,y1,x2,y2,x3,y3,x4,y4) ". I do not even remember these functions...


@Radnen: Maybe you create and destroy object calls each loop? Maybe you require a table where you keep them alive each loop?

@DaVince: Yay! new game from DaVince comming up!
Title: Re: minisphere 1.2.4
Post by: Fat Cerberus on June 11, 2015, 06:28:14 am
I have... odd sleep patterns.  And rest assured applyColorFX4() is getting implemented.  I figured it out once I started reimplementing it what it was doing, it's simple bilinear interpolation on the individual cells of the 4 matrices.  The way the code is written in Sphere 1.x doesn't make that obvious though.  Needless to say, my version will be much better annotated. :D

Not sure what that "not strict enough" thing is about... Sounds weird.

Bézier curves might be more difficult though.  The thing is, I don't really understand the math behind them and Allegro doesn't (to my knowledge) have a function built in to draw them.

Edit: As of about 5 minutes ago, applyColorFX4() is implemented.  I'm thinking my implementation may not be the fastest thing ever, Sphere does some weird thing with bitshifts that I don't quite understand, and I use fmin/fmax to clamp the pixels, which is probably a massive performance hit (doing int->float->int several times for every pixel has to take a toll).  The base code should be very easy to follow though:
https://github.com/fatcerberus/minisphere/blob/1fe34c2d603a5c49613db212c53ca8a1d3e2ccb7/src/image.c#L318-L381
Title: Re: minisphere 1.2.4
Post by: DaVince on June 11, 2015, 08:15:38 am
The BunnyMark only gets me as far as ~35000 bunnies before the FPS starts dropping, but then again I'm on a notebook with an NVIDIA GT540m and a 2Ghz Sandy Bridge CPU, so not exactly the most exciting thing.
For me, as long as games perform well, I'm happy, and in that regard minisphere is doing a lot better than original Sphere. (There is a level in Sir Boingers that starts lagging out once I add only a few more cupcakes; minisphere uses about 50% on a single thread at that point and 17% more on another.)

Quote
@DaVince: Yay! new game from DaVince comming up!

Whoa. I'm humbled. :> Now how about you make one again too? I liked your old games and demos. :)
Title: Re: minisphere 1.2.3
Post by: Flying Jester on June 11, 2015, 11:43:39 am

What are we doing wrong with OpenGL? I knew there's something messed up about how we are implementing OpenGL, because if you think about it, it can be used to display vast fully-realized high fidelity 3D scenes in 60fps, but we can barely make it all of our engines run more than 20000+ 2D entities on screen at the same time, quickly.


Three really important things I know I don't do are instancing, geometry/compute shaders (or Cuda/CG interop), and LOD.

Either way, TurboSphere can push 50,000 shapes and stay at 60(ish) FPS (So still more efficient than the BunnyMark on my machine). More or less vertices, depending on how they are divided between shapes and groups. I would highly suspect that's because I use OpenGL 4, which means that the single Group.draw() call to draw all those shapes results in only a fraction that many OpenGL calls. This is why the Galileo API is the way it is. It stops you from needing thousands of calls for thousands of sprites. That's also why I dropped the old API altogether. It's really not how OpenGL or D3D or any modern rendering technology works, and it shows.

But we will always be slower than dedicated 3D engines. They will always have specific functions built in, which the engine can be optimized for at the cost of flexibility. I'm more content to lose a little performance be be generally useful :)
Title: Re: minisphere 1.2.4
Post by: Fat Cerberus on June 11, 2015, 12:45:21 pm
I just added ByteArray inflate/deflate support:
https://github.com/fatcerberus/minisphere/commit/40063460804b7834b18b0e71099fab44184f7310

Used like:
var little = bytearray.deflate([level]);
var big = bytearray.inflate();

Honestly though, I'm not sure how useful this is in a game engine - I only added it because 1) Sphere 1.6 has it and 2) I already had a zlib dependency thanks to libmng, so may as well use it.
Title: Re: minisphere 1.2.4
Post by: Flying Jester on June 11, 2015, 01:35:30 pm
It would be useful saving data or sending data across a network.

zlib is so fast and so common that there's not really a good reason not to use it when sending or saving more than a few kilobytes of data.

You also pulled in zlib once you supported png.
Title: Re: minisphere 1.2.4
Post by: FBnil on June 11, 2015, 05:01:08 pm
Works perfectly:
Code: [Select]
function game(){
var originaltext = "Hello Sphere Worlds!";
var source = CreateByteArrayFromString( originaltext );

var compressed = DeflateByteArray( source , 9); // Sphere Syntax
//var compressed = source.deflate(9); // MiniSphere Syntax

if( compressed !== null ){
var inflated = InflateByteArray(compressed, 1024*16); // Sphere Syntax
//var inflated = compressed.inflate(); // MiniSphere Syntax
if(inflated !== null){
var copy = CreateStringFromByteArray(inflated);
if(copy === originaltext)
  Abort( "SUCCES:" + CreateStringFromByteArray(inflated) );
else
  Abort("ByteArray to string failed");
 
}else{
Abort( "Decompression failed." );
}
}else{
Abort("Compression failed.")
}
}

// MiniSphere to Sphere syntax

function DeflateByteArray(BA_obj,ratio){
  return BA_obj.deflate(ratio);
}

function InflateByteArray(BA_obj,size){
  return BA_obj.inflate(size); // need size or we can make a inflate bomb?
}


edit: A deflate bomb is possible:  http://security.stackexchange.com/questions/51071/zlib-deflate-decompression-bomb
Title: Re: minisphere 1.2.4
Post by: Fat Cerberus on June 11, 2015, 05:03:59 pm

You also pulled in zlib once you supported png.


In theory, yes.  In practice no because Allegro uses GDIplus to load images on Windows.  Nonetheless, I did pull it in with libmng, so your point stands. :)
Title: Re: minisphere 1.2.4
Post by: Fat Cerberus on June 11, 2015, 05:05:14 pm

Works perfectly:
Code: [Select]
function game(){
var originaltext = "Hello Sphere Worlds!";
var source = CreateByteArrayFromString( originaltext );

var compressed = DeflateByteArray( source , 9); // Sphere Syntax
//var compressed = source.deflate(9); // MiniSphere Syntax

if( compressed !== null ){
var inflated = InflateByteArray(compressed, 1024*16); // Sphere Syntax
//var inflated = compressed.inflate(); // MiniSphere Syntax
if(inflated !== null){
var copy = CreateStringFromByteArray(inflated);
if(copy === originaltext)
  Abort( "SUCCES:" + CreateStringFromByteArray(inflated) );
else
  Abort("ByteArray to string failed");
 
}else{
Abort( "Decompression failed." );
}
}else{
Abort("Compression failed.")
}
}

// MiniSphere to Sphere syntax

function DeflateByteArray(BA_obj,ratio){
  return BA_obj.deflate(ratio);
}

function InflateByteArray(BA_obj,size){
  return BA_obj.inflate(size); // need size or we can make a inflate bomb?
}



You don't even need the shims with the latest commit, I added the Sphere compatible functions.  :)

Could you also test the ColorMatrix support?
Title: Re: minisphere 1.2.4
Post by: FBnil on June 11, 2015, 05:18:30 pm
sure thing, will work on it over the weekend.
Title: Re: minisphere 1.2.4
Post by: Fat Cerberus on June 11, 2015, 05:22:31 pm
One potential pitfall: minisphere will throw if an inflate/deflate fails, apparently Sphere returns null instead?

Good point on the potential for inflate bombs though, I'll add an optional size parameter when I get a chance.
Title: Re: minisphere 1.2.4
Post by: DaVince on June 11, 2015, 05:50:48 pm
Didn't original Sphere never throw exceptions because implementing exceptions was a difficult mess, or am I wrong on that? Even if it did though, it'd be pretty inconsistent with everything else. I've never seen try..catch in Sphere...
Title: Re: minisphere 1.2.4
Post by: Flying Jester on June 11, 2015, 05:57:45 pm

Didn't original Sphere never throw exceptions because implementing exceptions was a difficult mess, or am I wrong on that? Even if it did though, it'd be pretty inconsistent with everything else. I've never seen try..catch in Sphere...


I thought it did? For instance, you could try...catch a LoadImage in case the image didn't exist?

Canonical Sphere scripts certainly don't use exceptions much at all, either way.
Title: Re: minisphere 1.2.4
Post by: Fat Cerberus on June 11, 2015, 06:03:42 pm
Yeah, LoadImage et al will throw on error.  sphere APIs that return null on failure are in the minority I think.
Title: Re: minisphere 1.2.4
Post by: DaVince on June 11, 2015, 06:13:55 pm
Huh. Well, how about that. I was certain there was a whole issue around this, but guess not.

...And here I have this whole script/function dedicated to loading resources and doing its best determining whether a resource exists or not and providing placeholders for years... Time to update that script to make use of it, I suppose.
Title: Re: minisphere 1.2.4
Post by: Flying Jester on June 11, 2015, 06:18:34 pm
I'm 99% certain that anytime you get the black screen + white text that blames a SS_* function, you could have used a try...catch on it :)

Just for some reason, none of us ever did that...
Title: Re: minisphere 1.2.4
Post by: Fat Cerberus on June 11, 2015, 06:39:52 pm
On that note, the minisphere error screen is so much nicer looking than the Sphere 1.5 one.  Just have to toot my own horn a little... ;)
Title: Re: minisphere 1.2.4
Post by: Flying Jester on June 11, 2015, 06:40:53 pm

On that note, the minisphere error screen is so much nicer looking than the Sphere 1.5 one.  Just have to toot my own horn a little... ;)


But can you select the text on the error screen?

You can select the text in TurboSphere's error screen :)
Title: Re: minisphere 1.2.4
Post by: Fat Cerberus on June 11, 2015, 06:41:56 pm
I wanted to do something like that, but as Allegro has no clipboard routines...
Title: Re: minisphere 1.2.4
Post by: Flying Jester on June 11, 2015, 06:51:08 pm
The way I did it was first using SDL's dialog methods, and then later a little platform-specific code to make dialogs for X11, OS X, and Win32.
Title: Re: minisphere 1.2.4
Post by: DaVince on June 11, 2015, 07:15:13 pm
I think that if you do implement error message copying, you could get away with simply copying the message to the clipboard once you click the screen.
But then again, the errors output to the terminal too, so how necessary is it really? Well, useful for reporting the errors, I suppose. :P
Title: Re: minisphere 1.2.3
Post by: Radnen on June 11, 2015, 08:08:55 pm
This is why the Galileo API is the way it is. It stops you from needing thousands of calls for thousands of sprites. That's also why I dropped the old API altogether. It's really not how OpenGL or D3D or any modern rendering technology works, and it shows.

But we will always be slower than dedicated 3D engines. They will always have specific functions built in, which the engine can be optimized for at the cost of flexibility. I'm more content to lose a little performance be be generally useful :)


I think you're right about the API. Sphere's immediate drawing routines are the issue here, even if you do creative batching like in SphereSFML. There are newer tricks that are easier to use had Sphere's API been different, which is the case for Galileo.
Title: Re: minisphere 1.2.4
Post by: Fat Cerberus on June 12, 2015, 12:48:05 am
Agreed.  However I won't drop the legacy routines as they serve as a convenient stepping stone.  Don't underestimate the value of having a fully Sphere-compatible engine.  It makes porting painless, so then you get access to all the nifty new features (like Galileo!) pretty much for free.  And then eventually you do start using them, and before long you wonder how you ever lived without the neat new additions. ;D

Basically minisphere is set up to let you learn new ways of doing things at your own pace rather than being forced into it, which from my own past experience I can say tends to make you resent "the new way".  Better to be able to ease your way into things than being thrown to the wolves.

That said, while the legacy primitives are included in the engine, I deliberately didn't document them for precisely the reason Jester mentioned.  They are available for backwards compatibility and easy porting, but for all intents and purposes they should be considered deprecated at this point.
Title: Re: minisphere 1.2.4
Post by: Fat Cerberus on June 12, 2015, 01:19:53 am

edit: A deflate bomb is possible:  http://security.stackexchange.com/questions/51071/zlib-deflate-decompression-bomb


Today I added an optional max_size parameter to bytearray.inflate() and InflateByteArray(), to defend against inflation bombs.  I left the default dynamic allocation behavior in for when a max size isn't provided however, as that may sometimes be preferable for trusted data, such as local save files.  Any inflation of data coming over a socket should definitely include a max size clause, though, I totally agree with that.

minisphere 1.3 is nearing release, I just want to do some updates to miniRT and then it should be good to go.  Unless I decide to add more features, I swear there was another new feature idea I had but now I've forgotten it...
Title: Re: minisphere 1.2.4
Post by: FBnil on June 12, 2015, 04:25:11 am
I had to create a shell function "gup", to update my git each time... man... chose changes are pumping through faster than I can make testcases.
Title: Re: minisphere 1.2.4
Post by: Fat Cerberus on June 12, 2015, 09:08:15 am
Yeah, nobody who saw this engine would believe it was one guy who put it together in 3 months, huh?  Nonetheless... ;D

I started development towards the end of January, minisphere 1.0 was released mid-to-late April.

It's funny, I'm generally bad at finishing projects I start, but minisphere... I don't know, it's been very easy for me to keep the wheels of development turning with this project for some reason.  Which is a good thing of course, I just don't understand it. :P

Title: Re: minisphere 1.2.4
Post by: Fat Cerberus on June 12, 2015, 11:49:07 am
I remembered the feature I wanted to add: SPK support!  I always aim to have at least one killer new feature for each version bump, so 1.3's will be archives.  For game packages I want to support, at the very least, SPK and ZIP.  To do this, there's apparently a zlib-licensed library called "PhysicsFS" that will let me access files directly from archives:

http://icculus.org/physfs/
Title: Re: minisphere 1.2.4
Post by: DaVince on June 12, 2015, 01:23:38 pm
Awesome! I have some ideas for redistributable games in that regard:

- Obviously, direct filetype association with spk files would be nice. Double-click the SPK, play the game.
- Renaming the zips with a different extension (like .spk2 or .spherezip or something). This makes filetype association easier for Sphere zips. (Compare to .cbz "comic book zip" files, which are just archives filled with pictures)
- The game launcher detecting these packages if you put them in games/, of course. :)

And some more special ideas:
- If you distribute just the engine binary + an spk file, it'll pick up on the spk file so you don't even need a games or startup folder, it'll just open that when you start the engine.
- The ability to load multiple spk/zip files. Could be useful for loading the game and then loading extra resources on top of it (like a mod, a levelpack, etc.)
Title: Re: minisphere 1.2.4
Post by: Fat Cerberus on June 12, 2015, 01:57:43 pm
Since minisphere reports as Sphere 2.0 now, we can definitely make an .spk2 format.  I think we'd have to standardize on an archive format though.  Zip seems the best option, as it can be supported easily enough with just zlib, regardless of what minisphere ends up using to support it.  Plus it seems to be what most compressed formats go with.  OpenDocument and Office 2007+ docx files are just relabeled zips, for example.

7z would of course compress better, but would hinder performance as decompression can be slow, especially if solid compression is used.  Ideally I'd want a format with decent compression but without sacrificing too much random access performance.  A non-solid deflate-based format like zip fits the bill, I'd think.

Where things get hairy is handling write access.  RawFile is the biggest issue here--the same API is used to open a file for either reading or writing, but you can't really write to a package at runtime.  It might be necessary for me to step back and look at refactoring the asset management first, before baking in package support.

I would also have to make sure running a game from a package is transparent.  This is an issue I know Sphere has had: some things just don't work when running games from an SPK.  It's a big reason I gave up on packaging games back when I was using 1.5.  Which is a shame, because being able to distribute a single .spk for your game is nice for when the person on the other end may not really know what to do with a zip file.

You know, I'm actually beginning to wonder if the FS sandbox imposed by the original engine wasn't deliberate, but just a necessary evil of supporting packages.  Not to say you can't dispense with the sandbox by using fallback clauses, but for consistency's sake Chad Austin might have decided to just sandbox always, regardless of the packaging method or lack thereof.
Title: Re: minisphere 1.2.4
Post by: Flying Jester on June 12, 2015, 02:36:36 pm

Since minisphere reports as Sphere 2.0 now, we can definitely make an .spk2 format.  I think we'd have to standardize on an archive format though.  Zip seems the best option, as it can be supported easily enough with just zlib, regardless of what minisphere ends up using to support it.  Plus it seems to be what most compressed formats go with.  OpenDocument and Office 2007+ docx files are just relabeled zips, for example.

7z would of course compress better, but would hinder performance as decompression can be slow, especially if solid compression is used.  Ideally I'd want a format with decent compression but without sacrificing too much random access performance.  A non-solid deflate-based format like zip fits the bill, I'd think.


I believe that a combination of tar or cpio and zlib or xz is the best. tar and cpio provide the same strengths, but are far simpler.
The reason I never got around to fully supporting spk's was that writing to a file from a game that is running from one is very complicated, as you mention. I finally said enough, and gave up on packages, since at that point the benefits seemed very small for the amount of complexity they introduced.

My final plan is to just unpack the package to some local directory and run the game there. If it looks like I've done that before, I merge the existing directory with what I unpack, favoring existing content. This bypasses many of the issues associated with packages, at the expense of having both a packaged and unpackaged game on the local disk at once.
Title: Re: minisphere 1.2.4
Post by: Fat Cerberus on June 13, 2015, 01:51:46 am
In the interest of making package support as painless to implement as possible, I've decided it would be best to standardize on a file system.  I call my initiative SphereFS, and it'll be a key pillar of the Sphere 2.0 API.  More details forthcoming, but suffice to say it will be backwards compatible with the Sphere 1.x sandbox but would allow, e.g. absolute paths via an escape.

SphereFS support will have its own extension designation in minisphere, sphere-spherefs.  Once I've fleshed things out some more, I will post a new thread in the Engine Development forum.

where doing it man
where MAKING THIS HAPEN
Title: Re: minisphere 1.2.4
Post by: N E O on June 13, 2015, 11:55:25 pm
Re Bezier curves - Fortunately for you I understand the maths and once wrote a script to use in Sphere. It's in the Wayback of the old wiki somewhere. I also C++-ed it for my hello-phoenix project (https://github.com/apollolux/hello-phoenix/blob/master/hello/ncurve.hpp) on my GitHub. The de Casteljau curve algorithm is essentially a divide-and-conquer one, but you may also need to limit the recursion depth if you don't check for point distance (NCurve in hello-phoenix does both, but I think the JS version only tests point distance).

Re spk/zip - If you choose to implement reading of renamed zip files as the next generation of spk and you want to keep a three-character extension, I recommend spz. If it's renamed 7z, sp7.

Re SphereFS - Feel free to make a "Future of Sphere" post for it, maybe including spitballing sphere:// or sph:// protocol handling or something too for a bit farther into the future.
edit: seems you already posted, I didn't finish catching up +neo
Title: Re: minisphere 1.2.4
Post by: Fat Cerberus on June 14, 2015, 03:29:33 am
Ugh, the package support wasn't even the most painful part of the SphereFS implementation, it's the abstraction that's the killer.  The whole engine was written with the assumption files will exist on the local FS, forcing me to not only have to implement custom sfs_fopen() etc. but even things like GetFileList() ended up getting broken.

The biggest issue though is loading images and such through Allegro.  If it weren't for Allegro's memfile add on (file-mapped memory!), a clean abstraction wouldn't even be possible--I'd have to resort to temp files.
Title: Re: minisphere 1.2.4
Post by: Fat Cerberus on June 14, 2015, 11:25:45 am
...nonetheless, I finally got it up and running this morning. :) A few things, like MNG loading, are still broken, but for the most part the engine is back in working order and will run a game from either a local folder or an SPK.

SPK is implemented by an spk_fopen() function which unpacks the requested file into memory and an emulated spk_fread() etc. which operate on the buffer.  This avoids a potentially lengthy unpacking step on startup without sacrificing too much performance, as memory is fast so the only additional overhead over straight disk access is the inflate step.

The end result is that the rest of the engine doesn't know or care where or how the file is stored, it just gives SphereFS a sandbox pointer and a filename and gets a file handle in return.  It's a very clean setup this way. :D

edit: It actually might be possible to support writing to an SPK, now that I know how the format is set up.  Every file, and the index itself, has an explicit offset stored in the headers, which means it's trivial to just append a new or modified file to the end.  For existing files you just modify the index entry, and new files can be tacked onto the end.  Of course this could cause the SPK to grow inordinately large without some method of compaction available... Just a thought.
Title: Re: minisphere 1.2.4
Post by: Fat Cerberus on June 15, 2015, 02:52:24 am

Awesome! I have some ideas for redistributable games in that regard:

- Obviously, direct filetype association with spk files would be nice. Double-click the SPK, play the game.
- Renaming the zips with a different extension (like .spk2 or .spherezip or something). This makes filetype association easier for Sphere zips. (Compare to .cbz "comic book zip" files, which are just archives filled with pictures)
- The game launcher detecting these packages if you put them in games/, of course. :)

And some more special ideas:
- If you distribute just the engine binary + an spk file, it'll pick up on the spk file so you don't even need a games or startup folder, it'll just open that when you start the engine.
- The ability to load multiple spk/zip files. Could be useful for loading the game and then loading extra resources on top of it (like a mod, a levelpack, etc.)


Going to take these one at a time.  Now that the SPK support is actually implemented, I can tackle these.

- Filetype association is best left to an installer, methinks.  Since the official distribution is for Windows, I think I can handle that.  minisphere 1.3 will be the first to be distributed as an installer.  That is, assuming Google will let me upload it to Drive, I think it might block uploading .exe files?  But yes, association with SPK would be nice.

- I'm thinking zip support won't make it into 1.3 after all.  Having actually implemented SPK and seen the inner workings of the format, it seems more than adequate for its intended purpose.  Plus it's insanely fast: I saw literally no performance difference at all running Specs from an SPK vs. directly.  They are even fast to compress, too--the Sphere 1.5 editor made a 35MB SPK out of my Specs project folder in seconds!  This to me is a clear case of "if it ain't broke, don't fix it" :P

- Self-evident, skipping. :)

Now, the "special" ideas:

- This is an awesome idea and not too difficult to implement either.  Only one question: If both a single SPK and a startup folder are present, which one takes precendence?

- This adds extra complexity to the engine, probably out of the scope of the 1.x releases.  A good idea for minisphere 2.0, though, I'll add it to the GitHub issue for that. :D
Title: Re: minisphere 1.2.4
Post by: DaVince on June 15, 2015, 05:39:16 am
Quote
- This is an awesome idea and not too difficult to implement either.  Only one question: If both a single SPK and a startup folder are present, which one takes precendence?

I'd say the startup folder, because that folder existing is evidence the entire package was not made to be a standalone game. Perhaps the game could still appear in the games list; I believe the default startup game just starts the game if it's the only one it finds anyway.

As for the special ideas: they're just ideas. But it's awesome that you're tackling both of them anyway. :P
Title: Re: minisphere 1.2.4
Post by: Fat Cerberus on June 15, 2015, 02:40:29 pm
I just enabled write access for games running from packages.  Actually modifying the SPK file at runtime would be time-consuming to implement and the file isn't guaranteed to be writable anyway, so if a game requests write access to an existing file, it is saved in ~/Sphere/.spkcache/[filename.spk] (the Linux meaning of ~, not Sphere's :) )

Note that this differs from Sphere 1.5, which puts the cache in packages under the engine.  Since nowadays we have to assume the engine directory is read-only, this needed to be changed.
Title: Re: minisphere 1.2.4
Post by: N E O on June 15, 2015, 07:48:46 pm
Re non-local files - For now, I recommend keeping all the various Sphere format file I/O functionality focused on local files. For non-local files, we can certainly consider expanding the network functions' capabilities to include a cURL implementation/shim or something as sugar for the existing socket functions for non-vanilla pre-2.0 engines and eventually fold them into official 2.0 API. Once the kinks are worked out, this folding in would also eventually allow non-local file reading on the Sphere format file I/O.

Then again, if it turns out to be trivial to change file I/O in minisphere to allow at least networked file I/O (as in less than 2 hours or so to add) feel free to add it now, show us some working tests, and we can have it much sooner. I'll then fully support such an endeavor as marked to be made official ASAP.
Title: Re: minisphere 1.2.4
Post by: Fat Cerberus on June 16, 2015, 03:35:31 am

Then again, if it turns out to be trivial to change file I/O in minisphere to allow at least networked file I/O (as in less than 2 hours or so to add) feel free to add it now, show us some working tests, and we can have it much sooner. I'll then fully support such an endeavor as marked to be made official ASAP.


The beauty of SphereFS is that it canonizes the Sphere 1.x sandbox.  For example when you call LoadImage("foo.png") under minisphere 1.3, you are not requesting <game path>/images/foo.png, the canonical name of the asset is literally:
images/foo.png

And names of this form are what get passed around inside the engine, not actual file paths.  SphereFS itself handles the final path resolution and I/O behind the scenes.  So yes, network I/O would be very easy to implement.  The tricky part is the synchronicity--the default APIs for loading assets are blocking in nature, which would slow them down running over the wire.

Long story short, the actual network file I/O isn't the issue, it's the API.
Title: Re: minisphere 1.2.4
Post by: Fat Cerberus on June 16, 2015, 02:52:16 pm
As of the latest master, minisphere will auto-launch a single .spk file placed alongside the engine executable, making game distribution drop-dead simple.  I just have to work out a couple more glitches and 1.3 should be ready for release.  ;D
Title: Re: minisphere 1.3.0
Post by: Fat Cerberus on June 17, 2015, 12:51:17 pm
minisphere 1.3 is out! 8)

This brings Sphere 2.0 SphereFS support, and with it the ability to run games packaged as SPKs!  You'll note that the startup game was converted to an .spk... ;)

As is usual for an x.x.0 release, expect bugs to show up.  So download minisphere 1.3 and test away!
Title: Re: minisphere 1.3.0
Post by: Fat Cerberus on June 17, 2015, 08:47:33 pm
Oh, not mentioned in the changelog, but minisphere 1.3 is fully Unicode-aware under the hood.  Person names, etc. are all UTF-8 internally, so you can feel free to use any characters you want in them and the engine won't choke on it. :)
Title: Re: minisphere 1.3.0
Post by: DaVince on June 18, 2015, 08:18:56 am
Nice work, as usual! ;D
Title: Re: minisphere 1.3.1
Post by: Fat Cerberus on June 18, 2015, 01:23:23 pm
minisphere 1.3.1 is available, with a ton of fixes for regressions introduced in 1.3.0.  This is my biggest maintenance release in a while, so be sure to check the changelog. :D

@FBnil: The fog demo should now work properly as of this release.
Title: Re: minisphere 1.3.1
Post by: FBnil on June 18, 2015, 01:38:02 pm
yes yes! it works now!

Tested ApplyColorFX(). (test script added).
Same behavior as Sphere 1.6, however, as you stated earlier, much slower.

Still have to modify the unittests, and publish it.
Title: Re: minisphere 1.3.1
Post by: Fat Cerberus on June 18, 2015, 01:51:21 pm
I think part of the speed problem is that I pass colormatrix_t objects around by value, so a lot of copying goes on, even more so for applyColorFX4().  But I also know Sphere does clever tricks with bitshifts for this operation, which I'm sure speeds it up considerably.  minisphere also calls a function to do the matrix interpolation, so that adds even more overhead if the compiler doesn't inline it.

I purposely didn't optimize it for this initial implementation, though.  I wanted to make sure I understood the theory behind it first.  I know now that it's just simple bilinear interpolation, but it wasn't easy to figure that out with all the magic tricks going on. :)
Title: Re: minisphere 1.3.1
Post by: Flying Jester on June 18, 2015, 01:55:44 pm
minisphere also calls a function to do the matrix interpolation, so that adds even more overhead if the compiler doesn't inline it.


Which is probably at least an order of magnitude smaller than passing an object on the stack :) What is the sizeof for a colormatrix_t?
Title: Re: minisphere 1.3.1
Post by: Fat Cerberus on June 18, 2015, 01:57:56 pm
int is 32 bits on Windows, a colormatrix_t has 12 of them.  So 48 bytes, or 96 bytes on a platform with 64-bit ints.

Edit: Honestly I'm starting to think most of the performance hit is that locking a bitmap in Allegro is just insanely expensive for no apparent reason.  I could understand it when I was using hardware textures, but switching surfaces to software offered no real performance improvement in, e.g. getPixel() until I also added the pixel cache for that.
Title: Re: minisphere 1.3.1
Post by: Fat Cerberus on June 19, 2015, 12:45:58 am
So I ran the profiler on minisphere to figure out what was causing the massive slowdown on my battle screen, and came back with some... interesting results.

As you can see on the Summary page, the function causing the majority of the bottleneck is js_Font_drawText().  No surprise there, I already knew minisphere was slow at rendering text.  However, the runner-up shocked me: js_new_Color, the Color constructor.  You can see the breakdown for that in the second screenshot.  Apparently creating Color objects on demand on expensive!

For good measure, the third screenshot shows the main culprit in the text rendering bottleneck: al_hold_bitmap_drawing(false);  This should be ridiculously fast, as fonts are atlased so Allegro can just send all the vertices at once.  But apparently not...
Title: Re: minisphere 1.3.1
Post by: Flying Jester on June 19, 2015, 01:59:17 am
I found that the color constructor adds noticeable overhead in TS, too. My main advice is just to not create colors on the fly as much as possible.


For good measure, the third screenshot shows the main culprit in the text rendering bottleneck: al_hold_bitmap_drawing(false);  This should be ridiculously fast, as fonts are atlased so Allegro can just send all the vertices at once.  But apparently not...


I'd be curious how the Turbo runtime's font renderer runs in Minisphere.
Title: Re: minisphere 1.3.1
Post by: Fat Cerberus on June 19, 2015, 02:46:03 am
I still can't get minisphere to load the Turbo runtime successfully due to all the circular RequireScripts.  How do you have RequireScript implemented in TS?  I evaluate the script AFTER entering it into the tracking list, to avoid infinite circular recursion.  So what ends up happening for me is that, after requiring map_engine.js, at some point in the require chain it gets to segment.js and Turbo is undefined because it's still in the middle of resolving the RequireScript chain.
Title: Re: minisphere 1.3.1
Post by: Flying Jester on June 19, 2015, 03:41:35 am
https://github.com/FlyingJester/TurboSphere/blob/master/src/configmanager/openscript.cpp#L68-L104 (https://github.com/FlyingJester/TurboSphere/blob/master/src/configmanager/openscript.cpp#L68-L104)

...Which leads to large stacks at certain points...

That's very strange. In TurboSphere, RequireScript enters a script into the list of evaluated scripts immediately after it checks if it was previously evaluated, which is right before it evaluates the next script.

But every one of the runtime's scripts should have the declaration of the Turbo object before anything that uses it--you should be able to require any one of them, and in any order, and not have that issue. It seems odd to me that Minisphere would complain about Turbo being undefined, unless the RequireScripts are not sharing all declarations until after they have completed or something similar. Or somehow our implementations are really that different? I think we do it the same way, and I can't really think of another way that would even come close to working properly.
Title: Re: minisphere 1.3.1
Post by: Fat Cerberus on June 19, 2015, 09:23:31 am
https://github.com/fatcerberus/minisphere/blob/master/src/api.c#L496-L521

Looks like the same basic logic to me.  Weird.

I know I had this same problem with miniRT, and I was only able to fix it by centralizing everything to a single script (miniRT.js) which pulls in all the others at the bottom (not the top).  And when I mentally followed the call chain, it made sense--if the RequireScripts are at the top and there's a circular reference, then when you hit the effective "bottom" of the tree (conceptually there is no bottom since it's a circle but in reality there is because of the implicit include guard), Turbo is undefined because all the scripts higher up in the call chain are still in the middle of include resolution, so nobody's actually had a chance to define it yet.

So yeah, not sure why this works in one engine but not the other.

Edit: Shame on you for calling malloc and not checking for null! :P  Actually though, I've stopped checking it myself.  I figure by the time a malloc returns null there's not much I can do in the way of recovery anyway so may as well just let it crash.
Title: Re: minisphere 1.3.1
Post by: Flying Jester on June 19, 2015, 11:54:30 am

Edit: Shame on you for calling malloc and not checking for null! :P  Actually though, I've stopped checking it myself.  I figure by the time a malloc returns null there's not much I can do in the way of recovery anyway so may as well just let it crash.


Yeah, in general there's just no point. In very almost all cases, an OOM is unrecoverable from any perspective. I could fail fast, but if I suspect an OOM I can use a debug malloc that aborts when it would return null.
Title: Re: minisphere 1.3.2
Post by: Fat Cerberus on June 20, 2015, 01:35:48 am
New version up, with a few map engine fixes.

edit: Awesome, 1111 posts! :P
Title: Re: minisphere 1.3.2
Post by: Radnen on June 20, 2015, 02:34:17 am

edit: Awesome, 1111 posts! :P


Don't you mean, 15? :P
Title: Re: minisphere 1.3.2
Post by: Fat Cerberus on June 20, 2015, 02:36:18 am
Why 15?
Title: Re: minisphere 1.3.2
Post by: Fat Cerberus on June 20, 2015, 06:39:12 pm
Tip of the day: Use RNG.name() if you need a unique internal name for something.  The function returns a random string of alphabetic characters, similar to the format of a YouTube video hash:
Code: [Select]
IlysMylJv


The function takes an optional integer parameter specifying the length of the string to generate, up to 255 characters.  If called with no parameter, a default length of 10 is used.
Title: Re: minisphere 1.3.2
Post by: Fat Cerberus on June 21, 2015, 03:05:05 am
https://github.com/fatcerberus/minisphere/commit/313d3dd455d632eb550de578233986c2a45fc5ad

That is all. ;D
Title: Re: minisphere 1.3.2
Post by: Radnen on June 21, 2015, 03:33:39 am
1111 is 15 in binary.

And you have some funny comments in your code. :P
Title: Re: minisphere 1.3.2
Post by: Fat Cerberus on June 21, 2015, 09:30:41 am
Hey, if I have to document the code I might as well have some fun with it, right? :)  You'll find I also tend to write funnier comments when I'm frustrated, like the "HERE BE DRAGONS" ones I have at the top of a few particularly hairy functions.  Then you have my personal favorite minisphere comment of all time, in persons.c:

Code: (c) [Select]
	// check that the person didn't mysteriously disappear...
if (!does_person_exist(person))
return;  // they probably got eaten by a hunger-pig or something.


And of course, this one's a classic too:
Code: (c) [Select]
	// check for obstructing persons
if (!person->ignore_all_persons) {
for (i = 0; i < s_num_persons; ++i) {
if (s_persons[i] == person)  // these persons aren't going to obstruct themselves!
continue;
if (s_persons[i]->layer != layer) continue;  // ignore persons not on the same layer
if (is_person_following(s_persons[i], person)) continue;  // ignore own followers
if (is_person_ignored(person, s_persons[i])) continue;
base = get_person_base(s_persons[i]);
if (do_rects_intersect(my_base, base)) {
is_obstructed = true;
if (out_obstructing_person) *out_obstructing_person = s_persons[i];
break;
}
}
}
Title: Re: minisphere 1.4.0
Post by: Fat Cerberus on June 21, 2015, 11:56:23 am
minisphere 1.4 is up!  I fast-tracked this one since I didn't really have any other ideas for a release, but the CS support is enough of a change to warrant a version bump, methinks.

To be clear: You can now specify .coffee files directly in a RequireScript() call, and require() will recognize .coffee modules as well.  No need to include the CS compiler with your game and manually invoke it, minisphere will load and use it from the system directory automatically.

The funny thing is I don't even really like CoffeeScript that much...

edit: I also recompiled everything with /O2.  It seems I sacrificed a lot of performance when I optimized for size a while back, not really worth it to reduce the engine size by half a MB.
Title: Re: minisphere 1.4.0
Post by: FBnil on June 21, 2015, 05:46:19 pm
Good or bad? Many opinions:
http://code.tutsplus.com/articles/should-you-learn-coffeescript--net-23206

And dipping your toes into CS:
http://blog.teamtreehouse.com/the-absolute-beginners-guide-to-coffeescript
Title: Re: minisphere 1.4.0
Post by: Radnen on June 21, 2015, 06:04:32 pm
Syntactically, coffescript is nice to have for a few areas: Classes, loops, and some areas of logic that may get too verbose. But I've found that libraries like my Link.js go a long ways in making sure iterations on lists and management of larger code sections is easier to maintain.

There's a point in professional JS in which you use code to write less code to code (like my post signature). I find that if you tackle every loop like this:
Code: (javascript) [Select]

for (var i = 0, l = items.length; i < l; ++i) { /**/ }

// rather than:
Link(items).each(function() { /**/ });


Or every class like this:
Code: (javascript) [Select]

var SubClass = function() {
    Class.call(this);
    /* ... */
}

SubClass.prototype = new Class();

// Rather than:
var SubClass = Extend(Class, { /**/ });


Then you are doing JS within JS wrong. CoffeeScript had a good use to write out JS shims for old browsers which isn't exactly needed for Sphere. Sure there are JS features that have been added since Sphere 1.6, but if you use CoffeeScript solely for minisphere I doubt you'll get the most out of it.
Title: Re: minisphere 1.4.0
Post by: Fat Cerberus on June 21, 2015, 06:10:02 pm
Yeah, I personally don't like a lot of things about CS.  Postfix if/unless, for one, confuses me to no end, and indent-based scoping... Ugh.  I prefer to write pure JS.  I still added CS though because I like to give people the option. :). I try not to impose my own preferences on others.
Title: Re: minisphere 1.4.0
Post by: Flying Jester on June 21, 2015, 06:24:36 pm
http://chadaustin.me/2015/05/coffeescript/ (http://chadaustin.me/2015/05/coffeescript/)

I certainly think that the syntax can be just a little ambiguous. I tend to be OK with ws-awareness, it's just a choice, and one I don't mind.

I've only used a little bit of Coffeescript. On the whole, it just seems to be a different syntax for JS (not too much better or worse). The only feature I thought was really nifty was how constructors could put named parameters directly into fields. That would be really nice to have in JS.
Title: Re: minisphere 1.4.0
Post by: FBnil on June 21, 2015, 07:28:06 pm
minimally rewrote agrapher to run with minisphere. It requires the system scripts typeof.js and colors.js (this one is updated with more things).
It draws functions and creates an image of that. See png attached.

So far, although similar at first glance, the grid and lines are offset a little, thus the image is not the same. I'm still investigating what exactly is different.
(s7.png is sphere 1.6 generated and ms.png is minisphere generated).
Title: Re: minisphere 1.4.0
Post by: Fat Cerberus on June 21, 2015, 07:32:26 pm
Just for future reference, you can put system scripts in (game dir)/lib and RequireSystemScript() will find them. :)
Title: Re: minisphere 1.4.0
Post by: FBnil on June 21, 2015, 07:33:39 pm
looking at it with gwenview reveals that the grid (which are transparent blue lines), are not the uniform color they should be, where, a lighter dot should be produced at intersections. This could be because of the way primitives are composed now. While irfanview does not show this difference. (the offset, is viewable in both image viewers, thus a real difference)

The sphere editor image viewer shows even more contrast in the grid produced by minisphere.

@L.E.: Thanks for the tips

edit: I know what it does now: minisphere, when printing a semi transparant color over the black canvas, actually makes the black canvas transparent, instead of blending, then leaving the alpha alone.
Title: Re: minisphere 1.4.0
Post by: Fat Cerberus on June 21, 2015, 07:46:55 pm
I should be able to fix that offsetting easily enough.  I'll take a look at it later.
Title: Re: minisphere 1.4.0
Post by: Fat Cerberus on June 21, 2015, 11:22:51 pm
I fixed the offset.  I just had to add 0.5 to the coordinates passed to Allegro.  Standard off-by-one error.

As for the colors, I think ultimately, with minisphere you're at whim of the hardware when using the legacy primitives.  A screenshot of my result is posted, and as you can see it's actually darker than the image produced by Sphere 1.5.  Which is the exact opposite of the result you got.
Title: Re: minisphere 1.4.1
Post by: Fat Cerberus on June 22, 2015, 12:44:07 am
1.4.1 fixes the off-by-one rendering for Line() as well as a CoffeeScript scoping issue.
Title: Re: minisphere 1.4.1
Post by: FBnil on June 22, 2015, 02:44:34 pm
Ah, it is darker because it is transparent blue, over black, which makes it very black, then rendered as non-transparent pixels (alpha 255).  It seems the transparency of a pixel also affects the RGBA of the destination, while this should only happen when it blends colors.
Title: Re: minisphere 1.4.1
Post by: FBnil on June 22, 2015, 03:56:45 pm
yay! I can segfault minisphere!

1. Run pianola
2. Press pageup twice (changes instrument)
3. press a key, for example q, twice.

Not sure why it doesnt segfault with the other sounds.
Title: Re: minisphere 1.4.1
Post by: Fat Cerberus on June 22, 2015, 05:48:31 pm

Ah, it is darker because it is transparent blue, over black, which makes it very black, then rendered as non-transparent pixels (alpha 255).  It seems the transparency of a pixel also affects the RGBA of the destination, while this should only happen when it blends colors.


Thanks, I'll have to look into that, I may have screwed up the blend modes for surfaces.

Not sure what's causing that segfault though, and I'm not near a computer to run it through the debugger at present.  I'll look at it tonight.
Title: Re: minisphere 1.4.1
Post by: Fat Cerberus on June 22, 2015, 11:49:44 pm
Hm, I can't get it to segfault following your directions.  I did notice however that the pitch doesn't change with different notes, they all sound the same.
Title: Re: minisphere 1.4.1
Post by: Fat Cerberus on June 23, 2015, 12:24:15 am
Well, the monotone notes are now fixed at least.  I forgot to reapply the gain, pitch, etc. when restarting the stream.

Somehow you keep finding the best testcases for minisphere, uncovering so many obscure bugs.  It helps me out a lot. ;)

Now to take another look at that grid.

edit: I figured it out, Allegro by default does blending for all components, including the alpha channel.  I have to use a different function to set a separate blendmode for the alpha channel:
https://www.allegro.cc/manual/al_set_separate_blender

Surprising I didn't notice this before, as I do some blending with surfaces myself.  I'll see about a fix.
Title: Re: minisphere 1.4.1
Post by: Radnen on June 23, 2015, 01:24:42 am

Surprising I didn't notice this before, as I do some blending with surfaces myself.  I'll see about a fix.


Well, full screen consistency can obscure it. I mean, unless you tested with Sphere 1.6 side-by-side you might have not just seen it. ;)
Title: Re: minisphere 1.4.1
Post by: Fat Cerberus on June 23, 2015, 02:07:09 am
@FBnil
The output of your grapher is, for all intents and purposes, identical to Sphere 1.5 now.  See screenshot. :)

The fix will be in 1.4.2.

edit: Dammit, my fix isn't right, I ended up breaking other stuff (like the startup game, and Spectacles).  And just as I was about to release 1.4.2 too... oh well.  Back to the drawing board...
Title: Re: minisphere 1.4.1
Post by: Fat Cerberus on June 23, 2015, 12:28:50 pm
Hm, looks like I'm going to have to leave the alpha blending code the way it is in 1.4.1.  It turns out Sphere 1.6 handles the BLEND mode like this:

Code: (cpp) [Select]
inline void blendRGBA(RGBA& dest, RGBA src)
{
    Blend3(dest, src, src.alpha);
    dest.alpha = 255;
}


Which appears to be impossible to do in hardware--or at least with the blend modes Allegro provides.  In most real-world cases the full RGBA blending works fine, for example the textboxes in Specs and... whatever the startup game does.

For what it's worth, the closest I could come to Sphere's actual behavior is this:
Code: (c) [Select]
al_set_separate_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA,
ALLEGRO_ADD, ALLEGRO_ZERO, ALLEGRO_ONE);


This leaves the destination's alpha channel alone.  That fixed agrapher, but broke everything else; fully-transparent surfaces stay fully transparent regardless of what you render.  Not particularly useful.
Title: Re: minisphere 1.4.1
Post by: FBnil on June 23, 2015, 03:10:21 pm
Dont break spectacles! fixing the Alpha channel can be done in scripting as well (or maybe a new function). This will become useful for me once spritesets can be updated dynamically (to be able to swap clothes, armour and gear;and if those functions are not available, I can work around that by mixing to disk, and reload the spriteset).
Ill look better into a testcase for the crash on Windows (my platform is Linux now, so maybe it is a library, and not minisphere).

Slowly recovering my ranma demo. You see, long time ago I did remove all duplicate files from my backup, but then lost the original directories (svn) in a laptop crash. Thus, all I have now are spritesets and maps all over the place, without knowing which is newer and more complete.

Lord English, more stuff broke with the current version(Tue Jun 23 02:43:42 2015 -0400), see the attached print demo. All skewed canvas drawings are invisible (or are not being printed). The code is unreadable. I guess I was more focused on functionality at that time. (I guess that is the change that you wanted to roll back).
I also get a bit funky in puff-puff, where NPC's are able to grab powerups. A 9x9 layer is not stretched anymore and surfaces are not mirrored (the firedemo/sun). And in the highscores, the stylewindow is not filled in, something is printed, in very light blue, bot not inside it. Also, the skewing there is weird, the right-side of the logo is not wobbly as expected. I will break that down into smaller bugtests during the week. So do not worry... lots of genuine bugs to come!

There are successes also:
Kamatsu's pathfind.js runs out of the box, as well as my demo around that library (see picture).
I am modifying pathfind.js, as it uses strings as indexes, and numbers are (should be) faster. Will need to benchmark that.

Its fun to read your log. I saw also that stray printf, but thought nothing of it.
Tested the coffee script, but as I do not know it (bar that webpage that had some example code). It was fun to get it in.

mod sound is still a bit off for me.. the channels pan totally right/left, but I'm not sure if that is allegro or that it can be controlled in ms.
Title: Re: minisphere 1.4.1
Post by: Fat Cerberus on June 23, 2015, 03:46:01 pm
Don't know what you mean about the MOD sound, you'll have to explain that a bit more.

I just pushed a commit reverting to the original blending behavior.  Could you test again and see if that fixes the canvas stuff?
Title: Re: minisphere 1.4.1
Post by: FBnil on June 23, 2015, 06:29:02 pm
* print example is 100% ok again (better than 2 build back, as the integration symbol in the formula now displays fine, just as the extra wide plus sign, so something in the resize is now done right again)
* puffpuff highscores still not ok (and the colorbars are back to that because of the old transparency behavior). Image attached. Like I said, will make a simple test for that.
* The sound on Linux seems worse than on windows. But it is in the wine version of Sphere 1.7 too (1.6 with the ctypes working). so a mod is 4 channels: left,right,left,right and not slightly panned off center, as I remember making the music. So it is probably linux. I will have to edit the music in impulse tracker again, create an .it file, and test that. So ignore my comment for the moment, it is not minisphere. (audiere used to sound very good on windows... )
Title: Re: minisphere 1.4.1
Post by: Fat Cerberus on June 23, 2015, 06:38:52 pm
Hm, I wonder what's causing the window to be transparent like that.  As for the blending, the only way I can see to fully emulate Sphere 1.x would be to use a shader.  The fixed-function pipeline just isn't capable of it, and doing surfaces entirely in software is unfeasible as Allegro blitting performance for memory bitmaps is atrocious.
Title: Re: minisphere 1.4.1
Post by: Flying Jester on June 23, 2015, 06:52:54 pm
Does Allegro not allow you to use glBlendFunc and friends?
Title: Re: minisphere 1.4.1
Post by: Fat Cerberus on June 23, 2015, 07:09:22 pm
In theory I could use that, I don't see any combination of parameters which would emulate this however:

RGB = src * alpha + dest * (255 - alpha) / 255
A = 255
Title: Re: minisphere 1.4.1
Post by: Flying Jester on June 23, 2015, 07:41:09 pm
I'm 99% certain you can use the GL FFP to do this.


RGB = src * alpha + dest * (255 - alpha) / 255
A = 255


This would equate to RGB = SRC_RGB * SRC_ALPHA + DEST_RGB * (1 - DEST_ALPHA)?

Perhaps:
Code: (c) [Select]
glBlendColor(0.0f, 0.0f, 0.0f, 1.0f);
glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_DST_ALPHA, GL_CONSTANT_ALPHA, GL_ZERO);
Title: Re: minisphere 1.4.1
Post by: Fat Cerberus on June 23, 2015, 07:45:08 pm
Indeed, the tricky part is that Sphere does RGB blending using the source alpha, but explicitly sets the alpha of the destination to full opaque.  Kind of odd, but as you can see, a lot of existing code relies on it.

Edit: wait, I see it now.  Never mind me, I need to pay better attention. :)
Title: Re: minisphere 1.4.1
Post by: Fat Cerberus on June 23, 2015, 10:52:41 pm

Code: (c) [Select]
glBlendColor(0.0f, 0.0f, 0.0f, 1.0f);
glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_DST_ALPHA, GL_CONSTANT_ALPHA, GL_ZERO);



Hm, I did some reading, and glBlendFunc() actually sets the multiplier for the source and destination pixels, even with GL_CONSTANT_COLOR/ALPHA (so the "constant color" is actually a mask and is thus a misnomer).  So basically what your snippet does is overwrite the destination alpha channel with the one from the source image, the same as if you did this:
Code: [Select]
glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_DST_ALPHA, GL_ONE, GL_ZERO);


It doesn't unconditionally set the destination pixel to full opaque like Sphere does. :(  So yeah, I'm pretty sure I will have to use a shader.  No big deal, I already have the plumbing in place for shaders, it's easy enough to throw a few into the system folder for blending modes.

edit: That said, I did just send a pull request to implement constant-color blending in Allegro, since it's indeed a useful feature and I have no clue how it didn't make it in before now. :P
Title: Re: minisphere 1.4.1
Post by: Fat Cerberus on June 24, 2015, 01:55:55 am
I just implemented engine-wide shader support in minisphere.  Previously shaders only applied to Galileo rendering, and a null shader (i.e. Allegro default) was used everywhere else.  Now minisphere looks for system.vs.glsl and system.fs.glsl in the system directory on startup and uses them if they are found.  These will be used to implement the Sphere 1.x blend and mask modes properly.

The engine will still work if the system shaders are unavailable, in which case it will fall back on the FFP (which will be inaccurate) and the aforementioned null shader.

edit: BAH!  It turns out you can't do blending in a shader because the fragment shader doesn't have access to the destination color, only the source fragment color.  Figures.
Title: Re: minisphere 1.4.1
Post by: Fat Cerberus on June 24, 2015, 01:06:46 pm
@FBnil
Good news, you found an unimplemented feature!  It seems I never implemented gradient windows...

I also got the blending closer to Sphere, but it's still not perfect.

edit: Got it!
Title: Re: minisphere 1.4.1
Post by: FBnil on June 24, 2015, 05:13:34 pm
;D yay! ;D
Title: Re: minisphere 1.4.1
Post by: Fat Cerberus on June 24, 2015, 06:15:37 pm
The only thing I can't figure out is why the fireball on the title isn't displaying.  I added a call to surface.save() to that part, and the image is empty, all black.  No sun.  Yet when I ran through the debugger the color values are right.  Apparently surface.setPixel() is broken.

The other bug I saw with this game is that the death animation isn't right, the car moves to a seemingly random location while it spins out.  I think MapToScreen() is glitched, but it works fine in Specs...
Title: Re: minisphere 1.4.1
Post by: Fat Cerberus on June 25, 2015, 02:53:08 am
Okay, I fixed the fireball/sun thing, and also the mirroring.

I also figured out that MapToScreen() is bugged for small repeating layers due to aliasing (internally it just does a reverse mapping from ScreenToMap, if the layer repeats within a screen it's ambiguous where you are in relation to it).  I'm too tired to come up with a fix now though, I will work on it in the morning.  I'm also not sure why the enemy cars are picking up the power-ups...

edit: MapToScreen*() and ScreenToMap*() are now fixed.
Title: Re: minisphere 1.4.1
Post by: Fat Cerberus on June 25, 2015, 03:14:49 pm
Okay, figured out why cars can pick up flags and stuff in Puff-Puff, it's not technically a bug.  Sphere 1.x only calls the touch-script for input person collisions, minisphere does it for all entities.  Despite that the behavior is not fully compatible, in almost all cases, minisphere's semantics here are preferable.  Persons should be able to respond to anyone touching them, not just the player(s).

For Puff-Puff specifically, the workaround is to add this line to the top of the relevant touch scripts:
Code: (javascript) [Select]
if (GetActivePerson() != GetInputPerson()) return;


So yeah, I think that's all the Puff-Puff bugs, time for 1.4.2!

edit: minisphere 1.4.2 is up.  This fixes an incredible number of bugs, so make sure to check the changelog. ;)
Title: Re: minisphere 1.4.2
Post by: Fat Cerberus on June 26, 2015, 01:24:17 am
Lookie here:
https://travis-ci.org/fatcerberus/minisphere

;D
Title: Re: minisphere 1.4.1
Post by: Radnen on June 26, 2015, 02:42:51 am

Okay, figured out why cars can pick up flags and stuff in Puff-Puff, it's not technically a bug.  Sphere 1.x only calls the touch-script for input person collisions, minisphere does it for all entities.  Despite that the behavior is not fully compatible, in almost all cases, minisphere's semantics here are preferable.  Persons should be able to respond to anyone touching them, not just the player(s).


Despite being incompatible I do like this system. It makes making a RPGMaker like eventing system easier to manage if other entities collisions can be handled gracefully. Otherwise it'd be hard to get back that kind of info without running your own loop of checks (which is rather redundant), and prone to failure.
Title: Re: minisphere 1.4.2
Post by: DaVince on June 26, 2015, 04:36:46 am

Lookie here:
https://travis-ci.org/fatcerberus/minisphere

;D

Nice! I suppose this will warn you of building issues before I get the chance to complain (:P) about it, right? :)
Title: Re: minisphere 1.4.2
Post by: Fat Cerberus on June 26, 2015, 09:04:27 am


Lookie here:
https://travis-ci.org/fatcerberus/minisphere

;D

Nice! I suppose this will warn you of building issues before I get the chance to complain (:P) about it, right? :)


Yes, plus it paves the way for a future official Linux release, as I'll know ahead of time whether the build is broken (so errors don't pile up).  What shocks me is how *silent* the build is, even in the clang build.  No warnings whatsoever.  I wonder what warning level SCons is using...
Title: Re: minisphere 1.4.2
Post by: Flying Jester on June 26, 2015, 11:51:12 am
It looks like the clang build is working in GCC compatibility mode, which is very permissive by Clang's standards.

Try adding CFLAGS=" -Wall " and you will get a barrage of new warnings, and " -pedantic " if you are feeling truly masochistic.
Title: Re: minisphere 1.4.2
Post by: Fat Cerberus on June 26, 2015, 11:58:17 am
I'm just going to go out on a limb here and guess that -pedantic will make the build horribly, horribly broken. :P
Title: Re: minisphere 1.4.2
Post by: Flying Jester on June 26, 2015, 12:21:21 pm
"-pedantic" makes the build 99.9% accurate to the standard you selected (which defaults -std=c99). Clang and GCC are far closer to the C99 standard than MSVC is (or really any other compiler except for Solaris Studio), so I would suspect that it bring up all kinds of new and exciting problems.

You can also add "-ansi" instead of "-std=c99" to get C89, which is very close to what MSVC 2010 has, except that it also disallows single-line comments. C99 didn't really work at all until at least MSVC 2012.
Title: Re: minisphere 1.4.2
Post by: Fat Cerberus on June 26, 2015, 12:23:56 pm
I'm not giving up C99, I like my // comments and sized ints too much. :)
Title: Re: minisphere 1.4.2
Post by: Flying Jester on June 26, 2015, 12:31:58 pm
Well, sized ints are a matter of the library itself, not the standard. While technically a compiler should limit the library a program can see when compiling for a certain standard, this tends to only happen with C++.

Then there's Solaris Studio. (Almost) fully C++14 and C11 compliant, still running on a C++03 and C89 library :/
Title: Re: minisphere 1.4.2
Post by: FBnil on June 26, 2015, 12:50:48 pm
Thanks a TON! It is unbelievable how fast you update and commit.
Good code too, will re-test stuff later-on.
I'm trying to get the networking working, but I seem to either not "getting" it, or there is a bug:

Code: [Select]
  var LocalPort = 9500;
  var Listen = 255; // MAXCONNECT
  var server = new ListeningSocket(LocalPort, Listen);
  if(! server ){Abort("Could not open socket on " + LocalPort)}
  var socket = server.accept();
  if(socket === NULL){Abort("Could not accept socket")}
  if(socket.isConnected()){
    var len = socket.getPendingReadSize();
    if(0 < len && len < 1024){
      var BUFFER = socket.readString(len);
      socket.write("404 Not Found\n\r\n\r");
      Abort(BUFFER);
    }else{
      Abort("len is not ok " + len);
    }
      socket.close();
  }

But for
Code: [Select]
var socket = server.accept();

it throws:
Code: [Select]
JS Error: main.js:10 - TypeError: not callable


I wrapped it in a try loop, of course, but even then, a webbrowser connects, but then "hangs" (as opposed to an immediate "unable to connect" error). So we know it is connecting, but it seems it is not able to start up communications.

Title: Re: minisphere 1.4.2
Post by: FBnil on June 26, 2015, 12:57:12 pm

I'm not giving up C99, I like my // comments and sized ints too much. :)

:D

Wall is allright, and with pedantic... wow...  don't even try it...

Quote
obj/utility.h:6:8: warning: (this will be reported only once per input file)
In file included from obj/animation.c:2:0:
obj/api.h:1:14: warning: ISO C forbids forward references to 'enum' types [-Wpedantic]
typedef enum js_error js_error_t;

(and of course, a waterfall of similar stuff)

Still, some things are worthy of checking out with Wall,
Code: [Select]
CFLAGS = ["-Wall", "-std=c99"]
minisphere = Program("msphere", msphere_sources, LIBS = msphere_libs, CFLAGS = CFLAGS)


Title: Re: minisphere 1.4.2
Post by: Fat Cerberus on June 26, 2015, 01:03:56 pm

Thanks a TON! It is unbelievable how fast you update and commit.
Good code too, will re-test stuff later-on.
I'm trying to get the networking working, but I seem to either not "getting" it, or there is a bug:

Code: [Select]
  var LocalPort = 9500;
  var Listen = 255; // MAXCONNECT
  var server = new ListeningSocket(LocalPort, Listen);
  if(! server ){Abort("Could not open socket on " + LocalPort)}
  var socket = server.accept();
  if(socket === NULL){Abort("Could not accept socket")}
  if(socket.isConnected()){
    var len = socket.getPendingReadSize();
    if(0 < len && len < 1024){
      var BUFFER = socket.readString(len);
      socket.write("404 Not Found\n\r\n\r");
      Abort(BUFFER);
    }else{
      Abort("len is not ok " + len);
    }
      socket.close();
  }

But for
Code: [Select]
var socket = server.accept();

it throws:
Code: [Select]
JS Error: main.js:10 - TypeError: not callable


I wrapped it in a try loop, of course, but even then, a webbrowser connects, but then "hangs" (as opposed to an immediate "unable to connect" error). So we know it is connecting, but it seems it is not able to start up communications.


Oops, I accidentally still had accept() exposed as "acceptNext" from when I originally implemented the Sockets API.  The latest Git build fixes it.
Title: Re: minisphere 1.4.2
Post by: Flying Jester on June 26, 2015, 01:34:05 pm
If -Wall is fine but pedantic is broken, you could also try -Wextra, sort of in between.

...but ideally I suggest at least looking at the output of pedantic.
Title: Re: minisphere 1.4.2
Post by: Fat Cerberus on June 26, 2015, 01:48:36 pm
Amusing side note: Don't ever attempt to use -Wall with MSVC.  It generates thousands of "warnings" that aren't even real warnings--noise like "Oh hey, I inlined this function for you" or "x amount of padding added to this struct" and other such nonsense.
Title: Re: minisphere 1.4.2
Post by: Fat Cerberus on June 26, 2015, 03:13:28 pm
I think I'll throw -pedantic into my SConscript for a bit and see what output I get out of Travis.  I don't have a Linux machine set up yet so I can't test it myself.

edit: Well, I broke the build--std=c99 doesn't define M_PI etc. apparently.

As for pedantic warnings, the only thing I can see is implicit declarations of standard library functions--which means I just forgot an include.  Even Duktape itself was silent.

edit 2: Well that's kind of annoying.  Apparently scons quits after the first file that has errors.  I like MSVC's build system, it will keep going anyway so you get to see if anything else has errors without having to keep restarting the build.
Title: Re: minisphere 1.4.2
Post by: FBnil on June 26, 2015, 05:29:09 pm
MSVC:


See also this: https://www.smore.com/clippy-js
Title: Re: minisphere 1.4.2
Post by: Flying Jester on June 26, 2015, 05:31:05 pm

edit 2: Well that's kind of annoying.  Apparently scons quits after the first file that has errors.  I like MSVC's build system, it will keep going anyway so you get to see if anything else has errors without having to keep restarting the build.


There is some option to change that, but I forget what it is.
Title: Re: minisphere 1.4.2
Post by: Fat Cerberus on June 26, 2015, 06:49:41 pm

MSVC:
[Clippy macro]


Heh... Haha.... ... BWAHAHAHAHAHHAA!  That's perfect.  Absolutely perfect.

I hated that stupid paperclip.  Thank god they had the decency to never implement Agent in MSVC, could you imagine the nightmare? :P

I always did have a soft spot for the cat though.  Annoying as it was I used to enable Agent anyway just to see the cat roll around and play, it was cute.  I turned off all the stupid "hints" though, of course. ;)
Title: Re: minisphere 1.4.2
Post by: Fat Cerberus on June 27, 2015, 01:51:09 am
Hm, I don't think this is too bad:
https://travis-ci.org/fatcerberus/minisphere/jobs/68574196

Rather noisy, but it looks like the vast majority of the warnings are C90 violations (long long, C++-style comments, etc.).  The only ones that really concern me are these:

Code: [Select]
obj/color.c:32:3: warning: initializer element is not computable at load time [enabled by default]


This happens when I declare and initialize a large structure, usually an array of vertices, inline.  The alternative is to set the individual struct members directly, which would be uglier.

So yeah, -pedantic wasn't nearly as scary as I thought it would be.  A testament to how clean the codebase is, I guess. :D
Title: Re: minisphere 1.4.3
Post by: Fat Cerberus on June 27, 2015, 02:59:20 am
minisphere 1.4.3 is up.  This is the first release to be distributed as an installer!  This is convenient, as the installer will automatically associate the engine with SGM and SPK files (the 64-bit engine is associated on 64-bit Windows).  Go try it out!

Oh, I was going to include Sphere Studio, but it doesn't work when run from Program Files, it just terminates immediately, I assume because it tries to save its .ini file in the editor directory...
Title: Re: minisphere 1.4.3
Post by: Fat Cerberus on June 28, 2015, 12:30:34 am
Just updated the 1.4.3 download, the installer now includes Sphere Studio. :D

@Radnen: I hope you don't mind... ;)  Also, check your pull requests. 8)
Title: Re: minisphere 1.4.2
Post by: Flying Jester on June 28, 2015, 12:47:55 am

Rather noisy, but it looks like the vast majority of the warnings are C90 violations (long long, C++-style comments, etc.).  The only ones that really concern me are these:
Code: [Select]
obj/color.c:32:3: warning: initializer element is not computable at load time [enabled by default]



In ansi C (and actually up to C11), initializer lists must be entirely made up of compile-time constants. Of course, common compilers can handle this kind of thing, which is why it ended up being in the C11 standard.

I think you can silence the comment error with "-Wno-comment".
Title: Re: minisphere 1.4.3
Post by: Fat Cerberus on June 28, 2015, 12:46:52 pm
So it seems I broke screenshots at some point... Oops.  I changed it to put them in ~/Sphere Files/Screenshots (home dir, not Sphere's definition of ~/), but forgot to have it create the screenshots folder.  So yeah, screenshots don't work unless you create the folder manually first.  It will be fixed in the next update.
Title: Re: minisphere 1.4.4
Post by: Fat Cerberus on June 28, 2015, 11:52:55 pm
minisphere 1.4.4 is up, fixing the screenshot bug.  The installer now pre-configures Sphere Studio as well (without clobbering existing settings), and creates presets for minisphere.  This should hopefully make the engine much more accessible to newbies! :)

edit: Make that 1.4.5.  I discovered a bug in the installer, it won't give the option to install Sphere Studio.  This fixes it.

I also split minisphere into two downloads.  The GDK includes Sphere Studio and minisphere Console, while the redistributable only includes the standard engine and sample games.
Title: Re: minisphere 1.4.5 with Sphere Studio
Post by: Fat Cerberus on July 02, 2015, 03:10:36 am
So, funny story: I'm all tapped out of ideas for how to improve minisphere any further.  This is probably a good thing since it means the engine is pretty much a complete, comprehensive package, but it's driving me bonkers with boredom. :P

I keep hoping for one more big feature idea so I can get minisphere to v1.5, but no such inspiration yet...

... any ideas? ;)
Title: Re: minisphere 1.4.6 with Sphere Studio
Post by: Fat Cerberus on July 02, 2015, 02:43:03 pm
minisphere 1.4.6 is up with a few minor fixes.  I found a bug where screenshots could be washed out because the backbuffer's alpha channel was incorrectly preserved when saving.  I also fixed the lack of a taskbar icon for games with no icon.png.

Additionally, I dug up the SVG version of the Spherical icon NEO posted a while back and scaled it up 768x768, so now minisphere has a proper Win10-ready icon. :)
Title: Re: minisphere 1.4.6 with Sphere Studio
Post by: Radnen on July 03, 2015, 01:16:41 am

Additionally, I dug up the SVG version of the Spherical icon NEO posted a while back and scaled it up 768x768, so now minisphere has a proper Win10-ready icon. :)


Awesome!
Title: Re: minisphere 1.4.6 with Sphere Studio
Post by: Fat Cerberus on July 04, 2015, 01:55:51 pm
Tip of the day: SphereFS enables creating games which can share save data.  For example, carrying over stats and such to a sequel, or similar such systems.  To do this, use a  ~usr/ path:

~usr/SpectaclesSaga/BrucesStory_fileA.save.

~usr/ points to the same location for all games, so they can share data!
Title: Re: minisphere GDK 1.4.7
Post by: Fat Cerberus on July 05, 2015, 03:01:29 am
New release. :)
Title: Re: minisphere 1.4.7
Post by: N E O on July 05, 2015, 04:26:54 am

Additionally, I dug up the SVG version of the Spherical icon NEO posted a while back and scaled it up 768x768, so now minisphere has a proper Win10-ready icon. :)

It is actually casiotone's, but I lost the original SVG he gave me when we lost the forums so I recreated it.
Title: Re: minisphere 1.4.7
Post by: Fat Cerberus on July 05, 2015, 12:18:18 pm
Did you ever find the gradient version?
Title: Re: minisphere 1.4.7
Post by: N E O on July 05, 2015, 05:49:15 pm
I think the SVG of the gradient version might be on my Windows laptop somewhere, but I haven't had occasion to look for it recently.
Title: commit 8f8e0273652ffe3b39dcc27143dd33c104264a6f
Post by: FBnil on July 08, 2015, 04:55:28 pm
Date:   Wed Jul 8 14:26:40 2015 -0400
Does not run (immediate coredump) on Linux
Title: Re: minisphere 1.4.7
Post by: Fat Cerberus on July 08, 2015, 05:04:16 pm
Hm.  Run with option --log-level 4, what is the output?
Title: Re: minisphere 1.4.7
Post by: FBnil on July 10, 2015, 05:53:29 pm
Sorry, did not read on time. I updated to today and it does not crash anymore. Do you need me to go back in time to compile that version again?
Title: Re: minisphere 1.4.7
Post by: Fat Cerberus on July 10, 2015, 06:11:01 pm
Nah, as long as it's working now that's good.  I probably broke something while I was moving the audio code around.
Title: Re: minisphere 1.4.7
Post by: Fat Cerberus on July 12, 2015, 03:23:13 am
Good news, guys: minisphere 1.5 is only a few days off. :D  Progress has been a bit slow because I'm in the middle of a huge overhaul under the hood of Sphere Studio (I have to earn my collaborator status you know! :P) but I just finished up implementing Mixers and so far everything looks good.  I do still have to add documentation for the Audialis additions and the Mixer object needs a few more features (volume adjustment, for one), but otherwise I'm pretty close to wrapping this up.

Keep in mind that SoundStreams will be limited to 8-bit unsigned in minisphere 1.5.  This makes them easy to manipulate with Sphere ByteArrays, whereas any other sample format would be unwieldy to work with under these circumstances.  Once Duktape releases a version supporting ArrayBuffer/TypedArray, then I'll open up more sample formats. ;)
Title: Re: minisphere 1.5.0
Post by: Fat Cerberus on July 12, 2015, 12:58:58 pm
Okay, 1.5 is up.  Nil, could you try out the new Audialis stuff and let me know how it works?

I removed the demo games from the installers for 1.5.  This got the engine-only down to 2.2mb and the GDK is under 4.5mb.  Not too shabby at all!
Title: Re: minisphere 1.5.1
Post by: Fat Cerberus on July 14, 2015, 12:10:19 pm
I posted minisphere 1.5.1 to fix an issue with creating 8-bit mixers.

To clarify on how the Mixer object works: It actually encapsulates both a hardware voice and a software mixer.  In 1.5.0, both of these were created with the parameters passed to the Mixer constructor.  This failed in the case of 8-bit, as Allegro will create an 8-bit voice but refuses to create an 8-bit mixer.  For good reason, too--it'd be difficult to do any kind of decent mixing at all with only 8 bits of precision! :P

As of 1.5.1, the hardware voice created matches the Mixer() parameters, but the mixer itself is float32.  This ensures the call will succeed so long as the underlying sound hardware supports the requested bit depth and channel count.
Title: Re: minisphere 1.5.1
Post by: Fat Cerberus on July 15, 2015, 03:44:51 pm
So I found a great use for Audialis already: Crossfading BGM.  Previously this would have been a pain, since the BGM volume is generally global, while crossfading requires manipulating individual streams' volume settings.  Under the Sphere 1.x API, something like setting the BGM volume in the middle of a fade would prove to be very tedious indeed.

Under Audialis, I can just set the volume on the BGM mixer when adjusting global volume, and adjust the individual stream volumes separately to handle crossfades.  It makes the code very elegant.
Title: Re: minisphere 1.5.1
Post by: DaVince on July 15, 2015, 05:02:36 pm
I don't really get it. I've successfully done audio1.setVolume(fadeoutvalues); audio2.setVolume(fadeinvalues); before. Or is BGM a separate thing compared to Sphere's standard sound playback functions?
Title: Re: minisphere 1.5.1
Post by: Fat Cerberus on July 15, 2015, 05:12:14 pm
That indeed works, the issue is if someone adjusts the global BGM volume in the midst of a fade, things get tricky because you're in the middle of a tweening operation.
Title: Re: minisphere 1.5.1
Post by: Fat Cerberus on July 15, 2015, 06:24:20 pm
To clarify further, assuming there's a fade in progress:

Code: (javascript) [Select]
mixer.volume = 0.5;


The above won't disturb a crossfade-in-progress.  Further, this allows the global volume to be faded at the same time, for example in a cutscenes where you want to fade down the BGM to half while simultaneously switching tracks.

Another good use would be to implement an in-game volume setting menu.  You create two mixers, one for music and one for sounds, and the volume slider adjusts the volume of the mixers without having to touch the individual Sound objects.

I'm glad I implemented this. :)
Title: Re: minisphere 1.5.1
Post by: N E O on July 16, 2015, 01:19:35 pm
Does 1.5.1 come with an example for using this new Mixer? I also would like updated instructions for Mac compilation (>=Mavericks) so I can try it out, thanks!
Title: Re: minisphere 1.5.1
Post by: Fat Cerberus on July 16, 2015, 01:23:03 pm
No example, but the Mixer and SoundStream objects are included in the API reference (minisphere-api.txt).

As for Mac compilation, it should be the same as Linux. Dependencies are:

* Allegro 5.1.11 (I think available through homebrew?)
* libmng
* zlib

And SCons to build.  Just issue an scons at the command line and you're good to go.  The engine will be built in <checkout dir>/bin/.
Title: Re: minisphere 1.5.2
Post by: Fat Cerberus on July 16, 2015, 02:57:43 pm
@DaVince
If you're still confused about the mixer thing discussed on the last page, check out miniBGM.js in 1.5.2.  You can see how I used the Mixer object to implement crossfading cleanly.
Title: Re: minisphere 1.5.2
Post by: N E O on July 17, 2015, 06:24:14 pm

No example, but the Mixer and SoundStream objects are included in the API reference (minisphere-api.txt).

As for Mac compilation, it should be the same as Linux. Dependencies are:

* Allegro 5.1.11 (I think available through homebrew?)
* libmng
* zlib

And SCons to build.  Just issue an scons at the command line and you're good to go.  The engine will be built in <checkout dir>/bin/.


homebrew doesn't have libmng and it seems to be unobtainable for me at the moment. Is there a command line switch to disable MNG support?
Title: Re: minisphere 1.5.2
Post by: Fat Cerberus on July 17, 2015, 06:28:27 pm
Not at present.  You can probably coax it to compile if you remove animation.c from the SConscript, and then comment out lines 2 and 174 of api.c.
Title: Re: minisphere 1.5.2
Post by: DaVince on July 17, 2015, 06:45:09 pm

@DaVince
If you're still confused about the mixer thing discussed on the last page, check out miniBGM.js in 1.5.2.  You can see how I used the Mixer object to implement crossfading cleanly.

Okey dokes, thanks.
Title: Re: minisphere 1.5.2
Post by: N E O on July 17, 2015, 08:13:42 pm

Not at present.  You can probably coax it to compile if you remove animation.c from the SConscript, and then comment out lines 2 and 174 of api.c.

Two errors:

obj/galileo.c:40:2: error: unknown type name 'ALLEGRO_VERTEX_BUFFER'
obj/galileo.c:393:77: error: use of undeclared identifier 'ALLEGRO_PRIM_BUFFER_STATIC'; did you mean 'ALLEGRO_PRIM_LINE_STRIP'?

Allegro through homebrew is 5.0.11, not 5.1.11 as you recommend. Is this a problem?
Title: Re: minisphere 1.5.2
Post by: Fat Cerberus on July 17, 2015, 08:15:14 pm
You need the latest Allegro (5.1.11).  What version do you have?

Edit:  yeah, 5.0.x won't work.  Not sure what to do here...
Title: Re: minisphere 1.5.2
Post by: Flying Jester on July 17, 2015, 08:37:00 pm
I just had to build it from scratch last I tried on OS X. The build is not especially pleasant on OS X, but it's manageable.
Title: Re: minisphere 1.5.3
Post by: Fat Cerberus on July 18, 2015, 11:17:15 am
1.5.3 adds My Documents\Sphere Games to the search path for GetGameList().  Since minisphere is installed to Program Files, this makes the startup game actually useful again. :P
Title: Re: minisphere 1.5.3
Post by: N E O on July 18, 2015, 03:13:47 pm

I just had to build it from scratch last I tried on OS X. The build is not especially pleasant on OS X, but it's manageable.

This Allegro wiki article (https://wiki.allegro.cc/index.php?title=Install_Allegro5_From_GIT/OSX) says get it from SourceForge, but SF is in "maintenance mode" right now. Don't know how long that will last, so can't build 5.1.11 either.

I don't suppose one of you can put up the Allegro 5.1.11 and libmng source for me to download?
Title: Re: minisphere 1.5.3
Post by: Fat Cerberus on July 18, 2015, 03:28:42 pm
Allegro 5 GitHub mirror:
https://github.com/liballeg/allegro5

Can't speak for libmng though.
Title: Re: minisphere 1.5.3
Post by: N E O on July 18, 2015, 05:09:54 pm
After building Allegro from the GitHub mirror and also removing "mng" from msphere_libs in SConscript and `brew install libjpeg`, new error:

Code: [Select]

Undefined symbols for architecture x86_64:
  "_main", referenced from:
     implicit entry/start for main executable
     (maybe you meant: __al_mangled_main)
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
scons: *** [obj/engine] Error 1
scons: building terminated because of errors.
Title: Re: minisphere 1.5.3
Post by: Fat Cerberus on July 18, 2015, 05:18:25 pm
You have to link to allegro_main on OSX (and only OSX), I forgot about that.  Add it to the SConscript.
Title: Re: minisphere 1.5.3
Post by: N E O on July 18, 2015, 06:59:28 pm

You have to link to allegro_main on OSX (and only OSX), I forgot about that.  Add it to the SConscript.

Just did it, compiles!

Just ran without a startup or any games (it automatically gives an Open File dialog, which is nice), got the following error on the console when canceling:

Code: [Select]

Setting up jump points for longjmp
Looking for a game to launch
Opening game ''
engine(32428,0x10ff94000) malloc: *** error for object 0x7fe271831200: pointer being freed was not allocated
*** set a breakpoint in malloc_error_break to debug
Abort trap: 6


edit: Running a game with just `Abort("Hello, mixer!");` in the game() function results in the following error on closing:

Code: [Select]

Shutting down Audialis
engine(32486,0x104bb1000) malloc: *** error for object 0x7ff8a201fc00: pointer being freed was not allocated
*** set a breakpoint in malloc_error_break to debug
Abort trap: 6
Title: Re: minisphere 1.5.3
Post by: Fat Cerberus on July 18, 2015, 07:04:03 pm
Hm, I'll look into that.  I don't usually cancel the file dialog, so maybe I missed a bug.
Title: Re: minisphere 1.5.3
Post by: N E O on July 18, 2015, 07:16:27 pm
Edited post w/new error.
Title: Re: minisphere 1.5.3
Post by: Fat Cerberus on July 18, 2015, 07:34:19 pm
These are weird.  They look like double free bugs, but I would think they should have shown up in the Windows and Linux builds by now if so.  Does it always crash shutting down Audialis?  Or is it in a different spot each time?
Title: Re: minisphere 1.5.3
Post by: Flying Jester on July 18, 2015, 08:18:45 pm
Try using lldb to see where crash is (or at least the second free)?
Title: Re: minisphere 1.5.3
Post by: N E O on July 18, 2015, 09:26:44 pm

Try using lldb to see where crash is (or at least the second free)?



lldb output for running engine but canceling the Open File:

Code: [Select]

[ ... ]
Setting up jump points for longjmp
Looking for a game to launch
Opening game ''
engine(32663,0x102a9e000) malloc: *** error for object 0x10081be00: pointer being freed was not allocated
*** set a breakpoint in malloc_error_break to debug
Process 32663 stopped
* thread #6: tid = 0x325f34, 0x00007fff96371866 libsystem_kernel.dylib`__pthread_kill + 10, stop reason = signal SIGABRT
    frame #0: 0x00007fff96371866 libsystem_kernel.dylib`__pthread_kill + 10
libsystem_kernel.dylib`__pthread_kill + 10:
-> 0x7fff96371866:  jae    0x7fff96371870            ; __pthread_kill + 20
   0x7fff96371868:  movq   %rax, %rdi
   0x7fff9637186b:  jmp    0x7fff9636e175            ; cerror_nocancel
   0x7fff96371870:  retq  


lldb output for running engine with my one-liner:
Code: [Select]

[ ... ]
Shutting down spriteset manager
Shutting down Audialis
engine(32687,0x102a9e000) malloc: *** error for object 0x101809a00: pointer being freed was not allocated
*** set a breakpoint in malloc_error_break to debug
Process 32687 stopped
* thread #6: tid = 0x3263bb, 0x00007fff96371866 libsystem_kernel.dylib`__pthread_kill + 10, stop reason = signal SIGABRT
    frame #0: 0x00007fff96371866 libsystem_kernel.dylib`__pthread_kill + 10
libsystem_kernel.dylib`__pthread_kill + 10:
-> 0x7fff96371866:  jae    0x7fff96371870            ; __pthread_kill + 20
   0x7fff96371868:  movq   %rax, %rdi
   0x7fff9637186b:  jmp    0x7fff9636e175            ; cerror_nocancel
   0x7fff96371870:  retq  


I don't know how to read debugger, sorry.
Title: Re: minisphere 1.5.3
Post by: Fat Cerberus on July 18, 2015, 09:30:52 pm
No stack trace?

Interesting that it's crashing at the exact same instruction, though.  Which means it's probably the same root cause.  Unfortunately I don't have a Mac to test this on myself.
Title: Re: minisphere 1.5.3
Post by: Flying Jester on July 18, 2015, 09:41:40 pm
At the crash, type `bt` to get a backtrace.

Then, I suggest typing `frame s 1` to see the second frame, and continuing this (but with increasing stack frame numbers) until you get an actual snippet of source with line numbers rather than just assembly.

Really unfortunately, llbd is much more verbose and difficult to use than gdb :(
Title: Re: minisphere 1.5.3
Post by: Fat Cerberus on July 18, 2015, 10:32:58 pm
@NEO:
Okay, from what I can tell from the console output, the first one it looks like the file dialog on OSX is returning true when it shouldn't, judging by this line: Opening game '').  That should be simple enough to fix.

The Audialis shutdown crash I think I have a lead on, but I'd need to see your entire console log, from "Parsing command line" on.
Title: Re: minisphere 1.5.3
Post by: N E O on July 18, 2015, 11:41:20 pm

The Audialis shutdown crash I think I have a lead on, but I'd need to see your entire console log, from "Parsing command line" on.


Dump:
Code: [Select]

Parsing command line
  Game path: <none provided>
  Frameskip limit: 5 frames
  CPU throttle: ON
  Console verbosity: L1

Initializing Allegro
Initializing Dyad
Loading system configuration
Initializing async manager
Initializing Mersenne Twister
Initializing Galileo
Initializing Audialis
Initializing input
Initializing spriteset manager
Initializing map engine
Initializing persons manager
Initializing Duktape
Initializing CoffeeScript
  Error evaluating compiler script  RangeError: compiler recursion limit (line 8)'CoffeeScript' not definedInitializing Sphere API
  v2.0 (minisphere 1.5.2)
  minisphere
  sphere-legacy-api
  sphere-obj-constructors
  sphere-obj-props
  sphere-audialis
  sphere-coffeescript
  sphere-commonjs
  sphere-galileo
  sphere-map-engine
  sphere-spherefs
  minisphere-async-api
  minisphere-new-sockets
  minisphere-rng-object
  minisphere-galileo-shaders
  frameskip-api
  set-script-function
Setting up jump points for longjmp
Looking for a game to launch
Opening game '/Users/lux/dev/minisphere/bin/games/nmix/game.sgm'
  Title: NMix
  Author: NeoLogiX
  Resolution: 320x240
Creating render window
Initializing shader manager

Fragment shader compile log:
ERROR: 0:10: 'blend_mode' : syntax error syntax error

  System shaders not found
Loading system font
Calling game()

JS Error: game.js:6 - Error: Hello, mixer!
Shutting down map engine
Shutting down persons manager
Shutting down input
Shutting down Duktape
Shutting down Dyad
Shutting down spriteset manager
Shutting down Audialis
engine(32687,0x102a9e000) malloc: *** error for object 0x101809a00: pointer being freed was not allocated
*** set a breakpoint in malloc_error_break to debug
Process 32687 stopped
* thread #6: tid = 0x3263bb, 0x00007fff96371866 libsystem_kernel.dylib`__pthread_kill + 10, stop reason = signal SIGABRT
    frame #0: 0x00007fff96371866 libsystem_kernel.dylib`__pthread_kill + 10
libsystem_kernel.dylib`__pthread_kill + 10:
-> 0x7fff96371866:  jae    0x7fff96371870            ; __pthread_kill + 20
   0x7fff96371868:  movq   %rax, %rdi
   0x7fff9637186b:  jmp    0x7fff9636e175            ; cerror_nocancel
   0x7fff96371870:  retq  


Re backtrace - `bt` and interesting frames are as follows:

Code: [Select]

* thread #6: tid = 0x33298d, 0x00007fff96371866 libsystem_kernel.dylib`__pthread_kill + 10, stop reason = signal SIGABRT
  * frame #0: 0x00007fff96371866 libsystem_kernel.dylib`__pthread_kill + 10
    frame #1: 0x00007fff92a1c35c libsystem_pthread.dylib`pthread_kill + 92
    frame #2: 0x00007fff96f58b1a libsystem_c.dylib`abort + 125
    frame #3: 0x00007fff9161707f libsystem_malloc.dylib`free + 411
    frame #4: 0x00000001000e29c6 liballegro_audio.5.1.dylib`_aqueue_deallocate_voice(voice=0x00000001005359f0) + 70 at aqueue.m:212
    frame #5: 0x00000001000e1a38 liballegro_audio.5.1.dylib`al_destroy_voice(voice=0x00000001005359f0) + 40 at kcm_voice.c:114
    frame #6: 0x0000000100164bab liballegro.5.1.dylib`_al_run_destructors(dtors=0x0000000100535980) + 155 at dtor.c:117
    frame #7: 0x00000001000d8675 liballegro_audio.5.1.dylib`_al_kcm_shutdown_destructors + 21 at kcm_dtor.c:46
    frame #8: 0x00000001000d74e8 liballegro_audio.5.1.dylib`al_uninstall_audio + 24 at audio.c:401
    frame #9: 0x0000000100166108 liballegro.5.1.dylib`_al_run_exit_funcs + 136 at exitfunc.c:92
    frame #10: 0x000000010016cac5 liballegro.5.1.dylib`al_uninstall_system + 21 at system.c:298
    frame #11: 0x00007fff96f59794 libsystem_c.dylib`__cxa_finalize + 164
    frame #12: 0x00007fff96f59a4c libsystem_c.dylib`exit + 22
    frame #13: 0x00000001001a77be liballegro.5.1.dylib`+[AllegroAppDelegate app_main:] [inlined] call_user_main + 30 at osx_app_delegate.m:214
    frame #14: 0x00000001001a77a4 liballegro.5.1.dylib`+[AllegroAppDelegate app_main:](self=<unavailable>, _cmd=<unavailable>, arg=<unavailable>) + 4 at osx_app_delegate.m:225
    frame #15: 0x00007fff917d0d8b Foundation`__NSThread__main__ + 1318
    frame #16: 0x00007fff92a1b899 libsystem_pthread.dylib`_pthread_body + 138
    frame #17: 0x00007fff92a1b72a libsystem_pthread.dylib`_pthread_start + 137
    frame #18: 0x00007fff92a1ffc9 libsystem_pthread.dylib`thread_start + 13


Code: [Select]

frame #4: 0x00000001000e29c6 liballegro_audio.5.1.dylib`_aqueue_deallocate_voice(voice=0x00000001005359f0) + 70 at aqueue.m:212
   209 static void _aqueue_deallocate_voice(ALLEGRO_VOICE *voice)
   210 {
   211    al_free(voice->extra);
-> 212    al_free(silence);
   213    voice->extra = NULL;
   214 }
   215

frame #5: 0x00000001000e1a38 liballegro_audio.5.1.dylib`al_destroy_voice(voice=0x00000001005359f0) + 40 at kcm_voice.c:114
   111       ASSERT(al_get_voice_playing(voice) == false);
   112
   113       /* We do NOT lock the voice mutex when calling this method. */
-> 114       voice->driver->deallocate_voice(voice);
   115       al_destroy_mutex(voice->mutex);
   116       al_destroy_cond(voice->cond);
   117



The problem very well could be audio. Among other things, I got warnings about missing libdumb and libvorbis for some reason during early attempts to compile, and when I followed the wrong instructions early on and CMake'ed it to be a Framework it kept giving "unexpectedly closed" errors during the process.
Title: Re: minisphere 1.5.3
Post by: Fat Cerberus on July 19, 2015, 12:04:40 am
Looks like the crash is inside of Allegro.  What's interesting is that it's crashing on trying to free the silence buffer...  Looks like I'll be putting in another bug report. :P

Also odd: CoffeeScript errors out, and the shaders fail to compile also.  Not sure what's going on there!
Title: Re: minisphere 1.5.3
Post by: Fat Cerberus on July 19, 2015, 03:02:42 am
Interesting, apparently for whatever reason your system doesn't like uint uniforms in shaders.  That same shader compiles fine on every Windows machine I've tested on, although I can't speak for Linux as I've never seen DaVince's startup listing.  In any case, the uniform in question wasn't even used (it was part of a failed attempt to implement blending in the fragment shader), so I removed it and also cleaned up the CoffeeScript output (I forgot to add newlines).

I did manage to fix (or think I fixed) the crash on canceling the file dialog.  Apparently al_show_native_file_dialog() returns true on OS X on cancel, even though it returns false in that circumstance seemingly everywhere else.  Then again, I probably just misinterpreted the documentation:
Code: [Select]
Returns true on success, false on failure.


I originally interpreted "failure" to mean "the user closed the dialog", but that might not have been the intent, since Allegro provides a different function, al_get_native_file_dialog_count(), which returns the number of files selected.  If the user cancels, the documentation says explicitly that this will return zero.  So that's what I used.
Title: Re: minisphere 1.5.3
Post by: N E O on July 19, 2015, 01:46:59 pm
*** set a breakpoint in malloc_error_break to debug

Just compiled 1.5.3 and same errors when trying to free audio, but seems like it gets there much faster now so whatever you did to fix OSX open file dialog seems to work. How do I set a breakpoint to confirm the above?
Title: Re: minisphere 1.5.3
Post by: Fat Cerberus on July 19, 2015, 11:47:50 pm
I don't know anything about lldb, but could you checkout the latest source, run the engine with the option --log-level 4 and post the console output?
Title: Re: minisphere 1.5.3
Post by: Flying Jester on July 20, 2015, 01:03:33 am
I don't think setting a breakpoint there would help much unless you had a really good knowledge of Allegro. You basically need to know exactly what is going on in the function directly above the one you set a breakpoint at the edge of.

In any case, in lldb it looks a little like this:
Code: [Select]
breakpoint set -f <filename> -l <line>

You need to set breakpoints either before you type `run` or at the prompt you get by hitting ctrl+c at the terminal while the program is running (or when another breakpoint is triggered, either from a set breakpoint or from a segfault)

I don't recall the syntax for setting it at edges of certain functions. This is where lldb's syntax is really annoying. Everywhere else it's basically just an extra letter here or there, but with breakpoints its fairly obtuse compared to gdb, Intel's debugger, and MS's command line debugger.
Title: Re: minisphere 1.5.3
Post by: Fat Cerberus on July 20, 2015, 01:45:54 am
MS has a command-line debugger?  I never knew that.  The only one I ever remember is the DEBUG command in DOS.  And that was more of a disassembler than a debugger anyway.

As for this crash, the most interesting part to me is the stack trace.  There is no user code on the stack at all--only Allegro functions and system calls.  this makes no sense to me since the last thing printed to the console is "Shutting down Audialis", whereas in a clean shutdown there are a few more steps after that.  So there should definitely be engine code on the stack at that point, but there clearly isn't.  I'm baffled.

edit: Hey, I have an idea!  Any chance you could run the engine under valgrind?  That tends to find weird memory bugs like this.
Title: Re: minisphere 1.5.3
Post by: N E O on July 20, 2015, 02:53:35 pm

I don't know anything about lldb, but could you checkout the latest source, run the engine with the option --log-level 4 and post the console output?


Log for canceling game load:
Code: [Select]

Parsing command line
  Game path: <none provided>
  Frameskip limit: 5 frames
  CPU throttle: ON
  Console verbosity: L4

Initializing Allegro
Initializing Dyad
Loading system configuration
Opening File 0 as '~sys/system.ini'
Initializing async manager
Initializing Mersenne Twister
Seeding MT19937 (1437418155)
Initializing Galileo
Initializing Audialis
Creating new Mixer 0 at 44 kHz
  Format: 2ch 44100 Hz, 16-bit
Incrementing Mixer 0 refcount, new: 1
Initializing input
Opening File 1 as '~sys/../minisphere.conf'
Reading key 'keymap_Player1_MENU' from File 1
Reading key 'keymap_Player1_UP' from File 1
Reading key 'keymap_Player1_DOWN' from File 1
Reading key 'keymap_Player1_LEFT' from File 1
Reading key 'keymap_Player1_RIGHT' from File 1
Reading key 'keymap_Player1_A' from File 1
Reading key 'keymap_Player1_B' from File 1
Reading key 'keymap_Player1_X' from File 1
Reading key 'keymap_Player1_Y' from File 1
Reading key 'keymap_Player2_MENU' from File 1
Reading key 'keymap_Player2_UP' from File 1
Reading key 'keymap_Player2_DOWN' from File 1
Reading key 'keymap_Player2_LEFT' from File 1
Reading key 'keymap_Player2_RIGHT' from File 1
Reading key 'keymap_Player2_A' from File 1
Reading key 'keymap_Player2_B' from File 1
Reading key 'keymap_Player2_X' from File 1
Reading key 'keymap_Player2_Y' from File 1
Reading key 'keymap_Player3_MENU' from File 1
Reading key 'keymap_Player3_UP' from File 1
Reading key 'keymap_Player3_DOWN' from File 1
Reading key 'keymap_Player3_LEFT' from File 1
Reading key 'keymap_Player3_RIGHT' from File 1
Reading key 'keymap_Player3_A' from File 1
Reading key 'keymap_Player3_B' from File 1
Reading key 'keymap_Player3_X' from File 1
Reading key 'keymap_Player3_Y' from File 1
Reading key 'keymap_Player4_MENU' from File 1
Reading key 'keymap_Player4_UP' from File 1
Reading key 'keymap_Player4_DOWN' from File 1
Reading key 'keymap_Player4_LEFT' from File 1
Reading key 'keymap_Player4_RIGHT' from File 1
Reading key 'keymap_Player4_A' from File 1
Reading key 'keymap_Player4_B' from File 1
Reading key 'keymap_Player4_X' from File 1
Reading key 'keymap_Player4_Y' from File 1
File 1 no longer in use, deallocating
Initializing spriteset manager
Initializing map engine
Initializing persons manager
Initializing JavaScript
  Duktape v1.2.2
  Error evaluating compiler script
  RangeError: compiler recursion limit (line 8)
  CoffeeScript support not enabled
Initializing Sphere API
  v2.0 (minisphere 1.5.3)
  minisphere
  sphere-legacy-api
  sphere-obj-constructors
  sphere-obj-props
  sphere-audialis
  sphere-coffeescript
  sphere-commonjs
  sphere-galileo
  sphere-map-engine
  sphere-spherefs
  minisphere-async-api
  minisphere-galileo-shaders
  minisphere-new-sockets
  minisphere-rng-object
  frameskip-api
  set-script-function
Reading key 'Arrow' from File 0
Loading Image 0 as '~sys/pointer.png'
Reading key 'UpArrow' from File 0
Loading Image 1 as '~sys/up_arrow.png'
Reading key 'DownArrow' from File 0
Loading Image 2 as '~sys/down_arrow.png'
Reading key 'WindowStyle' from File 0
Reading 16x16 Image 3 from open file
Reading 16x16 Image 4 from open file
Reading 16x16 Image 5 from open file
Reading 16x16 Image 6 from open file
Reading 16x16 Image 7 from open file
Reading 16x16 Image 8 from open file
Reading 16x16 Image 9 from open file
Reading 16x16 Image 10 from open file
Reading 16x16 Image 11 from open file
Setting up jump points for longjmp
Looking for a game to launch
engine(37145,0x10f111000) malloc: *** error for object 0x7fd01480da00: pointer being freed was not allocated
*** set a breakpoint in malloc_error_break to debug
Abort trap: 6


Re valgrind - I don't know how to use valgrind, but homebrew seems to let me install it.
Title: Re: minisphere 1.5.3
Post by: Fat Cerberus on July 20, 2015, 03:40:59 pm
And for your little demo game?
Title: Re: minisphere 1.5.3
Post by: N E O on July 20, 2015, 05:11:30 pm

And for your little demo game?


Sorry, I forgot, here it is:

Code: [Select]

Parsing command line
  Game path: <none provided>
  Frameskip limit: 5 frames
  CPU throttle: ON
  Console verbosity: L4

Initializing Allegro
Initializing Dyad
Loading system configuration
Opening File 0 as '~sys/system.ini'
Initializing async manager
Initializing Mersenne Twister
Seeding MT19937 (1437426614)
Initializing Galileo
Initializing Audialis
Creating new Mixer 0 at 44 kHz
  Format: 2ch 44100 Hz, 16-bit
Incrementing Mixer 0 refcount, new: 1
Initializing input
Opening File 1 as '~sys/../minisphere.conf'
Reading key 'keymap_Player1_MENU' from File 1
Reading key 'keymap_Player1_UP' from File 1
Reading key 'keymap_Player1_DOWN' from File 1
Reading key 'keymap_Player1_LEFT' from File 1
Reading key 'keymap_Player1_RIGHT' from File 1
Reading key 'keymap_Player1_A' from File 1
Reading key 'keymap_Player1_B' from File 1
Reading key 'keymap_Player1_X' from File 1
Reading key 'keymap_Player1_Y' from File 1
Reading key 'keymap_Player2_MENU' from File 1
Reading key 'keymap_Player2_UP' from File 1
Reading key 'keymap_Player2_DOWN' from File 1
Reading key 'keymap_Player2_LEFT' from File 1
Reading key 'keymap_Player2_RIGHT' from File 1
Reading key 'keymap_Player2_A' from File 1
Reading key 'keymap_Player2_B' from File 1
Reading key 'keymap_Player2_X' from File 1
Reading key 'keymap_Player2_Y' from File 1
Reading key 'keymap_Player3_MENU' from File 1
Reading key 'keymap_Player3_UP' from File 1
Reading key 'keymap_Player3_DOWN' from File 1
Reading key 'keymap_Player3_LEFT' from File 1
Reading key 'keymap_Player3_RIGHT' from File 1
Reading key 'keymap_Player3_A' from File 1
Reading key 'keymap_Player3_B' from File 1
Reading key 'keymap_Player3_X' from File 1
Reading key 'keymap_Player3_Y' from File 1
Reading key 'keymap_Player4_MENU' from File 1
Reading key 'keymap_Player4_UP' from File 1
Reading key 'keymap_Player4_DOWN' from File 1
Reading key 'keymap_Player4_LEFT' from File 1
Reading key 'keymap_Player4_RIGHT' from File 1
Reading key 'keymap_Player4_A' from File 1
Reading key 'keymap_Player4_B' from File 1
Reading key 'keymap_Player4_X' from File 1
Reading key 'keymap_Player4_Y' from File 1
File 1 no longer in use, deallocating
Initializing spriteset manager
Initializing map engine
Initializing persons manager
Initializing JavaScript
  Duktape v1.2.2
  Error evaluating compiler script
  RangeError: compiler recursion limit (line 8)
  CoffeeScript support not enabled
Initializing Sphere API
  v2.0 (minisphere 1.5.3)
  minisphere
  sphere-legacy-api
  sphere-obj-constructors
  sphere-obj-props
  sphere-audialis
  sphere-coffeescript
  sphere-commonjs
  sphere-galileo
  sphere-map-engine
  sphere-spherefs
  minisphere-async-api
  minisphere-galileo-shaders
  minisphere-new-sockets
  minisphere-rng-object
  frameskip-api
  set-script-function
Reading key 'Arrow' from File 0
Loading Image 0 as '~sys/pointer.png'
Reading key 'UpArrow' from File 0
Loading Image 1 as '~sys/up_arrow.png'
Reading key 'DownArrow' from File 0
Loading Image 2 as '~sys/down_arrow.png'
Reading key 'WindowStyle' from File 0
Reading 16x16 Image 3 from open file
Reading 16x16 Image 4 from open file
Reading 16x16 Image 5 from open file
Reading 16x16 Image 6 from open file
Reading 16x16 Image 7 from open file
Reading 16x16 Image 8 from open file
Reading 16x16 Image 9 from open file
Reading 16x16 Image 10 from open file
Reading 16x16 Image 11 from open file
Setting up jump points for longjmp
Looking for a game to launch
Opening game '/Users/lux/dev/minisphere/bin/games/nmix/game.sgm'
  Title: NMix
  Author: NeoLogiX
  Resolution: 320x240
Creating render window
Loading Image 12 as '~sgm/icon.png'
  Failed to load Image 12Loading Image 12 as '~sys/icon.png'
Decrementing Image 12 refcount, new: 0
Image 12 no longer in use, deallocating
Opening File 2 as 'keymap.mini'
Reading key 'keymap_Player1_MENU' from File 2
Reading key 'keymap_Player1_UP' from File 2
Reading key 'keymap_Player1_DOWN' from File 2
Reading key 'keymap_Player1_LEFT' from File 2
Reading key 'keymap_Player1_RIGHT' from File 2
Reading key 'keymap_Player1_A' from File 2
Reading key 'keymap_Player1_B' from File 2
Reading key 'keymap_Player1_X' from File 2
Reading key 'keymap_Player1_Y' from File 2
Reading key 'keymap_Player2_MENU' from File 2
Reading key 'keymap_Player2_UP' from File 2
Reading key 'keymap_Player2_DOWN' from File 2
Reading key 'keymap_Player2_LEFT' from File 2
Reading key 'keymap_Player2_RIGHT' from File 2
Reading key 'keymap_Player2_A' from File 2
Reading key 'keymap_Player2_B' from File 2
Reading key 'keymap_Player2_X' from File 2
Reading key 'keymap_Player2_Y' from File 2
Reading key 'keymap_Player3_MENU' from File 2
Reading key 'keymap_Player3_UP' from File 2
Reading key 'keymap_Player3_DOWN' from File 2
Reading key 'keymap_Player3_LEFT' from File 2
Reading key 'keymap_Player3_RIGHT' from File 2
Reading key 'keymap_Player3_A' from File 2
Reading key 'keymap_Player3_B' from File 2
Reading key 'keymap_Player3_X' from File 2
Reading key 'keymap_Player3_Y' from File 2
Reading key 'keymap_Player4_MENU' from File 2
Reading key 'keymap_Player4_UP' from File 2
Reading key 'keymap_Player4_DOWN' from File 2
Reading key 'keymap_Player4_LEFT' from File 2
Reading key 'keymap_Player4_RIGHT' from File 2
Reading key 'keymap_Player4_A' from File 2
Reading key 'keymap_Player4_B' from File 2
Reading key 'keymap_Player4_X' from File 2
Reading key 'keymap_Player4_Y' from File 2
File 2 no longer in use, deallocating
Initializing shader support
Loading system font
Reading key 'Font' from File 0
Loading Font 0 as '~sys/system.rfn'
Creating Image 13 at 128x192
Creating Image 14 as 8x12 subimage of Image 13
Creating Image 15 as 8x12 subimage of Image 13
Creating Image 16 as 8x12 subimage of Image 13
Creating Image 17 as 8x12 subimage of Image 13
Creating Image 18 as 8x12 subimage of Image 13
Creating Image 19 as 8x12 subimage of Image 13
Creating Image 20 as 8x12 subimage of Image 13
Creating Image 21 as 8x12 subimage of Image 13
Creating Image 22 as 8x12 subimage of Image 13
Creating Image 23 as 8x12 subimage of Image 13
Creating Image 24 as 8x12 subimage of Image 13
Creating Image 25 as 8x12 subimage of Image 13
Creating Image 26 as 8x12 subimage of Image 13
Creating Image 27 as 8x12 subimage of Image 13
Creating Image 28 as 8x12 subimage of Image 13
Creating Image 29 as 8x12 subimage of Image 13
Creating Image 30 as 8x12 subimage of Image 13
Creating Image 31 as 8x12 subimage of Image 13
Creating Image 32 as 8x12 subimage of Image 13
Creating Image 33 as 8x12 subimage of Image 13
Creating Image 34 as 8x12 subimage of Image 13
Creating Image 35 as 8x12 subimage of Image 13
Creating Image 36 as 8x12 subimage of Image 13
Creating Image 37 as 8x12 subimage of Image 13
Creating Image 38 as 8x12 subimage of Image 13
Creating Image 39 as 8x12 subimage of Image 13
Creating Image 40 as 8x12 subimage of Image 13
Creating Image 41 as 8x12 subimage of Image 13
Creating Image 42 as 8x12 subimage of Image 13
Creating Image 43 as 8x12 subimage of Image 13
Creating Image 44 as 8x12 subimage of Image 13
Creating Image 45 as 8x12 subimage of Image 13
Creating Image 46 as 8x12 subimage of Image 13
Creating Image 47 as 3x12 subimage of Image 13
Creating Image 48 as 5x12 subimage of Image 13
Creating Image 49 as 8x12 subimage of Image 13
Creating Image 50 as 7x12 subimage of Image 13
Creating Image 51 as 8x12 subimage of Image 13
Creating Image 52 as 8x12 subimage of Image 13
Creating Image 53 as 3x12 subimage of Image 13
Creating Image 54 as 5x12 subimage of Image 13
Creating Image 55 as 5x12 subimage of Image 13
Creating Image 56 as 7x12 subimage of Image 13
Creating Image 57 as 7x12 subimage of Image 13
Creating Image 58 as 4x12 subimage of Image 13
Creating Image 59 as 5x12 subimage of Image 13
Creating Image 60 as 3x12 subimage of Image 13
Creating Image 61 as 6x12 subimage of Image 13
Creating Image 62 as 7x12 subimage of Image 13
Creating Image 63 as 7x12 subimage of Image 13
Creating Image 64 as 6x12 subimage of Image 13
Creating Image 65 as 6x12 subimage of Image 13
Creating Image 66 as 7x12 subimage of Image 13
Creating Image 67 as 6x12 subimage of Image 13
Creating Image 68 as 7x12 subimage of Image 13
Creating Image 69 as 7x12 subimage of Image 13
Creating Image 70 as 7x12 subimage of Image 13
Creating Image 71 as 7x12 subimage of Image 13
Creating Image 72 as 3x12 subimage of Image 13
Creating Image 73 as 4x12 subimage of Image 13
Creating Image 74 as 6x12 subimage of Image 13
Creating Image 75 as 7x12 subimage of Image 13
Creating Image 76 as 6x12 subimage of Image 13
Creating Image 77 as 6x12 subimage of Image 13
Creating Image 78 as 8x12 subimage of Image 13
Creating Image 79 as 7x12 subimage of Image 13
Creating Image 80 as 7x12 subimage of Image 13
Creating Image 81 as 7x12 subimage of Image 13
Creating Image 82 as 7x12 subimage of Image 13
Creating Image 83 as 7x12 subimage of Image 13
Creating Image 84 as 7x12 subimage of Image 13
Creating Image 85 as 7x12 subimage of Image 13
Creating Image 86 as 7x12 subimage of Image 13
Creating Image 87 as 5x12 subimage of Image 13
Creating Image 88 as 6x12 subimage of Image 13
Creating Image 89 as 8x12 subimage of Image 13
Creating Image 90 as 7x12 subimage of Image 13
Creating Image 91 as 7x12 subimage of Image 13
Creating Image 92 as 7x12 subimage of Image 13
Creating Image 93 as 7x12 subimage of Image 13
Creating Image 94 as 7x12 subimage of Image 13
Creating Image 95 as 7x12 subimage of Image 13
Creating Image 96 as 8x12 subimage of Image 13
Creating Image 97 as 6x12 subimage of Image 13
Creating Image 98 as 7x12 subimage of Image 13
Creating Image 99 as 7x12 subimage of Image 13
Creating Image 100 as 7x12 subimage of Image 13
Creating Image 101 as 7x12 subimage of Image 13
Creating Image 102 as 7x12 subimage of Image 13
Creating Image 103 as 7x12 subimage of Image 13
Creating Image 104 as 7x12 subimage of Image 13
Creating Image 105 as 4x12 subimage of Image 13
Creating Image 106 as 6x12 subimage of Image 13
Creating Image 107 as 4x12 subimage of Image 13
Creating Image 108 as 7x12 subimage of Image 13
Creating Image 109 as 8x12 subimage of Image 13
Creating Image 110 as 4x12 subimage of Image 13
Creating Image 111 as 7x12 subimage of Image 13
Creating Image 112 as 7x12 subimage of Image 13
Creating Image 113 as 7x12 subimage of Image 13
Creating Image 114 as 7x12 subimage of Image 13
Creating Image 115 as 7x12 subimage of Image 13
Creating Image 116 as 6x12 subimage of Image 13
Creating Image 117 as 7x12 subimage of Image 13
Creating Image 118 as 7x12 subimage of Image 13
Creating Image 119 as 5x12 subimage of Image 13
Creating Image 120 as 5x12 subimage of Image 13
Creating Image 121 as 7x12 subimage of Image 13
Creating Image 122 as 5x12 subimage of Image 13
Creating Image 123 as 7x12 subimage of Image 13
Creating Image 124 as 7x12 subimage of Image 13
Creating Image 125 as 7x12 subimage of Image 13
Creating Image 126 as 7x12 subimage of Image 13
Creating Image 127 as 7x12 subimage of Image 13
Creating Image 128 as 6x12 subimage of Image 13
Creating Image 129 as 7x12 subimage of Image 13
Creating Image 130 as 6x12 subimage of Image 13
Creating Image 131 as 7x12 subimage of Image 13
Creating Image 132 as 7x12 subimage of Image 13
Creating Image 133 as 7x12 subimage of Image 13
Creating Image 134 as 7x12 subimage of Image 13
Creating Image 135 as 7x12 subimage of Image 13
Creating Image 136 as 7x12 subimage of Image 13
Creating Image 137 as 5x12 subimage of Image 13
Creating Image 138 as 3x12 subimage of Image 13
Creating Image 139 as 5x12 subimage of Image 13
Creating Image 140 as 8x12 subimage of Image 13
Creating Image 141 as 6x12 subimage of Image 13
Creating Image 142 as 8x12 subimage of Image 13
Creating Image 143 as 8x12 subimage of Image 13
Creating Image 144 as 8x12 subimage of Image 13
Creating Image 145 as 8x12 subimage of Image 13
Creating Image 146 as 8x12 subimage of Image 13
Creating Image 147 as 8x12 subimage of Image 13
Creating Image 148 as 8x12 subimage of Image 13
Creating Image 149 as 8x12 subimage of Image 13
Creating Image 150 as 8x12 subimage of Image 13
Creating Image 151 as 8x12 subimage of Image 13
Creating Image 152 as 8x12 subimage of Image 13
Creating Image 153 as 8x12 subimage of Image 13
Creating Image 154 as 8x12 subimage of Image 13
Creating Image 155 as 8x12 subimage of Image 13
Creating Image 156 as 8x12 subimage of Image 13
Creating Image 157 as 8x12 subimage of Image 13
Creating Image 158 as 8x12 subimage of Image 13
Creating Image 159 as 8x12 subimage of Image 13
Creating Image 160 as 8x12 subimage of Image 13
Creating Image 161 as 8x12 subimage of Image 13
Creating Image 162 as 8x12 subimage of Image 13
Creating Image 163 as 8x12 subimage of Image 13
Creating Image 164 as 8x12 subimage of Image 13
Creating Image 165 as 8x12 subimage of Image 13
Creating Image 166 as 8x12 subimage of Image 13
Creating Image 167 as 8x12 subimage of Image 13
Creating Image 168 as 8x12 subimage of Image 13
Creating Image 169 as 8x12 subimage of Image 13
Creating Image 170 as 8x12 subimage of Image 13
Creating Image 171 as 8x12 subimage of Image 13
Creating Image 172 as 8x12 subimage of Image 13
Creating Image 173 as 8x12 subimage of Image 13
Creating Image 174 as 8x12 subimage of Image 13
Creating Image 175 as 8x12 subimage of Image 13
Creating Image 176 as 8x12 subimage of Image 13
Creating Image 177 as 8x12 subimage of Image 13
Creating Image 178 as 8x12 subimage of Image 13
Creating Image 179 as 8x12 subimage of Image 13
Creating Image 180 as 8x12 subimage of Image 13
Creating Image 181 as 8x12 subimage of Image 13
Creating Image 182 as 8x12 subimage of Image 13
Creating Image 183 as 8x12 subimage of Image 13
Creating Image 184 as 8x12 subimage of Image 13
Creating Image 185 as 8x12 subimage of Image 13
Creating Image 186 as 8x12 subimage of Image 13
Creating Image 187 as 8x12 subimage of Image 13
Creating Image 188 as 8x12 subimage of Image 13
Creating Image 189 as 8x12 subimage of Image 13
Creating Image 190 as 8x12 subimage of Image 13
Creating Image 191 as 8x12 subimage of Image 13
Creating Image 192 as 8x12 subimage of Image 13
Creating Image 193 as 8x12 subimage of Image 13
Creating Image 194 as 8x12 subimage of Image 13
Creating Image 195 as 8x12 subimage of Image 13
Creating Image 196 as 8x12 subimage of Image 13
Creating Image 197 as 8x12 subimage of Image 13
Creating Image 198 as 8x12 subimage of Image 13
Creating Image 199 as 8x12 subimage of Image 13
Creating Image 200 as 8x12 subimage of Image 13
Creating Image 201 as 8x12 subimage of Image 13
Creating Image 202 as 8x12 subimage of Image 13
Creating Image 203 as 8x12 subimage of Image 13
Creating Image 204 as 8x12 subimage of Image 13
Creating Image 205 as 8x12 subimage of Image 13
Creating Image 206 as 8x12 subimage of Image 13
Creating Image 207 as 8x12 subimage of Image 13
Creating Image 208 as 8x12 subimage of Image 13
Creating Image 209 as 8x12 subimage of Image 13
Creating Image 210 as 8x12 subimage of Image 13
Creating Image 211 as 8x12 subimage of Image 13
Creating Image 212 as 8x12 subimage of Image 13
Creating Image 213 as 8x12 subimage of Image 13
Creating Image 214 as 8x12 subimage of Image 13
Creating Image 215 as 8x12 subimage of Image 13
Creating Image 216 as 8x12 subimage of Image 13
Creating Image 217 as 8x12 subimage of Image 13
Creating Image 218 as 8x12 subimage of Image 13
Creating Image 219 as 8x12 subimage of Image 13
Creating Image 220 as 8x12 subimage of Image 13
Creating Image 221 as 8x12 subimage of Image 13
Creating Image 222 as 8x12 subimage of Image 13
Creating Image 223 as 8x12 subimage of Image 13
Creating Image 224 as 8x12 subimage of Image 13
Creating Image 225 as 8x12 subimage of Image 13
Creating Image 226 as 8x12 subimage of Image 13
Creating Image 227 as 8x12 subimage of Image 13
Creating Image 228 as 8x12 subimage of Image 13
Creating Image 229 as 8x12 subimage of Image 13
Creating Image 230 as 8x12 subimage of Image 13
Creating Image 231 as 8x12 subimage of Image 13
Creating Image 232 as 8x12 subimage of Image 13
Creating Image 233 as 8x12 subimage of Image 13
Creating Image 234 as 8x12 subimage of Image 13
Creating Image 235 as 8x12 subimage of Image 13
Creating Image 236 as 8x12 subimage of Image 13
Creating Image 237 as 8x12 subimage of Image 13
Creating Image 238 as 8x12 subimage of Image 13
Creating Image 239 as 8x12 subimage of Image 13
Creating Image 240 as 8x12 subimage of Image 13
Creating Image 241 as 8x12 subimage of Image 13
Creating Image 242 as 8x12 subimage of Image 13
Creating Image 243 as 8x12 subimage of Image 13
Creating Image 244 as 8x12 subimage of Image 13
Creating Image 245 as 8x12 subimage of Image 13
Creating Image 246 as 8x12 subimage of Image 13
Creating Image 247 as 8x12 subimage of Image 13
Creating Image 248 as 8x12 subimage of Image 13
Creating Image 249 as 8x12 subimage of Image 13
Creating Image 250 as 8x12 subimage of Image 13
Creating Image 251 as 8x12 subimage of Image 13
Creating Image 252 as 8x12 subimage of Image 13
Creating Image 253 as 8x12 subimage of Image 13
Creating Image 254 as 8x12 subimage of Image 13
Creating Image 255 as 8x12 subimage of Image 13
Creating Image 256 as 8x12 subimage of Image 13
Creating Image 257 as 8x12 subimage of Image 13
Creating Image 258 as 8x12 subimage of Image 13
Creating Image 259 as 8x12 subimage of Image 13
Creating Image 260 as 8x12 subimage of Image 13
Creating Image 261 as 8x12 subimage of Image 13
Creating Image 262 as 8x12 subimage of Image 13
Creating Image 263 as 8x12 subimage of Image 13
Creating Image 264 as 8x12 subimage of Image 13
Creating Image 265 as 8x12 subimage of Image 13
Creating Image 266 as 8x12 subimage of Image 13
Creating Image 267 as 8x12 subimage of Image 13
Creating Image 268 as 8x12 subimage of Image 13
Creating Image 269 as 8x12 subimage of Image 13
Decrementing Image 13 refcount, new: 257
Decrementing Image 13 refcount, new: 256
Incrementing Font 0 refcount, new: 1
Calling game()

JS Error: game.js:6 - Error: Hello, mixer!
Shutting down map engine
Shutting down persons manager
Shutting down input
Shutting down Duktape
Shutting down Dyad
Shutting down spriteset manager
  Objects created: 0
  Cache hits: 0
Shutting down Audialis
Decrementing Mixer 0 refcount, new: 0
Mixer 0 no longer in use, deallocating
engine(37980,0x108c34000) malloc: *** error for object 0x7febeb812200: pointer being freed was not allocated
*** set a breakpoint in malloc_error_break to debug
Abort trap: 6
Title: Re: minisphere 1.5.3
Post by: Fat Cerberus on July 20, 2015, 05:34:10 pm
Okay, so in this case it's crashing trying to free the main mixer.  So why on earth does the stack contain no minisphere code whatsoever...?  The only thing I can think of is that some sort of exception is being raised and Allegro's shim for main() is catching it, obscuring the real source of the bug.

This is quite a stumper.
Title: Re: minisphere 1.5.3
Post by: Flying Jester on July 20, 2015, 05:41:18 pm
Or it's on a different thread.
Title: Re: minisphere 1.5.3
Post by: Fat Cerberus on July 20, 2015, 05:54:56 pm

Or it's on a different thread.


That's what I suspected at first too, but the stack says otherwise: there's a call_user_main() in there, which wouldn't make sense for a worker thread, and I also see an exit() in there, so it's running atexit stuff.  Looks like the main thread to me.

Wait a minute!  I seem to remember that Duktape calls abort() in the case of unrecoverable errors.  Allegro isn't throwing any asserts even though it's clearly a debug build (Allegro source shown in lldb), which means I may be barking up the wrong tree.  CoffeeScript triggered a recursion error during startup, while it works normally here.  So something wonky may actually be going on in Duktape...

NEO, add this define to the top of duktape.c:
Code: (c) [Select]
#define DUK_OPT_ASSERTIONS


And recompile.  See if any asserts fail.
Title: Re: minisphere 1.5.3
Post by: N E O on July 20, 2015, 06:21:26 pm
So something wonky may actually be going on in Duktape...

NEO, add this define to the top of duktape.c:
Code: (c) [Select]
#define DUK_OPT_ASSERTIONS


And recompile.  See if any asserts fail.


The console output doesn't show any failed asserts, no.
Title: Re: minisphere 1.5.3
Post by: Fat Cerberus on July 21, 2015, 12:46:07 am
Hm, well it was worth a shot at least.  Having studied your backtrace AGAIN (it was very illuminating, thanks!), I notice an exit() call in there.  So something, somewhere is calling, I assume abort() in response to the crash, and that could be why main is no longer on the stack (do exit()/abort() unwind the stack?).  That's why I suspected Duktape, because I know it will do so in case of an unrecoverable error.

I find it interesting that it still crashes in response to canceling the file dialog, but in a different spot than the crash on shutdown.  I'm curious now, will it run normally if you give it an actual game (not a Hello World stub) to run and only crash on shutdown, or would issues show up sooner...

By the way, not related to the crash, but could you add a define for DUK_OPT_DEEP_C_STACK to duktape.c and let me know if CoffeeScript starts working again (i.e. the RangeError disappears)?
Title: Re: minisphere 1.5.3
Post by: N E O on July 21, 2015, 04:32:19 pm

By the way, not related to the crash, but could you add a define for DUK_OPT_DEEP_C_STACK to duktape.c and let me know if CoffeeScript starts working again (i.e. the RangeError disappears)?

The RangeError does indeed disappear, yes.
Title: Re: minisphere 1.5.3
Post by: Fat Cerberus on July 21, 2015, 04:45:17 pm
Thanks. :D

Now if only I could figure out what's causing these crashes...  I won't rule out that the bug is on my end.  I know I've encountered similar issues in the past where things that should fail end up working on Windows preventing me from reproducing them.  For instance, a while ago DaVince discovered a crash in 1.2.2 that I couldn't reproduce, caused by a double call to fclose().  This has the same effect as a double free in Linux but in Windows it doesn't raise any red flags whatsoever--it succeeds without complaint.  I only figured it out after poring over the RawFile code for a while.
Title: Re: minisphere 1.5.3
Post by: N E O on July 21, 2015, 10:44:21 pm

Thanks. :D

Now if only I could figure out what's causing these crashes...  I won't rule out that the bug is on my end.  I know I've encountered similar issues in the past where things that should fail end up working on Windows preventing me from reproducing them.  For instance, a while ago DaVince discovered a crash in 1.2.2 that I couldn't reproduce, caused by a double call to fclose().  This has the same effect as a double free in Linux but in Windows it doesn't raise any red flags whatsoever--it succeeds without complaint.  I only figured it out after poring over the RawFile code for a while.


If I could understand Allegro better I would help poring over Audialis, since if it likely ends up being a double free to allegro_audio it's almost certainly there.

*sigh* I am so far behind in my independent programming studies and now currently lack motivation to learn anything useful :'(
Title: Re: minisphere 1.6.0
Post by: Fat Cerberus on July 27, 2015, 05:04:09 pm
minisphere 1.6.0 is released.  See changelog for details.

The debugging feature should work, as it just uses the Duktape debug API.  A client needs to be written using Duktape's remote debug protocol to take advantage of it, however:
https://github.com/svaarala/duktape/blob/master/doc/debugger.rst
Title: Re: minisphere 1.6.1
Post by: Fat Cerberus on July 31, 2015, 02:44:27 am
1.6.1 fixes a bug in the Sockets API where listening sockets wouldn't accept connections from IPv4 clients (including local clients, i.e. those connecting to 127.0.0.1).

I can also definitively say the debugging support in 1.6 works great.  I got a proof of concept plugin working in Sphere Studio that just sends a "resume" message to the engine.  The game runs upon receiving this message, so everything's in order so far!  Now to implement full debugger support in Sphere Studio... ;D
Title: Re: minisphere 1.6.1
Post by: Fat Cerberus on August 02, 2015, 03:04:24 am
@NEO, regarding Audialis:
Looks like minisphere isn't at fault here after all, it's an Allegro bug:
https://www.allegro.cc/forums/thread/615559/1015654

Everyone else: The debugger is coming along nicely. :)  Pretty soon we'll all be able to debug Sphere games like any other app!
Title: Re: minisphere 1.6.1
Post by: Fat Cerberus on August 02, 2015, 10:34:04 pm
NEO, could you try building the latest Allegro from the github mirror and let me know if the crashes are gone?
Title: Re: minisphere 1.6.1
Post by: N E O on August 04, 2015, 08:12:48 pm
(building Allegro from Git on OS X for future reference: cd allegro5; git pull; mkdir build; cd build; cmake ..; sudo make install)


NEO, could you try building the latest Allegro from the github mirror and let me know if the crashes are gone?


Rebuilt Allegro, pulled latest minisphere, removed MNG stuff as usual (I'll eventually go find libmng and build it to resolve this bit), recompiled. Ran my one-liner and exits clean! Ran and canceled choosing a game and exits clean! Ran CellarRush.spk and got an error that it failed to load sound file '../music/dungeon-v2.ogg' and exits clean!

For reference, building Allegro has consistently given me warnings about inability to build in loading of many audio formats like vorbis and speed.

Alright! Except for me advancing on the MNG front and figuring out how to fix audio building without building all the libs from scratch (it'd be nice if homebrew would update Allegro) it seems Sphere on Mac can indeed progress further! Now to resume my Pang96 conversion... ;)
Title: Re: minisphere 1.6.1
Post by: Fat Cerberus on August 04, 2015, 08:15:30 pm
Allegro's handling of audio format libs when building is dumb.  There are certain flags you have to set in CMake to get it to work right.  It's easier I've found to use cmake-gui.
Title: Re: minisphere 1.6.1
Post by: Fat Cerberus on August 04, 2015, 09:07:53 pm
Follow-up: Do you have the necessary libraries installed?  For full audio support you need:

* libvorbis
* libvorbisfile
* libogg
* dumb
* libflac
Title: Re: minisphere 1.6.1
Post by: HopeMetal on August 05, 2015, 06:59:37 am
I downloaded this a few days ago and I could run Sphere Studio just fine (even though I ran into problems trying to actually make anything), but now it doesn't even launch at all. When I try to run it just doesn't open. Help?
Title: Re: minisphere 1.6.1
Post by: Fat Cerberus on August 05, 2015, 10:04:03 am
Something probably got corrupted.  Delete MyDocuments/SphereStudio/Settings and try again.
Title: Re: minisphere 1.6.1
Post by: Fat Cerberus on August 05, 2015, 03:14:41 pm
Everyone: Next release will change the debugger semantics (allowing a debugger to be attached at any time) and include a debug-enabled build of Sphere Studio. :)

Edit: Also in the pipeline: ArrayBuffer support.  I bit the bullet and procured the latest build of Duktape to enable this.  From what I've seen, the Duktape master is extremely well-tested, so I'm not too concerned about catastrophic bugs there. :)  There are also supposed to be some performance improvements in the latest builds!
Title: Re: minisphere 1.6.1
Post by: HopeMetal on August 06, 2015, 04:42:53 am

Something probably got corrupted.  Delete MyDocuments/SphereStudio/Settings and try again.

Deleting the whole folder did the trick.

EDIT: But now when I try to add files to my project, it gives me unhandled exception errors about "illegal characters in path" and "Object reference not set to an instance of an object". When I try adding a spriteset it says "Can't load spriteset: ?.rss".
Title: Re: minisphere 1.6.1
Post by: Fat Cerberus on August 06, 2015, 10:04:11 am
The spriteset creation is probably a bug caused by my recent changes (it's going through a bit of upheaval at the moment), I'll look into it.  Not sure about the illegal filename characters though...  That seems weird.
Title: Re: minisphere 1.6.1
Post by: HopeMetal on August 06, 2015, 02:38:51 pm

The spriteset creation is probably a bug caused by my recent changes (it's going through a bit of upheaval at the moment), I'll look into it.  Not sure about the illegal filename characters though...  That seems weird.

I guess I'll use the editor provided with Sphere 1.5 for now. I just need to figure out how to get it to work with Minisphere.
Title: Re: minisphere 1.6.1
Post by: Fat Cerberus on August 06, 2015, 02:49:39 pm
You MIGHT be able to use a stock installation of Sphere 1.5 and copy minisphere's engine.exe over the 1.5 one.  That should work.
Title: Re: minisphere 1.6.1
Post by: Fat Cerberus on August 07, 2015, 01:27:39 am
Hey guys, see the screenshot below for what you have to look forward to! ;D

Having a Sphere debugger is so awesome.
Title: Re: minisphere 1.6.1
Post by: Radnen on August 07, 2015, 10:39:15 pm
Literally the very best thing from a new Sphere engine and editor combination. This is just really awesome! :)
Title: Re: minisphere 1.6.1
Post by: Fat Cerberus on August 08, 2015, 12:40:19 pm
The new Duktape build also seems to be a lot faster--game startup is now on par with Sphere 1.5 now, even for large games like Aquatis which used to take up to 5 seconds to compile all the scripts.
Title: Re: minisphere 1.6.1
Post by: DaVince on August 08, 2015, 08:13:57 pm
Amazing. That looks super useful.
Title: Re: minisphere 1.6.1
Post by: Fat Cerberus on August 11, 2015, 02:10:02 pm
minisphere 1.7 is out!

So... anyone care to test out the new debugger? ;)
Title: Re: minisphere 1.7.1
Post by: Fat Cerberus on August 12, 2015, 11:47:37 pm
Well, that didn't take long... I had to bump to 1.7.1 because I forgot to include a Duktape fix for improper breakpoint triggering in 1.7.0 (breakpoints inside if statements would trigger even if the condition itself wasn't hit).
Title: Re: minisphere 1.7.1
Post by: Radnen on August 13, 2015, 01:55:28 am
I tried out the debugger and I must say it's rather well done! I'm impressed. :) It doesn't handle infinite loops though, like a main game loop. But for certain function calls it's good to step through them and see what they do.

The packager is neat too. This is feeling like a real editor now. This editor with minisphere + debug is far more robust of a tool than ever before.
Title: Re: minisphere 1.7.1
Post by: Fat Cerberus on August 13, 2015, 01:58:29 am
If you step over a MapEngine call, it won't return to the debugger because MapEngine() runs its own loop.  If you use the analogue.js included with 1.7 you can set breakpoints inside map scripts though. :)

I don't know if you noticed, but in the variable viewer there's also an "eval" textbox... you can enter code there while execution is paused to inject stuff.  Whatever you enter will be evaluated within the current scope so that you can modify local variables, etc.
Title: Re: minisphere 1.7.1
Post by: Radnen on August 13, 2015, 03:10:11 am

If you step over a MapEngine call, it won't return to the debugger because MapEngine() runs its own loop.  If you use the analogue.js included with 1.7 you can set breakpoints inside map scripts though. :)


Yeah, that makes sense. I'll definitely try out the eval, it was very helpful to have that in the .NET debugger and so to do that in minisphere - that's just wow, that's amazing!

BTW +1 for analogue shoutout, this is not something you could have done easily in the map editor.
Title: Re: minisphere 1.7.1
Post by: Fat Cerberus on August 13, 2015, 12:48:05 pm
Note that the analogue debugging is only possible because I modified analogue.js to use EvaluateScript() to pull in the mapscripts.  This is incompatible with Sphere 1.x because EvaluateScript() doesn't return anything in that engine for some reason.

Unfortunately this change was necessary because otherwise Duktape doesn't assign a filename to the script and therefore breakpoints won't work.  Overall I don't think it's a big deal though--I would say the vanilla engine is well and truly obsolete at this point. ;)
Title: Re: minisphere 1.7.1
Post by: Fat Cerberus on August 14, 2015, 01:50:39 am
Here's a screenshot for another neat debug feature I added at the last minute: With the debugger attached, Print() calls are intercepted and sent to the debugger.
Title: Re: minisphere 1.7.1
Post by: Eggbertx on August 14, 2015, 03:27:40 pm
This may have been covered already, but there are 32 pages. minisphere doesn't accept constant (const) variables?
Also, it doesn't really look like the engine doesn't really say much about what went wrong. It just says "Parse error"
Title: Re: minisphere 1.7.1
Post by: Fat Cerberus on August 14, 2015, 03:29:40 pm
Yeah, "parse error" is all Duktape will give.  Not much I can do about that.  And yes, const isn't ES5 compliant so it's not supported.  The Duktape developer is working on adding ES6 features though, so hopefully it'll make it in soon.  In any case, it's mentioned in the readme.
Title: Re: minisphere 1.7.2
Post by: Fat Cerberus on August 15, 2015, 02:19:54 am
1.7.2 is posted, fixing a few bugs in Sphere Studio and making debugging local-only, avoiding the Windows Firewall prompt.  Oh, and there's a new stack viewer too. :D
Title: Re: minisphere 1.7.2
Post by: Fat Cerberus on August 16, 2015, 05:23:41 pm
So who thought minisphere would ever be this successful?  Least of all me.  In less than a year we now have a 99% compatible replacement for the vanilla engine, a bunch of new Sphere 2.0 stuff and even a stepping debugger, something I think Sphere has needed for a long time.  And all this from an experiment that I thought would never get off the ground...

At this point, at v1.7 I feel I can call minisphere fully mature.  Which means, I think it's time to get started on that JS map engine. :). Now more than ever, with a full debugger, being able to step into map engine code will be very useful, I think.
Title: Re: minisphere 1.7.4
Post by: Fat Cerberus on August 18, 2015, 02:56:53 am
Well, it turns out right-click New was completely broken in recent builds of Sphere Studio (those invalid filename errors someone mentioned recently)... I fixed it.
Title: Re: minisphere 1.7.4
Post by: N E O on August 18, 2015, 01:00:38 pm
we now have a 99% compatible replacement for the vanilla engine


What's the missing 1%?
Title: Re: minisphere 1.7.4
Post by: Fat Cerberus on August 18, 2015, 01:03:09 pm
Two things mainly: stricter argument type checking (this is an issue in rare cases), and a few lesser-used APIs, such as Complex().
Title: Re: minisphere 1.7.4
Post by: N E O on August 18, 2015, 01:37:28 pm
I'm tempted to ask you to fork minisphere once that's done so that one version has only the vanilla stuff for 1.5/1.6 (i.e. disable all the experimental/minisphere-specific API), we'd commit that to vanilla Sphere, then officially recognize minisphere as the vanilla successor and all the experimental/ms-specific stuff would be considered "proposed additions to Sphere 2.0" or "draft status" (using W3C terminology), then it's an arms race between the big three Sphere engines.

In this scenario, for lack of a better analogy minisphere becomes WebKit, TurboSphere becomes Gecko, SSFML becomes IE/Edge, YASE/sphereclone (http://forums.spheredev.org/index.php/topic,72.0.html) might be Opera/Presto unless casiotone decides to resume work on it or it gets folded into another engine project, the various web-sphere implementations are still web-based, and all other attempts at Sphere-compatible engines still exist but we haven't heard from them in a while.
Title: Re: minisphere 1.7.4
Post by: Fat Cerberus on August 18, 2015, 01:51:25 pm
I don't know, at this point I feel like that would just be needlessly extending the vanilla engine's life for no real gain.  If I were to add the missing primitives the engine would be 100% backward compatible as-is (save some audio formats), no need to make a build with removed functionality.  We WANT to get new users to use the new stuff, and having separate stable and unstable/experimental versions might scare them off of doing so.  In fact the additional bells and whistles are the biggest reason I recommend minisphere over vanilla--a build limited to just the 1.x APIs would Have no real advantage over the original engine, IMO.  Duktape is faster, yes, but not enough to make-or-break.

It's tempting to want to wait until Sphere 2.0 has stabilized to commit to anything, but part of the reason I took the initiative with minisphere in the first place was because that process was going nowhere--note the sorry state Pegasus ended up in.

I think our best bet is to embrace the extension system I already have implemented and, instead of standardizing "Sphere 2.0" wholesale, we work on standardizing the individual components.  So you would have a standard for Audialis, one for Galileo, etc., each with a unique extension string exposed through GetExtensions() and they would all be Sphere 2.0 components.  This is how the Ecmascript specs are built, and the process seems to work very well.
Title: Re: minisphere 1.7.4
Post by: Radnen on August 18, 2015, 07:48:09 pm

It's tempting to want to wait until Sphere 2.0 has stabilized to commit to anything, but part of the reason I took the initiative with minisphere in the first place was because that process was going nowhere--note the sorry state Pegasus ended up in.


Yeah, that's why I made Sphere Studio. There was a time when Vexo (man, what happened to these people :() said every year someone comes up with the idea of a new IDE and it always fails. I was thinking if I used a proper language and environment, say C# and WinForms I can make an IDE three times faster than anyone else (imagine doing it - alone - in C or C++!) and I'd have managed, clean code to work off of. .NET was built around the concept of being a desktop application developers language, or rather for Software Engineering projects in general.
Title: Re: minisphere 1.7.4
Post by: N E O on August 18, 2015, 09:50:05 pm

I don't know, at this point I feel like that would just be needlessly extending the vanilla engine's life for no real gain.  If I were to add the missing primitives the engine would be 100% backward compatible as-is (save some audio formats), no need to make a build with removed functionality.  We WANT to get new users to use the new stuff, and having separate stable and unstable/experimental versions might scare them off of doing so.  In fact the additional bells and whistles are the biggest reason I recommend minisphere over vanilla--a build limited to just the 1.x APIs would Have no real advantage over the original engine, IMO.  Duktape is faster, yes, but not enough to make-or-break.

It's tempting to want to wait until Sphere 2.0 has stabilized to commit to anything, but part of the reason I took the initiative with minisphere in the first place was because that process was going nowhere--note the sorry state Pegasus ended up in.

For all intents and purposes, the primary advantage a vanilla API minisphere would have over classic Sphere is the existence of reliable modern dependencies and cross-platform consistencies across modern systems. minisphere comes with Duktape bundled and only requires the easy-to-package Allegro, and is guaranteed to work on all three common modern systems (and probably will work on Windows < 7, OS X < 10.9, various older Linuxes, maybe the BSDs); Classic requires a slew of first-party dependencies that may or may not bundle/compile/package/etc cleanly and easily on modern systems (I'm sure y'all remember the PITA modernizing audiere was), and is only guaranteed to work on older Windows (I don't remember if 1.5 worked easily on >=Vista or not), OS X < 10.7 with the separate dependencies bundle, and maybe some Linuxes.

But yes, I understand the desire to "get new users to use the new stuff;" remember I was a web developer trying to convince clients to modernize sites to support Firefox & Chrome back when IE6 was still a thing ;)


I think our best bet is to embrace the extension system I already have implemented and, instead of standardizing "Sphere 2.0" wholesale, we work on standardizing the individual components.  So you would have a standard for Audialis, one for Galileo, etc., each with a unique extension string exposed through GetExtensions() and they would all be Sphere 2.0 components.  This is how the Ecmascript specs are built, and the process seems to work very well.

Ecmascript, CSS3, and HTML5 use this modular draft system, and I agree with its methodology. The doc for GetExtensions says the strings returned are mostly self-explanatory, but honestly I feel the new ones (basically any string that's not "sphere-legacy-api") need some sort of explanation, and I'd probably like to see some sectioned, e.g. sphere-audialis sectioned into sphere-audialis, sphere-audialis-wav, sphere-audialis-mp3, sphere-audialis-midi, sphere-audialis-ogg, ..., as R/W capabilities warrant. I assume the preferred way to check for certain functionality is (GetExtensions().indexOf(theCapability)!==-1)  ?

The doc for GetVersion says minisphere 1.4 and needs the version number updated, FYI.
Title: Re: minisphere 1.7.4
Post by: Fat Cerberus on August 18, 2015, 10:47:11 pm
Does it?  ill have to fix it.  I make a point to update the GetVersionString() return value every major release, but may have missed an annotation elsewhere.  The actual function should return the correct API version (2.0) in any case.

indexOf is the best way to check for extensions, yes.

But anyway, I don't think actively stripping out functionality helps anyone when the engine is already compatible with vanilla.  Vanilla compatibility is neatly encapsulated by the sphere-legacy-api extension, if you need to code against the new stuff you check for the appropriate extension and either degrade gracefully or fail outright.  That's why the system exists.

Speaking of which, I don't know that it's a good idea to overly compartmentalize the extension system as you're suggesting.  Extensions are shorthand for a set of APIs, supported formats don't really need dedicated extensions as more formats might be supported via plugins or whatnot, a la TurboSphere--and depending on the backend used, may even change between platforms...

As for documentation, again, each extension string represents an API.  So to find out what each represents if it's unclear, you have to read the API reference. ;)  Both Galileo and Audialis are covered via short descriptions and function documentation.  Even SphereFS is explained in that document.

Overall I just think that releasing a stripped-down engine is akin to saying "here's a modernized IE6, we know you're not ready for all the new technologies yet but at least it's new, right?"  Maybe that's just me though.
Title: Re: minisphere 1.7.4
Post by: N E O on August 19, 2015, 01:19:55 am

But anyway, I don't think actively stripping out functionality helps anyone when the engine is already compatible with vanilla.  Vanilla compatibility is neatly encapsulated by the sphere-legacy-api extension, if you need to code against the new stuff you check for the appropriate extension and either degrade gracefully or fail outright.  That's why the system exists.

[ ... ]

Overall I just think that releasing a stripped-down engine is akin to saying "here's a modernized IE6, we know you're not ready for all the new technologies yet but at least it's new, right?"  Maybe that's just me though.


I understand your approach better now. I was of an old mindset of "test if GetVersion() > X for Y functionality" to do stuff and forgot for a while that a modular extensions system like yours and testing for extension existence is indeed almost always the better option; it's the core tenet of Modernizr, among other libraries, and Crockford preaches about the methodology so hard in JS: The Good Parts that I really should have known better.

...crap. That it took me this long to put 2 & 2 together about this means the depression I seem to have is getting worse; the fact that I'm apparently losing focus and acuity in THIS aspect of my life is a pretty bad sign for me.
Title: Re: minisphere 1.7.4
Post by: Fat Cerberus on August 19, 2015, 02:17:14 am
Yeah, that's pretty much it.  Technically GetVersion() never has to return anything > 2.0 now since 2.0 implies the existence of GetExtensions()--and if THAT exists, you should be using that to test for feature support beyond the vanilla subset.
Title: Re: minisphere 1.7.4
Post by: Fat Cerberus on August 19, 2015, 01:53:29 pm
So I'm working on a modification to Duktape that will allow minisphere to break into the debugger if an error is thrown.  Attached is a screenshot of the dialog which would be displayed by Sphere Studio if this is successfully implemented:
Title: Re: minisphere 1.7.4
Post by: Fat Cerberus on August 20, 2015, 09:53:55 am
I think I want to make a command line debugger for minisphere.  Being able to do it in Sphere Studio is great (I always prefer an IDE for debugging), but this would allow debugging on any platform minisphere runs on, not just windows.  Especially if I coded it in C.
Title: Re: minisphere 1.7.4
Post by: Eggbertx on August 20, 2015, 02:57:49 pm
How do I send text to the console?
Title: Re: minisphere 1.7.4
Post by: Fat Cerberus on August 20, 2015, 03:39:19 pm
Code: (javascript) [Select]
Print("A pig ate everything at 8:12");


While debugging, this will also send it to the Sphere Studio console.
Title: Re: minisphere 1.7.5
Post by: Fat Cerberus on August 22, 2015, 01:24:52 am
1.7.5 is now available for download with the previously mentioned debugger enhancement allowing the debugger to pause execution when an error is thrown.  Very useful!
Title: Re: minisphere 1.7.6
Post by: Fat Cerberus on August 29, 2015, 12:49:15 am
minisphere 1.7.6 is up.  The redist engine now has JS debugging disabled as having it enabled hurt performance even when not actively debugging.  Debugging now requires minisphere Console to be used.

Sphere Studio has also been updated with the latest bug fixes and features, notably the new entity view implemented in the map editor by Radnen.
Title: Re: minisphere 1.7.7
Post by: Fat Cerberus on September 01, 2015, 12:03:30 pm
Okay, 1.7.7 is up, fixing misbehavior when infinite recursion is encountered--"double error" for a normal run, or an outright crash with the debugger attached.  Now it properly throws a RangeError in this case, which will be caught by the debugger.
Title: Re: minisphere 1.7.11
Post by: Fat Cerberus on September 10, 2015, 09:12:00 pm
I decided for minisphere 2.0, I'm going to deprecate ByteArray.  It will still be retained in the API for backwards compatibility, but all the new APIs (such as the new Sockets API) are being updated to use ArrayBuffers and TypedArrays instead.

I'm also going to try my hand at writing a new map engine in JavaScript.  Despite my misgivings in the past, I think this will ultimately be a good thing to have, if only because you'll be able to step into map engine code while debugging.  As with ByteArrays above, the classic map engine will be retained with its API fully intact.
Title: Re: minisphere 1.7.11
Post by: Fat Cerberus on September 19, 2015, 12:08:19 am
Good news: minisphere 2.0 will support const.  Well, in the same capacity as Sphere 1.5 does anyway (i.e. it's a synonym for var).  This improves legacy compatibility even further. :)
Title: Re: minisphere 1.7.11
Post by: Fat Cerberus on September 19, 2015, 01:47:06 am
Let me just say for the record here that SCons is a hellish nightmare to work with.  Things that should be simple like pulling in sources from minisphere to use in Cell cause no end of grief under SCons because it doesn't make a clear distinction between source and object files and treats one as a stand-in for the other.  That is, if you use the same source file in two programs, it compiles it once and tries to link the same object file into both programs.  And then if you try to use different compiler options between the two, SCons throws up its hands and gives up ("Two environments with different options for same target").

It doesn't help either that the SCons documentation is absolutely atrocious.  It took me forever just to find (on an obscure Stack Overflow question) that the solution was not to pass the .c file to Program() directly, but use the Object() method like so:

Code: (python) [Select]
cell_sources = [
Object("duktape", "../msphere/duktape.c"),
Object("vector", "../msphere/vector.c"),
"engine.c",
"main.c"  # <-- what this really means, to SCons, is "the object file created from main.c"
]


Ugh.

edit: GAAAAAAAAAAAAAAAHHHHHHHHHHHH *DBZ powerup* *goes Super Saiyan*
Code: [Select]
$ scons cell
scons: Reading SConscript files ...
scons: done reading SConscript files.
scons: Building targets ...
scons: building associated VariantDir targets: obj/cell
scons: *** [obj/cell/engine.o] Implicit dependency `obj/cell/duktape.h' not found, needed by target `obj/cell/engine.o'.
scons: building terminated because of errors.


That didn't work either.  At all.  Seriously, whoever wrote this piece of software should be drug out into the street and shot.

edit 2: So it started building properly again for no apparent reason.  Well, I'm not going to complain, but it doesn't do much for my faith in this build system.  I wonder if CMake is any better.  In any case, SCons provides a good baseline of what not to do in Cell. :P
Title: Re: minisphere 1.7.11
Post by: Flying Jester on September 19, 2015, 06:37:55 pm
Chad Austin is in the credits for SCons. That's how I originally found it.

The docs are bad, mostly because SCons wiki was destroyed by spambots a few years ago. I usually use the archive.org'ed version of it, since it was never properly rebuilt.

SCons doesn't make any distinctions about what anything is. Everything has a way of being created, and may be needed for something else. If you only care about compiling that C file, then you pass in that C file. Since you care about more than that (compiler options), what you care about is the resulting object files. This is how any dependency driven build system works.

An alternative (I suspect the intended way) is to use static libraries, since using the static library builder lets you do what you want--different options on the same source to create different object files. In general, static libraries stand in for individual object files in SCons when you don't want to build something in just one step.

When you hit implicit dependency issues, try nuking the .sconsign and scons DB files.
Title: Re: minisphere 1.7.11
Post by: Fat Cerberus on September 19, 2015, 06:47:24 pm
Okay, but if I use the same .c file in two programs, why does SCons think its a reasonable default to only generate a single object file for that source, even though the two programs may (and probably do) need to be compiled with different options?  That's what I meant by using sources as a stand-in for objects--if I tell it to build a program from main.c, SCons interprets that as "build a program from the object file created from main.c"--and any reference anywhere (even in different environments!) to main.c refers back to that exact same object file.  It makes no sense and I feel like I have to jump through hoops (using Object builders, etc.) just to get it to do something sane.
Title: Re: minisphere 1.7.11
Post by: Flying Jester on September 19, 2015, 06:58:22 pm
Referring directly to main.c when using either the shared library or program builders basically means you want any object file of that source. When you mean a specific object file, then you must specify that specific object file.

Basically, it's just a shortcut that simplifies things in 99% of the uses. This way you don't need to specify the object builder for every single source file, and managed each object file through to the library or program builder. In this case, you don't want to use that shortcut, and unfortunately the long-hand way is kind of obscure.

The other answer is that it's kind of bad practice to compile the exact same source with functionally different compiler options. But that's kind of a bad answer, since I know a lot of projects (both C and C++) do it.

I usually do this sort of thing (mostly when I want different preprocessor directives) by creating a C or C++ file for each use of the single source file, and including it from those. I never compile the main source directly, but instead the files that included it. That also keeps as much of the preprocessr usage out of the build system as possible, which I consider a good thing. The down side is that I'm including actual source files in other source files, which is a little unusual. But the up side is that it is clear what options are being specified from the source itself, and it also makes supporting multiple build systems easier.
Title: Re: minisphere 1.7.11
Post by: Fat Cerberus on September 22, 2015, 03:11:46 am
So I may have gotten spoiled by Allegro.  I had to pretty much reimplement its entire path builder API from scratch for Cell because it was very powerful but there was no way I was depending on Allegro for a command-line tool.  On the upside, my custom path routines now have better canonization than Allegro, I can have it collapse upstream (../) hops which Allegro's canonizer won't do (it's not symlink-friendly) but is needed when working with, e.g. SPKs.

Paths are represented internally as an array of hops, which makes the whole thing platform-agnostic: Only the pathname string creation needs to be changed to use a different seperator (but almost all platforms accept / so this isn't even necessary in practice).  It also makes working with paths safer since there is no risk of a buffer overflow--each hop is allocated independently using strdup().

Path building functions are one thing I always tend to miss when I'm not using .NET, so having them in C now is awesome.
Title: Re: minisphere 1.7.11
Post by: Fat Cerberus on September 27, 2015, 12:53:16 am
Cell is coming along nicely, and should be a nice addition to minisphere 2.0.  game.sgm is no longer a requirement for a Sphere project, instead you have a cell.js build script in the source directory, like this:

Code: (javascript) [Select]
function $sphere()
{
install(files("scripts/*.js", true), "scripts");
install(files("images/*.png", true), "images");
install(files("maps/*.rmp", true), "maps");
install(files("maps/*.rts", true), "maps");
install(files("spritesets/*.rss", true), "spritesets");
install(files("sounds/*.wav", true), "sounds");
install(files("sounds/*.ogg", true), "sounds");

install(sgm({
name: "Spectacles: Bruce's Story",
author: "Fat Cerberus",
description: "Follow Scott Starcross in his quest to stop the Primus.",
resolution: "320x240",
script: "main.js"
}));
}


And then, at the command line (be sure to scroll down to the bottom for something amusing ;)):

Code: [Select]

fatce@DESKTOP-AR6TT0B /d/src/spectacles-i
$ cell -p Spectacles-BS.spk
Cell v2.0-WIP Sphere Game Compiler x86
A scriptable build engine for Sphere games.
(c) 2015 Fat Cerberus

    Building 'D:/src/spectacles-i/Spectacles-BS.spk' (SPK)
    Source: 'D:/src/spectacles-i/'

Processing cell.js rule 'sphere'
Building assets...
  D:/src/spectacles-i/.cell/game.sgm
  1 asset(s) built
Installing assets...
  scripts/AIContext.js
  scripts/Battle.js
  scripts/BattleActor.js
  scripts/battleAI/HeadlessHorseAI.js
  scripts/battleAI/LumisquirrelAI.js
  scripts/battleAI/Robert1AI.js
  scripts/battleAI/Robert2AI.js
  scripts/battleAI/ScottStarcrossAI.js
  scripts/battleAI/ScottTempleAI.js
  scripts/battleAI/VictorAI.js
  scripts/BattleHUD.js
  scripts/BattleScreen.js
  scripts/BattleUnit.js
  scripts/ConditionContext.js
  scripts/Cutscenes.js
  scripts/FieldMenu.js
  scripts/gamedef/animations.js
  scripts/gamedef/battles.js
  scripts/gamedef/characters.js
  scripts/gamedef/conditions.js
  scripts/gamedef/game.js
  scripts/gamedef/items.js
  scripts/gamedef/maps.js
  scripts/gamedef/math.js
  scripts/gamedef/moveEffects.js
  scripts/gamedef/scenes.js
  scripts/gamedef/skills.js
  scripts/gamedef/stats.js
  scripts/gamedef/statuses.js
  scripts/gamedef/text.js
  scripts/gamedef/weapons.js
  scripts/GameOverScreen.js
  scripts/GrowthPopup.js
  scripts/ItemUsable.js
  scripts/lib/kh2Bar.js
  scripts/lib/SpriteImage.js
  scripts/LucidaClock.js
  scripts/main.js
  scripts/MapContext.js
  scripts/maps/main.js
  scripts/maps/Portentia.js
  scripts/maps/Testville.js
  scripts/MenuStrip.js
  scripts/MoveMenu.js
  scripts/MPGauge.js
  scripts/MPPool.js
  scripts/Party.js
  scripts/PartyMember.js
  scripts/Scrambler.js
  scripts/Session.js
  scripts/SkillUsable.js
  scripts/SpecsClient.js
  scripts/SpecsServer.js
  scripts/Stat.js
  scripts/StatusContext.js
  scripts/TargetMenu.js
  scripts/testcases/brucesStory.js
  scripts/testcases/lastLucidan.js
  scripts/TestHarness.js
  scripts/TitleScreen.js
  scripts/TurnPreview.js
  scripts/WeaponUsable.js
  images/GameOverScreen.png
  images/Logos/GameLogo.png
  images/Logos/TitleCard.png
  images/ScottSucks.png
  images/TestBattle.png
  images/TitleScreen.png
  maps/main.rmp
  maps/Portentia.rmp
  maps/Testville.rmp
  maps/Portentia.rts
  maps/TestvilleTiles.rts
  spritesets/battlers/Amanda.rss
  spritesets/battlers/Bruce.rss
  spritesets/battlers/Elysia.rss
  spritesets/battlers/H. Horse.rss
  spritesets/battlers/Justin.rss
  spritesets/battlers/Katelyn.rss
  spritesets/battlers/Lauren.rss
  spritesets/battlers/Lumisquirrel.rss
  spritesets/battlers/maggie.rss
  spritesets/battlers/maggie_hippo.rss
  spritesets/battlers/Robert.rss
  spritesets/battlers/Scott T.rss
  spritesets/battlers/Scott.rss
  spritesets/battlers/Victor.rss
  spritesets/battlers/Xemnas.rss
  spritesets/invisible.rss
  sounds/Munch.wav
  sounds/BGM/BasicInstinct.ogg
  sounds/BGM/BattleForLucida.ogg
  sounds/BGM/BruceTellsHisStory.ogg
  sounds/BGM/CreepFight.ogg
  sounds/BGM/DeathComeNearMe.ogg
  sounds/BGM/EndOfInnocence.ogg
  sounds/BGM/GameOver.ogg
  sounds/BGM/HymnOfLiberty.ogg
  sounds/BGM/LamentForBruce.ogg
  sounds/BGM/LucidaByNight.ogg
  sounds/BGM/MalmagmaManor.ogg
  sounds/BGM/ManorBoss.ogg
  sounds/BGM/MyDreamsButADropOfFuel.ogg
  sounds/BGM/MyDreamsButADropOfFuel2.ogg
  sounds/BGM/OneWorldIsNotEnough.ogg
  sounds/BGM/OurWorldCanStillBeSaved.ogg
  sounds/BGM/Portentia.ogg
  sounds/BGM/RiseOfThePrimus.ogg
  sounds/BGM/RunawayTrain.ogg
  sounds/BGM/ScottsHomecoming.ogg
  sounds/BGM/SeasonsEnd.ogg
  sounds/BGM/SpectaclesTheme.ogg
  sounds/BGM/SubfloorManor.ogg
  sounds/BGM/ThePromise.ogg
  sounds/BGM/TheQuantumEnigma.ogg
  sounds/BGM/TimeToLetGo.ogg
  game.sgm
  117 asset(s) installed
Success!

fatce@DESKTOP-AR6TT0B /d/src/spectacles-i
$ cell --explode
Cell seems to be going through some sort of transformation...
He's pumping himself up like a balloon!

    Cell says:
    "I'm quite volatile, and the slightest jolt could set me off!"

fatce@DESKTOP-AR6TT0B /d/src/spectacles-i
$ msphere Spectacles-BS.spk
Title: Re: minisphere 1.7.11
Post by: Radnen on September 27, 2015, 04:04:01 am
That's looking pretty right darn proper. :)
Title: Re: minisphere 1.7.11
Post by: Fat Cerberus on September 27, 2015, 11:43:55 am
Minor sidenote: I had to rename cell.js to Cellscript.js because otherwise cmd.exe uselessly tries to run the JS script directly when you type "cell". :-\
Title: Re: minisphere 1.7.11
Post by: Fat Cerberus on September 27, 2015, 12:40:02 pm
Now to really bring out the potential of this tool, it will need some image processing functions.  Is Corona still active or is that a dead project at this point?  I think I remember someone saying it was revived, but... If not, I'll probably just integrate libpng for image processing.

If anyone's wondering where I'm going with this, it's to support compiling spritesets and tilesets on-the-fly during the build process.  Sphere formats are a pain to edit, even with a purpose-built GUI, and would be much easier to manage I think if you could create them from bare images.  How this would work is you declare an asset in the Cellscript, like this:

Code: (javascript) [Select]
// 32x32, 8 directions, 5 frames per
var maggieSS = spriteset("src/sprites/maggie.png", 32,32, 8, 5);
install(maggieSS, "spritesets");


And then Cell would build the .rss file at compile time from the input image.  This would allow you to edit your sprites in your favorite image editor and let Cell deal with getting them into the proper format for the engine without a bunch of tedious copying and pasting into the RSS editor. ;D
Title: Re: minisphere 1.7.11
Post by: Flying Jester on September 27, 2015, 04:59:36 pm
Corona is still active. Both Chad Austin and I have branches (which are not exactly the same, although they have the same features and are binary compatible).

Most recently it's been updated to work with new TurboJpeg and MozJpeg.
Title: Re: minisphere 1.7.11
Post by: Fat Cerberus on September 28, 2015, 03:47:20 pm
Hm, I had forgotten Corona was C++.  Like minisphere, Cell is written in C so I would need to write a wrapper to be able to use it.  For now bare libpng will suffice.

Anyway, apparently the RTS tileset format doesn't support compression?  There's a "compression" flag in the header, but the RTS doc says it's unsupported.  As a result a tileset with just 256 32x32 tiles is already 1MB.

Since the flag is already there, I could add compression (either PNG or raw zlib) support easily enough (breaks backwards compat) but I'm not sure yet if it's worth the trouble--you get the zlib compression for free anyway via SPK packaging, which with Cell is ridiculously easy--just run cell -p mygame.spk.
Title: Re: minisphere 1.7.11
Post by: Flying Jester on September 28, 2015, 04:48:51 pm
Corona has a C interface, although it's 'hidden'. Corona's ABI is totally compiler agnostic--you could compile it with MingW and call it from MSVC, compile it with Solaris Studio and call it from tcc, etc. As a part of this, all functions have static versions, and all outward facing functions have no name C++ mangling.

http://chadaustin.me/cppinterface.html (http://chadaustin.me/cppinterface.html)
Title: Re: minisphere 1.7.11
Post by: Radnen on September 29, 2015, 11:57:14 am
So, here is what XNA does. XNA keeps all assets uncompressed even post pipeline (even if you fed it compressed formats like .png). The reason for this is because these games can be released in an archive format sorta like zip (or for Sphere, .spk) and so get benefited from compression. Further, when they decompress, there is no need to decompress a second time (e.g. from png to bmp). That way files can exist within a virtual file system and be streamed rather quickly into the game. This is how all great game engines work from Quake to Skyrim.

Sphere can be something like that. I was on a game developers forum and they laughed at me for having talked about releasing a game with hundreds of assets in subfolders (namely, every Sphere game not in a .spk format). BTW, spk's like other game engines shouldn't need to be compressed to the storage device - the assets should go straight from spk to RAM. But I think you may have that covered already in minisphere (;)).

So whatever processing occurs it's good to keep in mind what gets compressed or not, since it's the final compression - the .spk - which matters the most.
Title: Re: minisphere 1.7.11
Post by: Fat Cerberus on September 29, 2015, 12:06:13 pm
I take it you've looked at spk.c then. :)

But yes, that's what spk_fopen() does - it decompresses the packed file into a malloc'd buffer and any subsequent file reads simply read from that buffer.  Allowing write access (for transparency) was a bit trickier: I had to check the spk_fopen() mode string and if write access was requested, unpack the file to disk first then open that.  The end result is that minisphere's SPK handling is actually more robust than 1.5's: many games that broke under the old engine when packaged work just fine in minisphere.

That makes sense though, keeping assets uncompressed on disk.  This way too, if the SPK format gets an upgrade to use, say, LZMA compression it isn't held back by already-compressed assets being stored as-is.
Title: Re: minisphere 1.7.11
Post by: Radnen on September 29, 2015, 12:39:17 pm
The only downside I've had developing XNA games is the friggin' huge filesize on my storage device. But, that's considered standard in the industry (for all major fields whether you are a recording artist in a sound studio, a director shooting a film, or an animator or game developer). Almost nobody uses compressed formats professionally.

(btw, I love your .spk implementation, reminds me of quake).
Title: Re: minisphere 1.7.11
Post by: Fat Cerberus on September 30, 2015, 10:45:05 am
So apparently libpng v1.2 and v1.6 are mutually incompatible.  That makes things difficult, as it seems most Linux distros only provide a package for libpng 1.2, meaning my Travis build is quite thoroughly broken right now.  To get around this, I attempted to compile libpng 1.2 on Windows, but it seems that release uses an older zlib which is ALSO incompatible.  Lovely.  And I guess I'd have this same issue even if I switched to Corona, since it uses libpng...
Title: Re: minisphere 1.7.11
Post by: Flying Jester on September 30, 2015, 12:42:19 pm
No. Corona works with libpng older or newer than libpng 1.2. You just need to have compiled it for whichever libpng you have on that system.

Travis uses somewhat outdated Debian. Which is about the only place that still uses such an ancient version of libpng. My main complaint about Travis is that the system it represents is very out of date. Very few Linux users will have an environment like it.
Title: Re: minisphere 1.7.11
Post by: Fat Cerberus on September 30, 2015, 12:57:16 pm
Well, that's good to know at least.  Still stupid that the PNG group thought it was a good idea to release a 1.5/1.6 and not keep it at least somewhat source-compatible with 1.2, though.  The API is completely different.  I know PNG predates semantic versioning, but even so, that's tacky.

That said, I removed the image processing for now as it was only being used to generate tilesets, but that's not useful as the resulting tileset has no obstruction data.  I haven't come up with a solution for that yet.
Title: Re: minisphere 1.7.11
Post by: Flying Jester on September 30, 2015, 01:18:23 pm
I'm pretty sure there were a large number of versions that had both APIs. I am sure Travis is just that out of date. No library has the same API forever.

The new API is much, much better, and means that there is no forseeable reason to ever break the ABI again. It also makes the library's ABI compiler agnostic (the 1.2 and older API was not).
Title: Re: minisphere 1.7.11
Post by: Fat Cerberus on September 30, 2015, 01:36:07 pm
No, I like the new API a lot, don't get me wrong on that. :)  It's just that they should have versioned it at 2.0 to make it clearer that the upgrade wouldn't be seamless.  Keeping the major version the same implies at least mostly-backward compatibility with code from the older version, which isn't the case at all.  It certainly caught me by surprise!
Title: Re: minisphere 1.7.11
Post by: Flying Jester on September 30, 2015, 02:36:13 pm
I would consider the libpng changes mostly-backwards compatible. It only accounts for a handful of lines of code difference in Corona.
Title: Re: minisphere 1.7.11
Post by: Fat Cerberus on September 30, 2015, 02:44:10 pm
Hm, I'll look into it.  However, off topic, I found this:
https://github.com/dimensio/libpng16-deb/blob/master/README.md

Ubuntu, which Travis uses, includes 1.2.  The readme also says Debian is experimenting with adding 1.6, but there are apparently compatibility issues preventing it.  No idea why but that explains why the Travis build fails at least.
Title: Re: minisphere 2.0b1 (stable 1.7.11)
Post by: Fat Cerberus on October 02, 2015, 03:03:07 am
The first pre-release of minisphere 2.0 is now available, minisphere 2.0b1!  This includes a preview of the new Cell compiler.  To get started with Cell, place this example script in any Sphere game directory as Cellscript.js:

Code: (javascript) [Select]

function $sphere()
{
install(files("animations/*", true), "animations");
install(files("maps/*", true), "maps");
install(files("fonts/*", true), "fonts");
install(files("images/*", true), "images");
install(files("scripts/*", true), "scripts");
install(files("sounds/*", true), "sounds");
install(files("spritesets/*", true), "spritesets");
install(files("windowstyles/*", true), "windowstyles");

install(sgm({
name: "Awesome Sphere Game",
author: "Some Weird Guy",
description: "Follow the hero as he tries to get devoured by the nearest pig.",
resolution: "320x240",
script: "main.js"
}));
}


Then from the command line, switch to that game's directory and (assuming you added minisphere to the PATH during setup):
Code: [Select]

cell -p game.spk
msphere game.spk
Title: Re: minisphere 2.0b1 (stable 1.7.11)
Post by: Fat Cerberus on October 05, 2015, 02:28:47 pm
It's a good thing I really enjoy doing this or the overall deadness of the Sphere forums would be incredibly depressing after all the work I did on minisphere... :P
Title: Re: minisphere 2.0b1 (stable 1.7.11)
Post by: Radnen on October 05, 2015, 10:54:10 pm
Hopefully someday we can start marketing a nice solution to game hobbyists. I think Sphere has fallen in visibility lately and we can try to re-ignite what was there under Minisphere and my editor. Perhaps get a more advanced crowd to who'll appreciate debug tools and command line build scripts. ;)
Title: Re: minisphere 2.0b1 (stable 1.7.11)
Post by: Fat Cerberus on October 05, 2015, 11:01:05 pm
That's actually my overarching goal with the recent additions (from around 1.5 on)--to make Sphere look like a serious tool for game development, beyond the "toy" that is Sphere 1.5.  To accomplish that, I realized it needs to be more than just the engine; it doesn't matter how many awesome features I add to it, there needs to be some sort of toolchain to go with it.

If you think about it, being more than just a toy is what got Sphere on the map originally--it had JavaScript, a full programming language, while everyone else was using RPG Maker 2000 with its point and click "scripting".
Title: Re: minisphere 2.0b1 (stable 1.7.11)
Post by: DaVince on October 06, 2015, 12:10:08 am

Hopefully someday

We're pretty much already there.

Also, I remember talk about an overhauled map engine at some point? Definitely check out http://www.mapeditor.org/ - it's a fantastic cross-platform map editor I've been using since very recently which is just EXCELLENT and I think integration of its map format into minisphere would be *very* beneficial for Sphere and the community to have. And re-ignite some of its flames.

Heck, look at what already supports it (http://doc.mapeditor.org/reference/support-for-tmx-maps/). Add minisphere to that list and bam, visibility goes up. :)
Title: Re: minisphere 2.0b1 (stable 1.7.11)
Post by: Fat Cerberus on October 09, 2015, 02:54:23 am
That map editor looks awesome.  I'll see about integrating it, even if I don't support it in the engine directly I could have Cell be able to compile it to an RMP if nothing else.

Speaking of which, thanks to a recent massive overhaul of Sphere Studio's plugin system, the minisphere 2.0 GDK will have much tighter integration with the editor.  So you won't have to drop to the command line to get the full power of Cell! ;D

As for the overhauled map engine, I was considering doing one for minisphere 2.0 in JS.  I keep putting it off to do other stuff though, like the Sphere Studio overhaul, because I know it will be a huge undertaking.  Implementing the classic map engine was easily the most time-consuming part of minisphere's early development, and that was working off of the original Sphere 1.x source!
Title: Re: minisphere 2.0b1 (stable 1.7.11)
Post by: N E O on October 09, 2015, 11:41:03 am

As for the overhauled map engine, I was considering doing one for minisphere 2.0 in JS.  I keep putting it off to do other stuff though, like the Sphere Studio overhaul, because I know it will be a huge undertaking.  Implementing the classic map engine was easily the most time-consuming part of minisphere's early development, and that was working off of the original Sphere 1.x source!


Always remember the most immediate advantage of making a piece of the engine in JS is how easily portable it will be to the web versions (and likely inevitable node.js version). Once a working proof of concept is made (can probably reuse casiotone's, Radnen's, and/or my existing JS animation code (http://www.spheredev.org/fmt/) for animating tiles), THEN we can worry about optimization and stuff. If you look at the source for mine you'll see I had almost finished map stuff, but I was stuck on figuring out an efficient animated rendering method and didn't go further.

Note: in my tile animation demo section the 'A' that marks animated tiles is HTML, not canvas, so don't worry about a parsing error there if you want to save the canvas to a file.
Title: Re: minisphere 2.0b1 (stable 1.7.11)
Post by: Flying Jester on October 09, 2015, 03:56:30 pm
I found it was much, much faster and easier to write a map engine clone in JS. And I also found that, just knowing what characteristics it should have and implementing those, I came very close to creating an equivalent object-oriented API without really meaning to.

That was what prompted me to try and rewrite more of the API in JS. I found it was actually pretty easy for a lot of the API, and didn't incur much of a performance hit at all. Fortunately, SpiderMonkey is able to properly manage its own memory, so I could finally tie GPU resources to JS objects.

That was also what made me think about putting almost the entire API in script. Just expose a single ArrayBuffer that is the screen, and ArrayBuffer-like object you can post audio to, something equivalent in functionality to the RawFile object for filesystem and network access, and an object that represents input. Everything else can be done in script.
Title: Re: minisphere 2.0b1 (stable 1.7.11)
Post by: Fat Cerberus on October 09, 2015, 05:20:24 pm
That ArrayBuffer-like audio object is answered by Audialis, which as of 2.0 will support 8, 16, 24, and 32 bit audio, the last one being float.  Likewise RawFile is being deprecated in favor of the new FileStream object.

24 bit audio might be a bit awkward with ArrayBuffers though as there is no Int24Array.  Thankfully there IS a Float32Array. :)
Title: Re: minisphere 2.0b1 (stable 1.7.11)
Post by: Flying Jester on October 09, 2015, 05:35:57 pm
16-bit audio is pretty standard, though. You can assume that this is supported by just about every platform. Floating-point audio is a bit more exotic.
Title: Re: minisphere 2.0b1 (stable 1.7.11)
Post by: Fat Cerberus on October 09, 2015, 05:40:43 pm
It might still be useful to _render_ in floating-point thoigh, e.g. In the case of procedural audio.  Allegro automatically mixes it down, which is nice.
Title: Re: minisphere 2.0b1 (stable 1.7.11)
Post by: Fat Cerberus on October 11, 2015, 02:45:20 am
Thinking about the JS map engine some more, I'm beginning to think it might actually be outside the scope of the minisphere project itself.  It would be a great thing to have certainly, I just think it would be healthier as a project if it was maintained independently, instead of shipping with the engine.

The classic map engine will be kept in the minisphere 2.0 core for backwards compatibility (and as a convenient starting point for newbies), but I'd say any map engine projects going forward would be better off in the long run as independent projects.  Especially with Sphere Studio's plugin system being actually usable now, map engines don't have to be shackled to the RMP format anymore and thus there's no longer any need for the "one map engine to rule them all" model used thus far.
Title: Re: minisphere 2.0b1 (stable 1.7.11)
Post by: Fat Cerberus on October 11, 2015, 09:39:20 am
@DaVince Looked at that Tiled editor, it's pretty neat, but I'm not a big fan on the XML format for maps.  It also seems to be more complex than necessary and would require changes to the engine itself to fully support (e.g. changeable render order for tiles... weird, and kind of pointless).  And are there even any XML parsers for JS?  I'm not familiar with any if there are.
Title: Re: minisphere 2.0b1 (stable 1.7.11)
Post by: Flying Jester on October 11, 2015, 04:14:14 pm
Tiled can also output JSON, and many other formats.
Title: Re: minisphere 2.0b1 (stable 1.7.11)
Post by: Fat Cerberus on October 11, 2015, 04:48:39 pm
Do you lose the full feature set if you do though?  or would it be like saving an MS Word document in RTF, it keeps most of the formatting but you lose the more intricate stuff?
Title: Re: minisphere 2.0b2 (stable 1.7.11)
Post by: Fat Cerberus on October 12, 2015, 03:12:21 am
New minisphere 2.0 beta up with a few more engine improvements and previewing the recent Sphere Studio overhaul.  minisphere is finally starting to look like a real development platform! ;D
Title: Re: minisphere 2.0b1 (stable 1.7.11)
Post by: DaVince on October 13, 2015, 11:59:03 am
Awesome work. :)


Do you lose the full feature set if you do though?  or would it be like saving an MS Word document in RTF, it keeps most of the formatting but you lose the more intricate stuff?

From what I could see, it makes a perfect copy of all the data in the map. I tried all the different layer types, tile rotation, objects, custom properties, basically all of the major features in the editor. See attached file.
Title: Re: minisphere 2.0b2 (stable 1.7.11)
Post by: Fat Cerberus on October 14, 2015, 07:44:20 pm
I'm thinking I'm going release minisphere 2.0 as-is, with only basic file copy and SPK creation for Cell.  I started out a bit more ambitious than this, I wanted it to have various builders for maps, spritesets, etc. but that will require a bit more effort than anticipated--there's no way to specify collision data with only images, for example.  So implementing that will need more thought.

The only other improvement I might make for 2.0 is a new SGM format, probably JSON-based.  The current format is starting to show its age, especially in light of the recent SphereFS enhancements and such.
Title: Re: minisphere 2.0b2 (stable 1.7.11)
Post by: Fat Cerberus on October 17, 2015, 02:01:08 am
Want to hear something awesome?  Cell is completely compatible with Sphere 1.5. :D  I added a Cellscript to "In the Steps of the Blackfoot" (if anyone remembers, that was my first minisphere compatibility target), then used Cell to make an SPK from it and Sphere 1.5 ran the SPK with no issues.

I wasn't sure if it would work because I've had issues in the past with SPK creation where minisphere will read the package just fine but Sphere 1.5 either locks up or crashes when given the same package.  So it's good to know I finally got it right.
Title: Re: minisphere 2.0b2 (stable 1.7.11)
Post by: Radnen on October 17, 2015, 04:14:15 am
That's awesome!
Title: Re: minisphere 2.0b2 (stable 1.7.11)
Post by: Fat Cerberus on October 21, 2015, 02:57:36 pm
Progress report:
2.0 release has been delayed somewhat due to unforeseen issues.  I wanted to release it last week, but decided to implement a game.sgm replacement... and that uncovered a few shortcomings in the way the engine is currently set up.

Long story short: JS context handling is broken.  minisphere uses a single Duktape context which is created at launch and whose pointer is stored in a global variable.  This is normally fine--only one game can be run at a time.  The issues show up when a startup game is used: calling GetGameList() creates new temporary sandboxes which share the global JS environment and clobber stuff.  This in turn causes weird crashes when switching games that are difficult to pin down.  Fixing this will require a bit of refactoring, not sure how much actual work is involved yet.

Cell is basically finished though, so that's good.
Title: Re: minisphere 2.0b2 (stable 1.7.11)
Post by: Flying Jester on October 21, 2015, 03:24:30 pm
This was a huge issue in V8 and SM, too.

I for one don't really think that the game loading functions are that useful, and they go pretty hard against how modern JS engines actually work.
Title: Re: minisphere 2.0b2 (stable 1.7.11)
Post by: Fat Cerberus on October 21, 2015, 04:51:28 pm
The way I implemented it in minisphere is actually pretty clean: ExecuteGame() is simply a longjmp back into main() which shuts down everything and restarts with the new game (Duktape uses longjmp itself so it tolerates such antics).  The fix for this is easy in theory: Duktape contexts are completely independent of one another, so sandboxing is trivial.  The main issue preventing a quick fix is that API functions are also registered globally.
Title: Re: minisphere 2.0b2 (stable 1.7.11)
Post by: Fat Cerberus on October 22, 2015, 02:31:14 am
Good news: I managed to fix the bug without a huge amount of refactoring.  Which is good, because the Duktape context wasn't even the half of it: There are file-scoped static variables all over the place, etc. that would need to be sandboxed as well.

The game.sgm replacement I came up with is nifty: It's JSON-based, and all properties contained in it are exposed to script by calling GetGameManifest().  This is useful for embedding game-specific data directly in the manifest, for example debugging options, and in the future it would even be possible to store the debugger map directly in the .s2gm file (Cell currently writes it to a separate file, sourcemap.json, by analogy with MSVC's .pdb files).
Title: Re: minisphere 2.0b2 (stable 1.7.11)
Post by: Fat Cerberus on October 22, 2015, 01:21:25 pm
Just fixed the bug this morning where minisphere can't load images with the wrong file extension.  The latest Allegro release (5.1.12) includes a fix for this, but building it in Windows is a pain (its CMake script can never find all the dependencies, making it work is an exercise in frustration) so I added a workaround myself.  I'm determined to get KR running out of the box, hehe. :P

I may have mentioned this above but const works now, thanks to a quick hack by the author to add it as an alias for var.

The only thing I really have left to do is give the code another quick lookover to make sure there are no inconsistencies with the new behavior and perhaps strengthen the sandbox somewhat (it currently allows relative paths to go out of the game directory when it probably shouldn't).
Title: Re: minisphere 2.0b2 (stable 1.7.11)
Post by: Radnen on October 22, 2015, 10:22:30 pm

I may have mentioned this above but const works now, thanks to a quick hack by the author to add it as an alias for var.


That is the single best thing. Man, I think that's it then, you've reimplemented Sphere (minus a few small things?)
Title: Re: minisphere 2.0b2 (stable 1.7.11)
Post by: Fat Cerberus on October 22, 2015, 11:21:40 pm
Pretty much, yeah.  There are a handful of lesser-used APIs that I never bothered to implement such as Complex(), but otherwise nearly 100% of the Sphere API is there.  I even managed to add all the new stuff for 2.0 without changing the semantics of the legacy functions.  Of course that was only possible because Sphere doesn't have constructors. :)

Oh, and there are also a few regexes that don't work under minisphere because Duktape's parser is stricter to the ES standards than most engines.  Not much I can do there.
Title: Re: minisphere 2.0b2 (stable 1.7.11)
Post by: Fat Cerberus on October 23, 2015, 03:08:14 am
Okay, I improved the path handling in the latest minisphere commit.  Fully rooted (absolute) paths are still allowed; however, a relative path like this:

Code: (javascript) [Select]

var image = new Image("../../../image.png");


will be rejected with a very clear error message ("SphereFS sandbox violation").  This is an improvement over Sphere 1.5, which I believe just says something stupidly vague like "invalid filename".
Title: Re: minisphere 2.0b2 (stable 1.7.11)
Post by: Fat Cerberus on October 23, 2015, 10:12:18 am
Regarding compatibility, I discovered that this line in Blockman doesn't work:
Code: (javascript) [Select]
Debug.log("Can't deserialize: {?}", o.toSource(), LIB_ERROR);


It craps out with a "not callable" error because Duktape doesn't support .toSource().  Apparently that's a Spidermonkey-specific thing.  Duktape doesn't track source code for functions at all, even calling .toString() on a function just gives you an empty function body.

The debugger is such an awesome thing to have by the way, normally with Sphere I would have to drill down into the project tree to find the file (annoying when there are multiple levels of subfolders), then scroll to the correct line, instead I just let the debugger open the file and highlight the line for me. :)
Title: Re: minisphere 2.0b2 (stable 1.7.11)
Post by: Fat Cerberus on October 24, 2015, 11:55:24 pm
Last-minute debugger feature addition: You can double-click any callstack entry while stopped at a breakpoint to see the values of variables in that function.  Unfortunately you can only Eval in the context of the topmost call, so you can only view primitive values in this case. :(

edit: Scratch that, Eval is supported now as well. :)
Title: Re: minisphere 2.0.0
Post by: Fat Cerberus on October 26, 2015, 09:03:53 pm
minisphere 2.0 is out! ;D

A few planned features got knocked off the checklist, but regardless this is still a very worthy upgrade.  The only thing I didn't get to yet was writing an API reference for Cell, but seeing as that API consists of exactly four functions, it shouldn't be a big issue.  I'll get to it eventually.

The debugger improvements are worth the upgrade alone--you can now view variables at any point in the call chain, not just from the currently executing function.  Plus you get some neat goodies like 16-bit and float support for Audialis, better integration of ArrayBuffers, and of course, the new S2GM format.
Title: Re: minisphere 2.0.0
Post by: N E O on October 28, 2015, 05:10:38 pm
Remind me to try 2.0.0 on my OSX Mavericks this weekend!
Title: Re: minisphere 2.0.0
Post by: Fat Cerberus on October 28, 2015, 09:52:04 pm
Sure, you should be good as far as Allegro goes, I'm still using 5.1.11.  minisphere and Cell both build with no issues under Linux using SCons, so you should be good.  Unfortunately, single-step debugging is Windows-only for the moment because I haven't made a command-line debugger yet, so you need Sphere Studio for that.
Title: Re: minisphere 2.0.1
Post by: Fat Cerberus on October 30, 2015, 01:33:35 am
Just posted minisphere 2.0.1 which fixes a bunch of crashes and adds an API reference for Cell.  The installer has been improved somewhat, too.
Title: Re: minisphere 2.0.1
Post by: Fat Cerberus on October 30, 2015, 07:25:13 pm
New feature in latest Git build: SetScreenSize() API allowing to change screen resolution on the fly.  No more ugly hacks modifying the .sgm and restarting. :P

edit: Sneak peak of what's in the pipeline so far for minisphere 2.1:

Title: Re: minisphere 2.0.1
Post by: Fat Cerberus on November 01, 2015, 01:53:20 am
Regarding the checked extensions, you have to use an S2GM manifest first of all, and add a minimumPlatform object to it, like this:

Code: (javascript) [Select]

install(s2gm({
name: "Spectacles: Bruce's Story",
author: "Fat Cerberus",
summary: "Follow Scott Starcross in his quest to stop the Primus.",
resolution: '320x240',
script: 'scripts/main.js',

minimumPlatform: {
recommend: "minisphere 2.1 or later",
apiVersion: 2.0,
extensions: [
"sphere-legacy-api",
"sphere-obj-constructors",
"sphere-obj-props",
"sphere-map-engine",
"sphere-rng-object",
"sphere-s2gm",
"sphere-spherefs",
]
},
}));


The engine will then check for required extensions when loading the game, before any JS code is even executed.  This is better than leaving the requirements check completely up to script, as RequireScript()'d scripts may actually cause a runtime error before the check can be done if they use any extended functionality.
Title: Re: minisphere 2.1.0
Post by: Fat Cerberus on November 01, 2015, 10:39:50 am
In what must be the fastest turnaround for a release in minisphere history, even by my standards, minisphere 2.1 is now available for download! ;D

Now I think I'll take a much-needed break from my tireless work on the engine to work on Spectacles instead... It is, after all, the whole reason I started working on minisphere on the first place. :P
Title: Re: minisphere 2.1.0
Post by: FBnil on November 17, 2015, 09:35:03 pm
You say that... but I still get updates on the git pull.
Pretty impressive so far.
Found some time to play Blackfoot. Very nice block-pushing puzzle game.
Title: Re: minisphere 2.1.0
Post by: Fat Cerberus on November 17, 2015, 10:11:38 pm

You say that... but I still get updates on the git pull.
Pretty impressive so far.
Found some time to play Blackfoot. Very nice block-pushing puzzle game.


Yeah, mostly it's just fixing little annoyances I run into while working on Specs.
Title: Re: minisphere 2.1.1
Post by: Fat Cerberus on November 25, 2015, 02:31:40 am
Quick update (2.1.1): JS errors are now more informative thanks to recent enhancements to Duktape.  Instead of a vague "invalid base value" or "not string", you now get "cannot read property 'foo' of undefined" or "number required, found string 'foobar'" and similar.
Title: Re: minisphere 2.1.1
Post by: N E O on December 02, 2015, 02:13:30 pm
I just pulled the latest source, but I've forgotten how to compile on Mac.  XP

Please refresh me on compilation instructions, thanks!
Title: Re: minisphere 2.1.1
Post by: Fat Cerberus on December 02, 2015, 02:18:42 pm
You need:
Allegro 5.1.11+ (may have to build this yourself, https://github.com/liballeg/allegro5)
libmng
zlib

From the command line, switch to the minisphere source directory and run scons which will build minisphere and Cell in the bin/ subdirectory.
Title: Re: minisphere 2.1.1
Post by: N E O on December 02, 2015, 02:59:24 pm

You need:
Allegro 5.1.11+ (may have to build this yourself, https://github.com/liballeg/allegro5)
libmng
zlib

From the command line, switch to the minisphere source directory and run scons which will build minisphere and Cell in the bin/ subdirectory.


Gave a missing libmng error (pretty much the only library error left after all the previous work I did before), DLed libmng 2.0.3 from Sourceforge, one `./configure; make; sudo make install` later was able to scons minisphere!

Running my two tests worked ok, running Radnen's Cellar Rush gave a LoadSound() error - failed to load some ogg file. I've previously had trouble building Allegro on this Mac with extended sound capabilities (including anything libogg related), so this one's probably on me.

Other than Allegro-specific or me-specific things like the libogg issue, it builds on Mac OS X Mavericks! I'll take a look at Allegro stuff later.

This current building served two purposes: make sure current minisphere builds and runs on Mavericks, and set up a prep environment related to my game dev and my RFC about adding Python (http://forums.spheredev.org/index.php/topic,1320.0.html).
Title: Re: minisphere 2.1.1
Post by: Fat Cerberus on December 02, 2015, 03:21:49 pm
Here's the thing with Allegro: By default it dynamically loads audio codecs such as libogg at runtime, and gracefully degrades if they are missing (this is annoying).  You can static link them if you disable the CMAKE flag WANT_ACODEC_DYNAMIC_LOAD, not sure how feasible that is on OS X though.  Either way, additional dependencies needed for Allegro audio:

dumb
libFLAC
libogg
libvorbis
libvorbisfile

They really need to get rid of that "dynamic link by default" feature, it causes so many headaches.
Title: Re: minisphere 2.1.1
Post by: Fat Cerberus on December 03, 2015, 11:43:58 pm
@NEO: Did you get Allegro to build properly with sound support?
Title: Re: minisphere 2.1.1
Post by: N E O on December 04, 2015, 01:37:46 pm

@NEO: Did you get Allegro to build properly with sound support?


Not yet; for reference, Allegro's cmake is giving me the following output (tl;dr - I'm missing libFLAC, libdumb, libvorbis):

Quote

-- Allowing GCC/Clang to use SSE instructions
-- Could NOT find PkgConfig (missing:  PKG_CONFIG_EXECUTABLE)
S3TC locking disabled. You will not be able to load/save pre-compressed textures with OpenGL.
-- Could NOT find OPENSL (missing:  OPENSL_INCLUDE_DIR OPENSL_LIBRARY)
-- Could NOT find FLAC (missing:  FLAC_INCLUDE_DIR)
WARNING: libFLAC not found or compile test failed, disabling support.
-- Could NOT find DUMB (missing:  DUMB_INCLUDE_DIR DUMB_LIBRARY)
WARNING: libdumb not found or compile test failed, disabling support. <http://dumb.sourceforge.net/>
-- Could NOT find OGG (missing:  OGG_INCLUDE_DIR)
WARNING: libvorbis not found or compile test failed, disabling support.
-- Could NOT find OGG (missing:  OGG_INCLUDE_DIR)
-- Could NOT find OGG (missing:  OGG_INCLUDE_DIR)
WARNING: allegro_video wanted but no supported backend found
-- Not building ex_video
-- Configuring done
CMake Warning (dev):
  Policy CMP0042 is not set: MACOSX_RPATH is enabled by default.  Run "cmake
  --help-policy CMP0042" for policy details.  Use the cmake_policy command to
  set the policy and suppress this warning.

  MACOSX_RPATH is not specified for the following targets:

   allegro
   allegro_acodec
   allegro_audio
   allegro_color
   allegro_dialog
   allegro_font
   allegro_image
   allegro_main
   allegro_memfile
   allegro_physfs
   allegro_primitives
   allegro_ttf

This warning is for project developers.  Use -Wno-dev to suppress it.

-- Generating done
-- Build files have been written to: /Users/lux/dev/allegro5/Build
Title: Re: minisphere 2.1.1
Post by: Fat Cerberus on December 05, 2015, 12:35:28 am
You think this is bad, you should have seen me try to build Allegro on Windows when I first upgraded to 5.1.  Even with CMake it's a nightmare, sometimes it doesn't find libraries that are actually present, or they'll fail a compile test for no reason at all (which CMake then "remembers" and won't try again until you blow away the entire build cache and start over).  This is why I'm still using Allegro 5.1.11 even though 5.1.12 has some new stuff that would actually be useful to have (such as cross-platform clipboard support).

Allegro is a great library, but their build process needs a lot of work.
Title: Re: minisphere 2.1.1
Post by: Flying Jester on December 05, 2015, 03:53:29 am
Even with CMake it's a nightmare


CMake is just always a bit of a nightmare. This is a pretty normal experience with it, especially on Windows.
Title: Re: minisphere 2.1.1
Post by: Fat Cerberus on December 08, 2015, 01:17:10 pm
I got minisphere to compile with Chipmunk2D linked in.  So minisphere 2.2 will definitely have some kind of physics support, once I figure out a good API structure.

Originally I was going to try to copy the particle engine from Sphere 1.6, but I'm thinking now that a more general-purpose physics engine will be better in the long run.
Title: Re: minisphere 2.1.1
Post by: Fat Cerberus on December 11, 2015, 12:36:38 pm

Even with CMake it's a nightmare


CMake is just always a bit of a nightmare. This is a pretty normal experience with it, especially on Windows.


In large part this seems to be caused by CMake's braindead caching setup: When a variable is set, its value is stored in the CMakeCache and future accesses will always just read from the cache.  There doesn't appear to be any kind of conditional logic where the cached value can be ignored when something related to it changes.
Title: Re: minisphere 2.1.3
Post by: Fat Cerberus on December 15, 2015, 02:41:23 am
Just implemented: Error copying.  Finally you can press Ctrl+C on the error screen to copy error text (and filename/line number) directly to the clipboard.  This has been a long time coming.
Title: Re: minisphere 2.1.3
Post by: Radnen on December 15, 2015, 02:47:12 am

Just implemented: Error copying.  Finally you can press Ctrl+C on the error screen to copy error text (and filename/line number) directly to the clipboard.  This has been a long time coming.


Ok, that's it. I'm done with Sphere 1.5/1.6. That was the secret. I wanted you to do that, but never said, and now that you did it, bye bye Sphere 1.5/1.6. :)
Title: Re: minisphere 2.1.3
Post by: Fat Cerberus on December 15, 2015, 03:20:52 am

Ok, that's it. I'm done with Sphere 1.5/1.6. That was the secret. I wanted you to do that, but never said, and now that you did it, bye bye Sphere 1.5/1.6. :)


Hehe.  I wanted to do this a while ago, but I was too lazy to research the clipboard APIs for the different platforms.  As of Allegro 5.1.12, basic clipboard functions are built-in, so I took advantage of it.

2.1.3 doesn't include the feature, but it's in the git repository anyway (Windows build requires VC++2015).  If I release a 2.1.4 I'll backport it, otherwise it'll be in v2.2 along with some sort of physics support.  I haven't quite worked out a good API for that yet.
Title: Re: minisphere 2.1.4
Post by: Fat Cerberus on December 16, 2015, 12:22:39 am
Okay, Radnen, you lucked out, I had to fix a map engine bug related to GrabImage() (actually a regression due to a careless recent change to the map update loop) so I released a hotfix.  Said hotfix happens to include the error message copying, so now you can download minisphere 2.1.4 and ditch Sphere 1.x if you want. ;)

As for physics, the API is going to need some more thought before I forge ahead with it, so I'm postponing it to minisphere 3.0.  Instead I think I'll dedicate minisphere 2.2 to improving Cell.  What was released of it with minisphere 2.0 is little more than a prototype and I'd like to make it a more invaluable part of the Sphere toolchain.
Title: Re: minisphere 2.1.4
Post by: casiotone on December 16, 2015, 11:20:53 am
Having an issue building this again on OS X - I've installed Allegro 5.0.11 through homebrew and I'm getting this when running scons:

Code: [Select]
scons: Reading SConscript files ...
scons: done reading SConscript files.
scons: Building targets ...
gcc -o obj/msphere/main.o -c -DDUK_OPT_HAVE_CUSTOM_H obj/msphere/main.c
obj/msphere/main.c:183:44: error: use of undeclared identifier 'ALLEGRO_PROGRAMMABLE_PIPELINE'
        al_set_new_display_flags(ALLEGRO_OPENGL | ALLEGRO_PROGRAMMABLE_PIPELINE);
                                                  ^
obj/msphere/main.c:624:5: warning: implicit declaration of function 'al_set_clipboard_text' is invalid in C99
      [-Wimplicit-function-declaration]
                                al_set_clipboard_text(g_display, msg);
                                ^
obj/msphere/main.c:779:13: warning: using the result of an assignment as a condition without parentheses [-Wparentheses]
        while (fse = al_read_directory(engine_dir)) {
               ~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
obj/msphere/main.c:779:13: note: place parentheses around the assignment to silence this warning
        while (fse = al_read_directory(engine_dir)) {
                   ^
               (                                  )
obj/msphere/main.c:779:13: note: use '==' to turn this assignment into an equality comparison
        while (fse = al_read_directory(engine_dir)) {
                   ^
                   ==
2 warnings and 1 error generated.
scons: *** [obj/msphere/main.o] Error 1
scons: building terminated because of errors.


Any ideas?
Title: Re: minisphere 2.1.4
Post by: Fat Cerberus on December 16, 2015, 11:45:36 am
Yeah, you need Allegro 5.1 "unstable" (i.e. the API is unstable, it's actually quite reliable).  Not sure if that's available through homebrew; you may need to build Allegro yourself:
http://github.com/liballeg/allegro5
Title: Re: minisphere 2.1.4
Post by: casiotone on December 17, 2015, 07:46:36 am
Thanks, managed to build Allegro. Now having a problem with libmng - I can't get that to build on OS X at all. I have no plans to actually use MNG, is there any chance you could add an option to compile without MNG support?
Title: Re: minisphere 2.1.4
Post by: Fat Cerberus on December 17, 2015, 10:17:35 am
You're the second person to request that, I'll see what I can do.  For now you can probably disable it by:
* Remove 'animation.c' from msphere_sources in the SConscript
* Remove 'mng' from msphere_libs in the SConscript
* Comment out the call to init_animation_api() in api.c

There's been talk of Allegro adding optional MNG support to the library; if that happens I can do away with my own libmng dependency.  Oh, that reminds me, watch out with Allegro's audio support; if you didn't set WANT_ACODEC_DYNAMIC_LOAD=0 when using Allegro's CMake, then it attempts to dynamically load libvorbis, etc. at runtime and fails silently if it can't, so if minisphere fails to load any sound files--it's most likely not my fault! ;)
Title: Re: minisphere 2.1.4
Post by: Fat Cerberus on December 17, 2015, 10:22:03 pm
By the way, casiotone: I just found out you didn't have to compile Allegro from source after all.  5.1.12 was available on homebrew after all, the command is:
brew install --devel allegro

@NEO: You might want to take note of the above as well. :)
Title: Re: minisphere 2.1.4
Post by: N E O on December 17, 2015, 11:07:23 pm

By the way, casiotone: I just found out you didn't have to compile Allegro from source after all.  5.1.12 was available on homebrew after all, the command is:
brew install --devel allegro

@NEO: You might want to take note of the above as well. :)


Two errors:

Code: [Select]

airlux:magento lux$ brew install --devel allegro
Error: You must `brew link libogg libvorbis cmake freetype flac' before allegro can be installed


...then...

Code: [Select]

airlux:magento lux$ brew link libogg libvorbis cmake freetype flac
Linking /usr/local/Cellar/libogg/1.3.2...
Error: Could not symlink lib/libogg.0.dylib
Target /usr/local/lib/libogg.0.dylib
already exists. You may want to remove it:
  rm '/usr/local/lib/libogg.0.dylib'

To force the link and overwrite all conflicting files:
  brew link --overwrite libogg

To list all files that would be deleted:
  brew link --overwrite --dry-run libogg


Give me a bit of time to eventually focus on doing this and I'll let y'all know results.
Title: Re: minisphere 2.1.4
Post by: casiotone on December 18, 2015, 01:59:23 pm

You're the second person to request that, I'll see what I can do.  For now you can probably disable it by:
* Remove 'animation.c' from msphere_sources in the SConscript
* Remove 'mng' from msphere_libs in the SConscript
* Comment out the call to init_animation_api() in api.c

There's been talk of Allegro adding optional MNG support to the library; if that happens I can do away with my own libmng dependency.  Oh, that reminds me, watch out with Allegro's audio support; if you didn't set WANT_ACODEC_DYNAMIC_LOAD=0 when using Allegro's CMake, then it attempts to dynamically load libvorbis, etc. at runtime and fails silently if it can't, so if minisphere fails to load any sound files--it's most likely not my fault! ;)


Works like a charm, thanks again.
Title: Re: minisphere 2.1.5
Post by: Fat Cerberus on December 19, 2015, 01:08:56 am
minisphere 2.1.5 fixes corruption at the end of a WAV stream (note: this was an Allegro bug) and adds an option to the GDK plugin to Test Game in windowed mode.  The default is still fullscreen, of course.
Title: Re: minisphere 2.1.6
Post by: Fat Cerberus on December 24, 2015, 01:38:13 pm
So I've been thinking on and off about the direction I want to go with in minisphere 3.0, but I've been wracking my brain because pretty much all of what I set out to implement has been implemented as of minisphere 2.1.  I haven't even been able to muster a clear plan for a v2.2 (which will likely end up just being some Cell enhancements), let alone a major upgrade.  Which really only leaves one more hurdle: plugins.  The engine already has most of the framework in place for this (the extension system), most of the work would be coming up with an API.
Title: Re: minisphere 2.1.6
Post by: FBnil on December 25, 2015, 12:37:36 pm
http://www.drdobbs.com/cpp/building-your-own-plugin-framework-part/204202899

I like DrDobbs magazine for the conceptual things it contains. Just relax, sit down in non-programming mode, and read it. Around page 3/4 it goes into code... maybe it gives you an idea on how to start the API.
Title: Re: minisphere 2.1.6
Post by: DaVince on December 29, 2015, 07:51:22 pm
Hey, so this is just my selfishness speaking, but how feasible would a software renderer mode be? :P I'm developing something while temporarily on quite a crappy computer (Supports up to OpenGL 1.3...) so I obviously stumbled against the issue of not being able to run minisphere.
Title: Re: minisphere 2.1.6
Post by: Fat Cerberus on December 29, 2015, 07:54:21 pm
Hm, in theory it's possible to initialize Allegro in D3D mode, which would raise compatibility.  The downside is that shader support would be disabled, but it would allow the rest of the functionality (including base Galileo) to work.  I'll see about making that change in minisphere 2.2.
Title: Re: minisphere 2.1.6
Post by: Flying Jester on January 01, 2016, 07:30:54 pm
I've read that Dr Dobb's article, and I'm not really a fan of how they do it.

I did about the simplest thing in TurboSphere. The API looked like this:

Code: (C) [Select]

const char *Init(JSContext *ctx); // Returns the plugin name.

int GetNumFunctions(JSContext *ctx);
const char *GetFunctionName(JSContext *ctx, int i);
JSNative GetFunction(JSContext *ctx, int i);

int GetNumVariables(JSContext *ctx);
const char *GetVariableName(JSContext *ctx, int i);
void GetVariable(JSContext *ctx, int i, JSMutableHandle out); // It's much better to use an out-parameter for handles with SpiderMonkey.

void Close(); // Closes the plugin.


I'm still using a variant on that in UltraSphere/Turbo. I guess why complicate things, I never found I needed anything more than this. With how minisphere handles extensions, you could also add a GetExtension/GetNumExtensions component.

That's just my two cents from my own experiments.
Title: Re: minisphere 2.1.6
Post by: Fat Cerberus on January 01, 2016, 09:58:37 pm

I've read that Dr Dobb's article, and I'm not really a fan of how they do it.


I have to agree.  I looked over it and the very OO method they provided just seemed overcomplicated for most purposes.  That said, I did use a similar setup when I overhauled Sphere Studio's plugin API, but at least there it's justified since 1) There are a bunch of different plugin roles (debugger, editor, engine runner, and so on) but I needed to be able to have one plugin implement multiple roles while still having a unified interface, and 2) It's C#, so I don't have to worry about name mangling differences, etc. like I would with C++.
Title: Re: minisphere 2.1.6
Post by: DaVince on January 03, 2016, 02:02:38 pm
minisphere now runs on my ancient OpenGL 1.3-only system. Thanks a lot for the support, Lord English. :)
Title: Re: minisphere 2.1.6
Post by: Fat Cerberus on January 07, 2016, 02:36:58 am
Having just started work on minisphere 3.0, a question occurs to me: Would anyone be opposed if, for the 3.0 Windows release, I provided only a 64-bit build?  The x86 build seems pretty redundant nowadays, I personally haven't encountered a 32-bit version of Windows in years.
Title: Re: minisphere 2.1.6
Post by: FBnil on January 07, 2016, 05:48:17 pm
On older systems, there are many other game makers... go for gold. When the time comes, compile for 128-bit.
Before you tag and go to 3, can you take a tiny look at Linux? My latest succesful build was Nov 29. And

Code: [Select]
obj/msphere/main.o: In function `main':
main.c:(.text+0x3ce): undefined reference to `al_set_new_window_title'
obj/msphere/main.o: In function `on_duk_fatal':
main.c:(.text+0x1e32): undefined reference to `al_set_clipboard_text'
collect2: error: ld returned 1 exit status
scons: *** [obj/msphere/msphere] Error 1
scons: building terminated because of errors.
Title: Re: minisphere 2.1.6
Post by: Fat Cerberus on January 07, 2016, 05:55:01 pm
You need Allegro 5.1.12 for the current builds.  If you're using Ubuntu there are PPA packages available, otherwise you'll have to compile it yourself.

Basically whenever you get undefined references to a function starting with al_, you need to update Allegro.
Title: Re: minisphere 2.1.6
Post by: DaVince on January 08, 2016, 07:50:10 pm
Is there a way to make the build system spew out that bit of information?

Also, I don't mind you dropping the 32-bit Windows version too much. Poor Windows XP users though... :P
Title: Re: minisphere 2.1.6
Post by: Flying Jester on January 08, 2016, 07:51:47 pm
It would be simple in SCons using `Configure` to check for a certain library and then function in it, and then print out such a warning.
Title: Re: minisphere 2.1.6
Post by: Fat Cerberus on January 08, 2016, 07:58:14 pm
Actually does minisphere even run on WinXP?  Defiant had issues a while back, I think I fixed it but I don't have an XP machine to test on.

I'm going to work on improving the documentation for minisphere 3.0.  Developer documentation is still pretty scant right now because I've been lazy.  I need to get off my duff for 3.0. :P
Title: Re: minisphere 2.1.6
Post by: FBnil on January 09, 2016, 04:45:53 pm
git tag just shows 5.1.11 (from git clone git://git.code.sf.net/p/alleg/allegro) will wait for 5.1.12 because my HEAD is not compiling at the moment.
Title: Re: minisphere 2.1.6
Post by: Fat Cerberus on January 09, 2016, 04:50:43 pm
Try cloning from https://github.com/liballeg/allegro5 instead.  They switched to GitHub recently so I don't think the SourceForge repo is maintained anymore.
Title: Re: minisphere 2.1.6
Post by: FBnil on January 09, 2016, 05:06:34 pm
Wow, quick, yes git clone https://github.com/liballeg/allegro5.git
has a 5.1.12.0 tag...

Sorry for asking, in another thread I stated:
Quote
Allegro "make" only plays nice if I disable FFMPEG and CG

.... but I can not remember how I did that (and it is not in my howto.txt I always write what I do...)
Title: Re: minisphere 2.1.6
Post by: Fat Cerberus on January 09, 2016, 05:52:10 pm
Did you try Allegro's cmake?
Title: Re: minisphere 2.1.6
Post by: FBnil on January 09, 2016, 07:22:44 pm
When running for the second time I get

Code: [Select]
-- Allowing GCC/Clang to use SSE instructions
S3TC locking disabled. You will not be able to load/save pre-compressed textures with OpenGL.
-- Could NOT find OPENSL (missing:  OPENSL_INCLUDE_DIR OPENSL_LIBRARY)
-- Configuring done
-- Generating done
-- Build files have been written to: /home/fbnil/MiniSphere/allegro5/Build

But I do not remember requiring that last time. Do you mean editing AllegroFindFFMPEG.cmake there remove FFMPEG... and... yes... now it compiles, and I can make install. hmm... did not recall this. Same error in minisphere though. Will check tomorrow, last time, I had to purge the previous Allegro version before it started working (too late now, need Zzzz)
Title: Re: minisphere 2.1.6
Post by: Fat Cerberus on January 09, 2016, 07:27:03 pm
If Allegro cmake can't find FFMPEG it should just disable the video component (or at least that's how it's supposed to work).  This is fine since minisphere doesn't use that part.  You should be in the clear.
Title: Re: minisphere 2.1.6
Post by: Fat Cerberus on January 09, 2016, 07:38:26 pm
To everyone else: I'm in the process of writing a full install guide for minisphere.  This should hopefully alleviate some of the issues seen in the past for people building minisphere on non-Windows platforms.
Title: Re: minisphere 2.1.6
Post by: DaVince on January 09, 2016, 08:27:37 pm

Actually does minisphere even run on WinXP?  Defiant had issues a while back, I think I fixed it but I don't have an XP machine to test on.


Well, I could probably test this soon... Just need to shrink my Linux partition on this old PC and install XP on it. Depending on the last version that works, you could still offer that as the last 32-bit version download for those who really are stuck on 32-bit Windows. :)
Title: Re: minisphere 2.1.6
Post by: Defiant on January 10, 2016, 12:06:25 am

Actually does minisphere even run on WinXP?  Defiant had issues a while back, I think I fixed it but I don't have an XP machine to test on.


I haven't got it to work yet on my XP machine. Doesn't crash, just loads up a dialog and then exits, can't see the error before it disappears.
Title: Re: minisphere 2.1.6
Post by: Fat Cerberus on January 10, 2016, 12:09:23 am
Huh, that's weird.  Perhaps I'll try setting up a VM with XP to try to diagnose it.
Title: Re: minisphere 2.1.6
Post by: Fat Cerberus on January 10, 2016, 03:23:56 am
For SSJ, to make it as efficient as possible to debug on the command-line, I think I want to go with 1- or 2-character commands, for example "s" to step, "st" for a stack trace, "v" to list local variables, and so on.  No prefixing commands with a dot or ! as that just slows down command entry.

I'm not sure yet how to handle locating sources for a game.  Cell can optionally include a source map if needed when building a game (this is very useful as it allows SPKs to be debugged!), but even that uses relative paths.  In Sphere Studio it's trivial to just resolve the relative path against the current project, but SSJ will need a command-line option or something to provide the location of the sources.

What features would you want to see in the debugger?  Keep in mind some things might not be possible until Duktape implements them in its debug API, but I'll make sure to note any requests regardless. :)
Title: Re: minisphere 2.1.6
Post by: FBnil on January 10, 2016, 08:56:03 am
I would like a break command in the code to set a breakpoint. If the break command can have an identifier, to know which one breaked....
Title: Re: minisphere 2.1.6
Post by: Fat Cerberus on January 11, 2016, 02:57:02 am
I don't know if anyone remembers the --explode switch you could pass to Cell to get an easter egg (specifically, a quote from the program's namesake), but I'm starting a tradition with SSJ where all the GDK tools will have this little secret.

For point of reference, sample output from Cell:
Code: [Select]

C:\Users\fatce>cell --explode
Cell seems to be going through some sort of transformation...
He's pumping himself up like a balloon!

    Cell says:
    "If only you'd finished me off a little bit sooner..."


And now, from SSJ:
Code: [Select]

C:\Users\fatce>ssj --explode
Release it, release everything! Remember all the pain he's caused, the people
he's hurt--now MAKE THAT YOUR POWER!

    Cell says:
    "Would you stop interfering!?"


;D

Let nobody say I don't have lots of fun while programming these tools!
Title: Re: minisphere 2.1.6
Post by: Fat Cerberus on January 11, 2016, 09:13:53 am
Also see this:
https://github.com/fatcerberus/minisphere/issues/56

:P
Title: Re: minisphere 2.1.6
Post by: Flying Jester on January 11, 2016, 11:24:46 pm


Actually does minisphere even run on WinXP?  Defiant had issues a while back, I think I fixed it but I don't have an XP machine to test on.


I haven't got it to work yet on my XP machine. Doesn't crash, just loads up a dialog and then exits, can't see the error before it disappears.


Try running it in a cmd.exe console? That's usually the thing to do when errors pop up too fast to read.
Title: Re: minisphere 2.1.6
Post by: Defiant on January 13, 2016, 11:13:52 pm
So it crashes when it tries to create the window. I copied the data it contains in the technical stuff, let me know if anything else would help diagnose this.
Title: Re: minisphere 2.1.6
Post by: Fat Cerberus on January 13, 2016, 11:48:15 pm
I see you're using minisphere 1.7.4.  I was going to suggest upgrading to 2.1.6, but I think I know the cause of the bug: Your machine might not support OpenGL shaders.  minisphere currently requires shader support to run.  In the latest builds I added a fallback for that, but I didn't backport the fix to 2.1 because I figured it wasn't a practical concern.  Seems I was wrong. ;)

I'll try running minisphere in my XP VM to verify my theory.

edit: Hm.  The last line printed out by minisphere 2.1.6 on my Hyper-V WinXP SP3 VM is:
Code: [Select]

Looking for a game to launch


Seemingly no crash, though.  Really weird.  I'll review the code for the "looking for a game" to see if I can find anything.
Title: Re: minisphere 2.1.6
Post by: Fat Cerberus on January 14, 2016, 12:27:35 am
Interesting oddity I found: Cell doesn't work properly under XP either.  I tried compiling Spectacles with it, and was told "no Cellscript.js in input directory", which is patently false.  So it seems this might be file system-related.  I'll keep digging.
Title: Re: minisphere 2.1.6
Post by: Defiant on January 14, 2016, 10:51:58 pm
Sorry, I should clarify that I can load a game, doesn't matter which one, but it fails to load the window when launching the game, sorry for the confusion.
Title: Re: minisphere 2.1.6
Post by: Fat Cerberus on January 14, 2016, 11:04:48 pm
So it successfully runs the startup game?  That's quite strange then.
Title: Re: minisphere 2.1.6
Post by: Defiant on January 15, 2016, 06:13:20 pm
It successfully loads minisphere. It allows me to select a game, but then crashes there after. It doesn't load the game.
Title: Re: minisphere 2.1.6
Post by: Fat Cerberus on January 17, 2016, 08:24:33 pm
Good news everyone: I finally got Ubuntu 14.04 successfully installed on my laptop to dual boot with Win10.  What this means is that I can actively support the engine code on both Windows and Linux now (or Ubuntu, at least).  Now if only I had a Mac, we'd have the trifecta...

If I could get some official Ubuntu packages going that'd be great for exposure too, I think.
Title: Re: minisphere 2.1.6
Post by: FBnil on January 18, 2016, 04:56:14 pm
Yes, that would certainly help a lot. You have time until Allegro 5.x hits Ubuntu (at least, your unstable version with the code you need to get it compiled/running).
Also: Documentation documentation documentation.
From using it as node.js (sphere was a crappy node.js, but I could serve webpages)... hmm.. maybe not this one...
to debugger (good work getting it working!)
to using it like image magick (I have some turtle code I think lost it) read png, add text, write to jpg things. Read file, parse data, create graph...
to well... a game making software.
Bundle it with some small default examples (from pianola to slideshow, an rpg, a sidescroller, things like that)

I still need to get into the code to add the things I miss (like changing the spriteset directions labels to "swap" graphics) and test out if I finally can access the spriteset image to mix it (overlay different hair (processed through a color matrix) and such to generate spritesets on the fly).

oh boy oh boy... very good news...
Title: Re: minisphere 2.1.6
Post by: N E O on January 19, 2016, 02:18:44 am

Now if only I had a Mac, we'd have the trifecta...


If you personally invest money in a Mac, I highly recommend getting into iOS app dev at that point, since IMO that's the only thing a Mac can do properly that no other OS can come close to (basically the iOS equivalent of the C#+Visual Studio vs. Mono+MonoDevelop and/or maybe the wine vs. Windows debate).
Title: Re: minisphere 2.1.6
Post by: Fat Cerberus on January 19, 2016, 03:30:15 am
I have to say I'm not liking Linux as a development environment.  It has all kinds of neat tools like valgrind (note: minisphere, Cell and SSJ all leak like a sieve :P), and of course the package system makes it ridiculously quick and simple to install new stuff, but for everyday code maintenance I'd much rather have Visual Studio, bloat and all.

Doing everything from the terminal and using a text editor to edit source files feels like a massive downgrade after being spoiled by Intellisense.  I know there are IDEs that work on Linux, but... eh.  I think I'll just stick to Windows for primary development. ;)
Title: Re: minisphere 2.1.6
Post by: Flying Jester on January 19, 2016, 04:31:37 am
Not having Intellisense can be a good thing, too. It made me realize that if I can never remember my own API, it can be a sign it is not designed well.
Title: Re: minisphere 2.1.6
Post by: Fat Cerberus on January 19, 2016, 09:40:43 am
It's less that I can't remember the API so much as I strive for utmost readability, leading to descriptive struct member names like ignore_all_persons.  Imagine how much time it saves when Intellisense figures out, nine times out of ten, exactly which variable I want after typing only one character (and sometimes not even that!).  Then just press Tab to accept.  It's a tremendous time-saver.  I could survive without it, but code readability would likely suffer for it, as I would be too tempted to abbreviate all my variable and function names.
Title: Re: minisphere 2.1.6
Post by: FBnil on January 19, 2016, 02:13:17 pm
Well there are some IDE's that have some of the VC properties:

https://en.wikipedia.org/wiki/Code%3A%3ABlocks
https://en.wikipedia.org/wiki/Eclipse_%28software%29
https://en.wikipedia.org/wiki/Qt_Creator

I found Eclipse slow (java based) although some of my colleagues praise it so much its religous, Codeblocks very fast (runs on the OpenPandora) and complete (but not the stable release, that one is 2 years old, you really want the rc1 from a month ago). And Not sure what happened to Qt Creator, it seems like gone, but was very good a few years ago.

I am curious about http://anjuta.org/ so I'm going to give it a spin.
Never tried this one, but it looks also like something you would want to try:
https://www.kdevelop.org/sites/kdevelop.org/files/photos/Kdevelop_cpp_codetooltip.png

I actually use Notepad++ under wine. Gives me all I need.
Title: Re: minisphere 2.1.6
Post by: Radnen on January 19, 2016, 04:09:58 pm

I have to say I'm not liking Linux as a development environment.  It has all kinds of neat tools like valgrind (note: minisphere, Cell and SSJ all leak like a sieve :P), and of course the package system makes it ridiculously quick and simple to install new stuff, but for everyday code maintenance I'd much rather have Visual Studio, bloat and all.

Doing everything from the terminal and using a text editor to edit source files feels like a massive downgrade after being spoiled by Intellisense.  I know there are IDEs that work on Linux, but... eh.  I think I'll just stick to Windows for primary development. ;)


Use MonoDevelop. It's really good and had decent intellisense last I used it. Plus, apps you do happen to make on it are Mono and therefore cross-platform. I might just restart my Mono Sphere Editor one of these days...
Title: Re: minisphere 2.1.6
Post by: Fat Cerberus on January 19, 2016, 05:17:36 pm
I've been trying to get Sphere Studio to run under Mono, but no such luck.  Before the huge refactoring I did a few months back, it used to throw an exception related to the Weifen Luo controls.  Now it doesn't produce any output at all, and terminates immediately.  Not sure what's causing it and I don't know how to get debugging information out of Mono.
Title: Re: minisphere 2.1.6
Post by: Fat Cerberus on January 20, 2016, 12:41:52 am
Follow-up: I managed to pin down the Wine lockup.  It locks up whenever it tries to open a document tab.  Wine, like Mono, really seems to hate the Weifen Luo dock panel. :-\
Title: Re: minisphere 2.1.6
Post by: N E O on January 20, 2016, 01:49:10 pm

Follow-up: I managed to pin down the Wine lockup.  It locks up whenever it tries to open a document tab.  Wine, like Mono, really seems to hate the Weifen Luo dock panel. :-\


Do the Weifen Luo widgets need .NET >=4.0 or use some obscure, undocumented Win32 |API?
Title: Re: minisphere 2.1.6
Post by: Fat Cerberus on January 20, 2016, 01:57:05 pm
Sphere Studio itself requires .NET 4.5.  It's impossible to backport now since it uses async/await pretty extensively, especially in the debugger code.  But that's not the issue I don't think--everything else seems to work fine under Wine (even things I didn't expect to work, like running Cell and redirecting it's stdout to the IDE), until you go to open a file.  Then it freezes.

I think the problem is that the Weifen Luo controls abuse P/Invoke for calling into native win32 APIs, to support things like interprocess drag-and-drop.  Wine's emulation of the necessary APIs must not be perfect and so it causes deadlocks or something.

The weird thing is that the start page shows up just fine.  It's quite baffling.
Title: Re: minisphere 2.1.6
Post by: Fat Cerberus on January 24, 2016, 02:59:05 am
Here's a sneak peek at SSJ, the new console debugger that will come with minisphere GDK 3.0.  It has fancy colors and everything! ;D  As a convenience, SSJ will launch minisphere for you, meaning all you have to do to start a fresh debugging session is run ssj <filename>.  This is especially convenient on Linux, which previously required using two terminals, one to run msphere --debug <filename> and the other for the debugger.

Anyway, check out the screenshot, it's looking pretty slick so far I think.
Title: Re: minisphere 2.1.6
Post by: Flying Jester on January 24, 2016, 02:41:05 pm
This is especially convenient on Linux, which previously required using two terminals, one to run msphere --debug <filename> and the other for the debugger.


Or you could just run minisphere with a `&` after it, to not make it blocking :P
Title: Re: minisphere 2.1.6
Post by: Fat Cerberus on January 24, 2016, 02:48:36 pm
I did find that out, although in my attempts at that the two programs would fight over the same terminal, unless of course you redirect the engine's stdout elsewhere (which is exactly what SSJ does).  In any case this matches how GDB and similar debuggers work, where you pass the program to be debugged as an argument to the debugger.

Basically, in Windows if you do start whatever, it opens a new terminal (console) for the program, I couldn't find a way to do the same in Linux.
Title: Re: minisphere 2.1.6
Post by: Flying Jester on January 24, 2016, 04:23:39 pm
Traditionally, you would explicitly start another terminal (usually `xterm`, which a lot of distros symlink to be their DE's terminal rather than the real xterm), which works similarly to `start` in Windows. If you pass an argument, that is executed by the terminal, which will exit once that command returns.
Title: Re: minisphere 2.1.6
Post by: FBnil on January 25, 2016, 04:45:08 pm
# You can run 2 things like this:
$ xterm -title "This is a terminal1" -r -selbg blue -e "/script/or/program/run"  &
$ xterm -title "This is a terminal2" -e "vi" &
# The wait statement waits for all the child processes...
$ wait
# now do some cleanup...
echo "cleaning up"...
Title: Re: minisphere 2.1.6
Post by: Fat Cerberus on January 26, 2016, 02:14:24 am
SSJ commands implemented so far (names subject to change as development progresses):

"go" - Resumes execution.
"step" - Step over, same as "next" in GDB
"in" - Step in
"out" - Step out
"trace" - Prints a numbered stack trace, 0 is the function currently executing, counts up from there
"var" - Prints local variables for the current function.  Doesn't yet show values.
"eval" - Runs arbitrary JS code in the current context, can also be used to examine variables ("eval someVar")
"quit" - Detaches the debugger and terminates

No breakpoint support yet, and the Step commands don't show any source code for context, but these all work otherwise, so I'm off to a good start.  Oh, and it also reports uncaught exceptions.
Title: Re: minisphere 2.1.6
Post by: Flying Jester on January 26, 2016, 10:54:45 am
It might be nice to have 'continue' as a synonym for 'go' and 'print' for 'eval', since that would match lldb and gdb.

Can you just use the first letter of the command to perform it? That's a really nice feature of most debuggers.
Title: Re: minisphere 2.1.6
Post by: Fat Cerberus on January 26, 2016, 11:40:34 am
Right now, single letters aren't accepted as valid commands, but I do want to implement that.  It gets tedious typing 'step' (or selecting it from history) over and over again. :)

For the most part I take inspiration from gdb for command naming, but a few of its naming decisions baffle me.  For example in gdb `step` is actually Step In, while Step Over is mapped to `next`.  This is weird to me, since it's been my experience that the vast majority of stepping done is Step Over.  In most cases with well-placed breakpoints you don't need to step into functions unless the code is really tangled. (the reason this matters is that it's quite a bit faster to type 's'+enter than 'n'+enter)

I will most likely rename `trace` to `backtrace`.  Even though the term is odd to me, it matches gdb and lldb naming and is an accepted term for a call stack listing. As for `print`, I was considering that initially, but hesitated: `eval` can execute arbitrary code with any number of side effects.  Someone using a command called `print` may not expect that.  That said, I'll probably do it anyway though for parity with gdb.

What's your opinion of the command line (see screenshot posted earlier)?  gdb's prompt is just "(gdb)", likewise for lldb, whereas I include the source file and line number.  I'm undecided on whether this is legitimately useful or just adds noise.
Title: Re: minisphere 2.1.6
Post by: Flying Jester on January 26, 2016, 10:49:30 pm
I think the debugger having its own prompt name makes more sense when you have control of stdin, since many programs (in Unix at least) provide line-editing like features.

`print` in lldb does perform JITing in expressions via llvm.

In general if it were me, I'd take more inspiration from gdb than lldb. The latter tends to be much more annoying to use, since it's extremely verbose. The reasoning is that it's more orthogonal and descriptive, but in reality it just makes everything more work.

Most of the unusual names in gdb were just to give each command a unique but initial letter synonym. If you always call stack traces 'backtraces', you will always remember they are `bt` or just `b`.
Title: Re: minisphere 2.1.6
Post by: Fat Cerberus on January 27, 2016, 03:18:24 am
I implemented stack walking, yay!  You can now enter `frame <x>` to switch to a different function in the stack.  Future requests to print variables, run code, etc. will then use that scope.

This is actually coming together pretty quickly!  I do still need to implement source code listing and most importantly, breakpoints, and that should put SSJ pretty close to feature parity with the Sphere Studio plugin.  Heck, I might even be able to rewrite that plugin to use SSJ under the hood, to avoid having to maintain two debugger codebases. ;D
Title: Re: minisphere 2.1.6
Post by: FBnil on January 27, 2016, 03:33:01 pm
.. nice...

I managed to finally compile minisphere, but only after using http://download.gna.org/allegro/allegro-unstable/5.1.13/  (but I also removed all allegro libs from my debian, breaking allegro games, then make installed the new version)
I noticed that --game is not an option anymore, and I couldn't see why in the git log's, so I assume it is a bug?

Code: [Select]
fbnil@convoy$ strings msphere.20150610 |grep ^-- |sort >a ; strings msphere|grep ^-- |sort >b;diff a b
0a1
> --debug
3d3
< --game
6c6,7
< --windowed
---
> --version
> --window

fbnil@convoy$ comm a b
        --debug
                --frameskip
                --fullscreen
--game
                --log-level
                --no-throttle
        --version
        --window
--windowed
Title: Re: minisphere 2.1.6
Post by: Fat Cerberus on January 27, 2016, 03:53:25 pm
-game (single hyphen) should still be supported for legacy compatibility, however new-style --game is not, because I switched to the more Unix-y convention of:
msphere [options] <path>

This was changed in version 2.0.  I don't think it will accept an .sgm file on the command line though, due to a bug I haven't gotten around to fixing.  As a workaround for now, just pass the name of the directory containing game.sgm.
Title: Re: minisphere 2.1.6
Post by: Fat Cerberus on January 28, 2016, 01:57:49 am
Here's another screenshot.  It's starting to look very mature now. :)
Title: Re: minisphere 2.1.6
Post by: Eggbertx on January 28, 2016, 01:50:29 pm
This may have already been addressed, but have there been any plans to add mp3 and/or midi support? I have it in Linux, fully updated as of yesterday.
Title: Re: minisphere 2.1.6
Post by: Fat Cerberus on January 28, 2016, 02:19:20 pm
mp3 is impossible without relicensing minisphere as GPL (no thank you), and MIDI... I don't even know where to start with that.  For Windows I can probably just call into winmm, no idea for other platforms.
Title: Re: minisphere 2.1.6
Post by: Eggbertx on January 28, 2016, 06:16:40 pm
Oh, alright. It was more a matter of convenience. I have Audacity, so converting oggs is no problem, and I have timidity installed, so I can just use a soundfont to render a midi file as an ogg.
Title: Re: minisphere 2.1.6
Post by: Radnen on January 28, 2016, 09:06:31 pm
I think .ogg is better than .mp3 because it can play at lower bitrates with nearly the same quality, thus reducing filesize (especially useful for certain songs in midi or other soundfont formats).
Title: Re: minisphere 2.1.6
Post by: Fat Cerberus on January 28, 2016, 09:14:15 pm
That's definitely true in my experience - .ogg still sounds decent even down to 48kbps in stereo (the lowest bitrate the encoder will give you in "constant quality" mode) - try that with an mp3 and it'll be so full of compression noise as to be unlistenable.
Title: Re: minisphere 2.1.6
Post by: Fat Cerberus on January 30, 2016, 03:03:43 am
SSJ works on Linux too!
Title: Re: minisphere 2.1.6
Post by: Fat Cerberus on February 01, 2016, 02:18:44 am
I just switched minisphere's UNIX build system from SCons to make.  Not autotools, I don't have time for that. :P  It's a hand-made makefile.  The makefile allows minisphere and GDK tools to be installed in /usr/bin as well:
Code: [Select]
make && sudo make install


Also, "make dist" will make a tarball.

From there it's a simple matter to run games from the command line:
Code: [Select]
sphere game.spk
sphere game.sgm


Or to debug them (note SSJ doesn't yet show source):
Code: [Select]
ssj game.sgm
ssj --pause game.sgm
(the debugger works with SPKs too!)
Title: Re: minisphere 2.1.6
Post by: Flying Jester on February 01, 2016, 11:34:01 am

I just switched minisphere's UNIX build system from SCons to make.  Not autotools, I don't have time for that. :P


The days when Autotools made sense are mostly gone. Supporting Unix no longer means supporting Linux, Irix, Solaris, HP-UA, AIX, etc., and ignoring the hoopla, most Linux distros are very similar. The only thing you really need to do is support prefixes.

The other main use of autotools was to smooth over different libc's, but again, those days are gone. Every system either uses glibc, bsd libc (which is very similar in API to glibc), or something that tries its best to look like glibc (like musl).
Title: Re: minisphere 2.1.6
Post by: Eggbertx on February 01, 2016, 04:31:00 pm
So since Oracle either stopped or will stop working on the applet system (though thanks to Oracle's crap security, it was pretty much dead in the water a while ago) JavaSphere is a no go there, and since doing JavaSphere from scratch would be effectively reinventing the wheel, do you think it would be at all possible to port miniSphere to Android? Looking around, it doesn't look like it should be too difficult to compile Allegro stuff for Android. I'm not familiar with Allegro (I've mostly just used SDL in the past), but I'll see what I can do. Keyboard stuff might be a bit tricky, if impossible, but mouse stuff could possibly be converted to swiping and touching. So while there might be a lot of Sphere games that either won't work at all, or will have to be heavily modified for Android, I still think it could be pretty cool.
Title: Re: minisphere 2.1.6
Post by: Fat Cerberus on February 01, 2016, 04:40:44 pm
Allegro has a lot of stuff built in that I would likely have to implement myself or go looking for third-party add-on libraries to do in SDL, and it's ridiculously simple to compile static (the official Windows releases are statically linked to Allegro).  Also, SDL as far as I know is LGPL, making static linking more of an iffy proposition due to minisphere's BSD license.  Allegro is zlib licensed.  Oh, and I like the Allegro API, very C-like. :)

Allegro can be compiled on Android, and actually I wanted to do an Android build of the engine at some point in the future, but getting the build environment set up seemed like a daunting task, so I keep putting it on the back burner.  Feel free to try it yourself and let me know the results!
Title: Re: minisphere 2.1.6
Post by: Eggbertx on February 01, 2016, 07:25:56 pm
If that's the case, it might be easier to just use SDL or something. I'll look into working with one of the other cross-platform engines, or just making my own and using some code from them as reference. But I'm already working on a non-Sphere related project, so that may or may not happen. (shameless (http://github.com/eggbertx/gochan) plug (http://gochan.org))
Heck, since it's developed by Google anyway, can is compatible with Linux, OS X, Windows, Android, and iOS and it can link other non-Go libraries like SDL and GTK, I wonder how feasable a Sphere engine written in Go (http://golang.org) would be...
Title: Re: minisphere 2.1.6
Post by: Fat Cerberus on February 01, 2016, 07:30:58 pm
Do keep in mind that when I said it seemed daunting, I was developing exclusively on Windows at the time--a platform which is not really well-suited to cross-platform development. :P  Now that i have access to Linux, I might try it again at some point in the future.
Title: Re: minisphere 2.1.6
Post by: Eggbertx on February 01, 2016, 10:19:00 pm
That's fine. I haven't used it a whole lot since building it a few days ago in Linux, but it seems to run pretty well. This was more of a random idea, since Radnen suggested I look into porting JavaSphere to Android.
Title: Re: minisphere 2.1.6
Post by: Fat Cerberus on February 03, 2016, 02:47:40 pm
minisphere has a man page now!
Title: Re: minisphere 2.1.6
Post by: Flying Jester on February 04, 2016, 03:51:41 pm

Allegro has a lot of stuff built in that I would likely have to implement myself or go looking for third-party add-on libraries to do in SDL, and it's ridiculously simple to compile static (the official Windows releases are statically linked to Allegro).  Also, SDL as far as I know is LGPL, making static linking more of an iffy proposition due to minisphere's BSD license.  Allegro is zlib licensed.  Oh, and I like the Allegro API, very C-like. :)


SDL2 is zlib licensed.

SDL2 is also extremely similar to SDL1 in an API sense (to the point that a few very common functions now have dummy arguments to match the API of their SDL1 counterparts). I personally prefer SDL2's API, and if you were going to call it from Java I think it would be a much better choice since its API is very well suited to being used from an object-oriented environment. SDL2 also has full support for Android, and has a variety of features to either query the actual touch system or to just emulate a keyboard and mouse with it.

If cross-platfom is a goal, SDL1 and even SDL2 utterly annihilate Allegro, though :P
Title: Re: minisphere 2.1.6
Post by: Fat Cerberus on February 04, 2016, 04:07:09 pm
Not sure about Allegro 4, but v5 supports Android back to API level 12, iOS, and of course the big three (Windows, OSX, Linux).  Possibly BSD as well, not sure about that though.  Allegro 4 is very much a legacy platform (being designed originally for MS-DOS games and ported elsewhere over the years), v5 was rewritten from the ground up but it gets a bad rap because people assume it's just an incremental evolution of the classic Allegro.

SDL probably does support more platforms, but for something like Sphere, the 5 listed above should cover the majority of users.  Honestly though most of why minisphere is still using Allegro is inertia - it was the first thing I tried after SFML, and had everything I needed--and still does--and now that I have the whole Sphere API built on top of it (note: the Allegro 5 API is VERY similar in structure to Sphere 1.x) it would be a massive undertaking to port it to a new backend.

Speaking of porting, I backported minisphere to be able to compile against Allegro 5.0, which is what's pulled by default via apt-get and homebrew since 5.1 is "unstable".  This should make it easier for people to compile the engine now. :)
Title: Re: minisphere 2.1.6
Post by: Eggbertx on February 04, 2016, 04:33:21 pm

minisphere has a man page now!

Nice! So is this something that will be installed by make install?


Allegro 4 is very much a legacy platform (being designed originally for MS-DOS games and ported elsewhere over the years),

Wow, I knew Allegro was around during the DOS days, but I didn't know that Allegro 4 was that old.
Title: Re: minisphere 2.1.6
Post by: Fat Cerberus on February 04, 2016, 04:37:22 pm


minisphere has a man page now!

Nice! So is this something that will be installed by make install?


Yes.  There are also man pages for Cell and SSJ, but they are currently incomplete.
Title: Re: minisphere 2.1.6
Post by: Flying Jester on February 04, 2016, 06:14:28 pm
Allegro 5 sort of supports FreeBSD (no sound), and doesn't support OpenBSD at all. They say they do, but the OpenBSD people say they don't (and Allegro doesn't compile in OpenBSD 5.7+, I know from experience). Either way, they don't support the OpenBSD audio system for sure.

The other targets that are important to me are Solaris (particularly on UltraSparc) and Haiku. SDL2 supports both, although their raw Surface video backend is pretty bugged on Haiku (the Render backend and OpenGL support has no issues, though). It also has audio on BSDs. But I don't use SDL2 for audio anyway, I usually use OpenAL or OpenBSD's native sndio when on OpenBSD or Linux (which is easily the best audio backend I've found so far).

You're right, though, these are pretty obscure targets. Allegro could probably be made to support FreeBSD with PulseAudio enabled, but the BSD people hate the PulseAudio people and the PulseAudio people hate the BSD people, so I don't suspect that's a good long term plan.
Title: Re: minisphere 2.1.6
Post by: Fat Cerberus on February 06, 2016, 03:34:03 am
So I finally got Travis to actually use clang to build minisphere (turns out SCons doesn't honor the pre-existing environment, it was simple now that I have a makefile), and said compiler now seems to hate me, mostly because I like to do this:

Code: (c) [Select]

if (thing = create_foobar(...)) {
    ...
}


It's just so succinct and elegant that I got into the habit of doing it everywhere.  I can easily shut up the warnings of course, by adding another set of parentheses, but that triggers my OCD and makes the statement look uglier. :-\

I should try adding -Wall -pedantic to that command line and see if I can get clang even angrier at me. :P

Anyway, I think I'm getting close to releasing the first 3.0 beta, but I have to get SSJ to be able to locate source code properly first, and also implement breakpoints.  It's kind of useless without those. ;)
Title: Re: minisphere 2.1.6
Post by: Fat Cerberus on February 07, 2016, 01:50:18 am
I think minisphere on Windows XP is a lost cause.  I set up Windows XP x64 edition in a VirtualBox VM yesterday and tried to get minisphere going on it, but failed miserably.  I think it might just be that the MSVC 2015 C runtime doesn't like XP - everything was fine until something tried to access the file system.  Cell will report that there's no cellscript in the current directory, minisphere errors out if a game is passed on the command line, the "select a game" dialog doesn't show up at all, etc.

So yeah, I'm just going to cross XP off the list of supported platforms.  Anyone know if minisphere runs on Vista or should I just say the minimum requirement is Win7 and call it a day?

In any case, I decided not to drop the 32-bit builds after all.  There are still quite a few 32-bit Windows installs in the wild, particularly netbooks tend to be preinstalled with a 32-bit OS to counterbalance the low RAM.  Since both the 32- and 64-bit binaries are built from the same source, it's not a big deal to maintain two sets of binaries.  Speaking of which, starting with minisphere 3.0 the entire toolchain will be built for 64-bit.  In minisphere 2.x, Cell was 32-bit even in a 64-bit minisphere installation.
Title: Re: minisphere 2.1.6
Post by: Flying Jester on February 07, 2016, 02:27:45 pm
XP is more than 15 years old. If someone is disappointed with Minisphere not supporting it, I would be more disappointed they are still using XP.
Literally even Wine is better supported, more compatible, more stable, and more secure at this point.


So I finally got Travis to actually use clang to build minisphere (turns out SCons doesn't honor the pre-existing environment, it was simple now that I have a makefile)

It's easy once you know how, but I agree that SCons should really accept hints from $CC, $CXX, etc. When I started fiddling with Emscripten I had to learn how to accept environment settings, but it really should be the default to do so.


Code: (c) [Select]

if (thing = create_foobar(...)) {
    ...
}


It's just so succinct and elegant that I got into the habit of doing it everywhere.  I can easily shut up the warnings of course, by adding another set of parentheses, but that triggers my OCD and makes the statement look uglier. :-\


I sort of understand why they do this. It's because using both equality and assignment has screwy precedence order...
Code: [Select]

int x = 1;
if(x=0 == 1)
    causeNuclearWar();
else
    puppiesForEveryone();
// I hope that turned out OK!


It also is intended to show you that in such cases variable decaration will not be hoisted to the next block. But I wish they would just leave these warnings on conditionals with both assignment and equality.
Title: Re: minisphere 2.1.6
Post by: Fat Cerberus on February 09, 2016, 12:04:43 pm
Hey, could someone with a 64-bit installation of Debian or Ubuntu test out this .deb package for me?
https://drive.google.com/open?id=0BxPKLRqQOUSNVmR3SFU0QXB6ZUE

I'll be providing .deb's and tarballs for minisphere 3.0, so I figured I'd make sure everything is in order now. :)
Title: Re: minisphere 2.1.6
Post by: DaVince on February 09, 2016, 08:30:45 pm
I suppose the Allegro 5.1 PPA is mandatory for this one, since it gave me "Dependency not satisfiable: liballegro-acodec5.1" in Ubuntu's package manager.

Installed fine after adding that. The minisphere desktop entry also appeared in my Xfce menu. It opened the standard "open file" dialog; can't help but feel that showing the launcher game with sample games would be better though. (Maybe with a simple game that explains/demonstrates what this whole thing is? That could be a future step, I suppose... :P )
Title: Re: minisphere 2.1.6
Post by: Fat Cerberus on February 09, 2016, 08:42:10 pm
It's actually supposed to show the startup game, guess that's a packaging bug.  Thanks for testing!

As for Allegro 5.1, minisphere will actually compile against Allegro 5.0 now, at the cost of disabling some features--the ones I know are shaders, error copy-to-clipboard, and vertex buffers (improves Galileo performance).  But apparently debuild just sees that Allegro 5.1 is installed and declares that as the dependency.  I'll see if I can fix that before release.

By the way if you drop to command line, can you successfully execute cell and ssj?  Also check if you have man pages for minisphere, spherun, cell and ssj.
Title: Re: minisphere 2.1.6
Post by: DaVince on February 09, 2016, 08:46:35 pm
All of the commands and manpages seem to be present.

I also noticed that my dev copy of Sir Boingers likes to lock up and crash minisphere when navigating over the High Scores option. And also when in the pause menu for half a second or so. Not sure what's up with that; haven't tested if it only happens with the precompiled version or also when I compile it myself. In any case, I can't even navigate down enough to enable the sound and music...

Edit: this error when running from the command line:
Code: [Select]
fish: "minisphere ." terminated by signal SIGSEGV (Address boundary error)


Also, when trying to run the game with ssj, I get:
Code: [Select]
$ ssj .
SSJ 3.0a0 Sphere game debugger x64
A powerful JavaScript debugger for minisphere
(c) 2016 Fat Cerberus

Starting '/home/vincent/Dropbox/projects/sphere/boingers2.2/games/SirBoingers/'... OK.
Connecting to 127.0.0.1:1208... OK.
Handshaking... OK.
  Attached to minisphere 3.0a0
  Duktape v1.4.0
uncaught `TypeError: cannot read property 'origin' of undefined` at input:1
Unrecoverable error, target detached

^C⏎
Title: Re: minisphere 2.1.6
Post by: Fat Cerberus on February 09, 2016, 08:49:41 pm
Alright, I'll look into that.  It's possible there's a regression in the latest builds.  Could you PM me a copy of the game?
Title: Re: minisphere 2.1.6
Post by: DaVince on February 09, 2016, 08:51:13 pm
Sure. I also edited my above post with the error messages.
Title: Re: minisphere 2.1.6
Post by: Fat Cerberus on February 09, 2016, 08:54:15 pm
That second one is a bug in SSJ, it's trying to load the source map which isn't present unless you compile with Cell using the -d switch.  It's supposed to gracefully degrade, but apparently something fouled up there. ;)
Title: Re: minisphere 2.1.6
Post by: Fat Cerberus on February 11, 2016, 03:04:02 am
So I came up with a way to make Cell more useful.

In minisphere 2.1, compiling with cell -d will generate a debug map which maps the name of a script in the compiled package to its location in the source tree.  This aids the debugger (Sphere Studio for 2.1, SSJ for 3.0) in locating the original scripts, even if the Cellscript relocates them.

For Cell 3.0 I'm going to add a new option, --ssj2, which augments the debug info with the full original source code for all scripts.  Not only does this allow easy debugging of SPK packages even if the original source tree changes (or is moved), but it will also let you release betas compiled with --ssj2 that others can run through the debugger when errors occur to get meaningful info. :D
Title: Re: minisphere 2.1.6
Post by: Fat Cerberus on February 11, 2016, 02:36:02 pm
SSJ is starting to shape up.  I just implemented listing source code:
Code: [Select]

fatcerberus@pigcult-vm:~/src/spectacles-i$ ssj -p specs.spk
SSJ 2.99.812.1 Sphere debugger (x64)
A powerful JavaScript debugger for minisphere
(c) 2016 Fat Cerberus

spherun /home/fatcerberus/src/spectacles-i/specs.spk... OK.
connecting to 127.0.0.1:1208... OK.
verifying... OK.
: attached minisphere 2.99.812.1
: duktape v1.4.0
locating sources... OK.
: source tree /home/fatcerberus/src/spectacles-i/

>>   0: eval() at scripts/main.js:6
6: const DBG_DISABLE_TEXTBOXES = false;

eval() ssj$ l
      1 /***
      2  * Specs Engine v6: Spectacles Saga Game Engine
      3   *           Copyright (c) 2015 Power-Command
      4 ***/
      5
>>    6 const DBG_DISABLE_TEXTBOXES = false;
      7 const DBG_DISABLE_TRANSITIONS = false;
      8
      9 RequireSystemScript('mini/miniRT.js');
     10 RequireSystemScript('analogue.js');

eval() ssj$ so
>>   0: game() at scripts/main.js:30
30: mini.initialize();

game() ssj$ l
     25
     26 // game() function
     27 // This is called by Sphere when the game is launched.
     28 function game()
     29 {
>>   30 mini.initialize();
     31 analogue.init();
     32
     33 mini.Console.register('specs', global, {
     34 'exit': function() { Exit(); }

game() ssj$ q
SSJ session has been detached.
Title: Re: minisphere 3.0b1 (stable: 2.1.6)
Post by: Fat Cerberus on February 12, 2016, 02:46:54 am
After almost 2 months of development, the first beta of minisphere 3.0 is available.  Make sure to test drive SSJ and let me know of any issues.  It still needs polishing, but should be functional enough to use for actual debugging. :P

I recommend uninstalling previous versions of minisphere before trying the beta as the engine executables were renamed, so the old files may cause conflicts/confusion.  Note also that Sphere Studio is no longer included in the download--that will have to be installed separately now for anyone that wants it.  The GDK plugin is included, though, and will be picked up by Sphere Studio 1.2.

If you choose to add minisphere to the PATH, the command to run a game on the command-line is:
spherun <gamepath>

If you omit the path, it will list available command-line options.

edit: By the way, minisphere is available on Ubuntu 14.04 now, through PPA:
Code: [Select]

sudo add-apt-repository ppa:fatcerberus/minisphere
sudo apt-get update
sudo apt-get install minisphere


This probably won't work on later versions of Ubuntu, e.g. 15.10 due to Ubuntu's braindead PPA packaging system (you can't upload multiple packages with the same version number, even if they are built for a different Ubuntu version).  So I'll be posting .deb packages sometime in the near future.

edit 2: Alright, the .deb packages are now available for direct download for those who can't get it through APT.
Title: Re: minisphere 3.0b1 (stable: 2.1.6)
Post by: DaVince on February 12, 2016, 12:30:41 pm
Quote
This probably won't work on later versions of Ubuntu, e.g. 15.10 due to Ubuntu's braindead PPA packaging system (you can't upload multiple packages with the same version number, even if they are built for a different Ubuntu version)

I suppose this is why they keep appending -1, -2, etc. to the end of the version number... You might want to do that for the 15.10 repo, since that's probably the other Ubuntu version a lot of people (including me :P ) will be running.

Will just get the deb file now.
Title: Re: minisphere 3.0b1 (stable: 2.1.6)
Post by: Fat Cerberus on February 13, 2016, 12:25:35 am
Heads up, DaVince: I just realized why I originally made the switch to Allegro 5.1.  There are some pretty nasty bugs in 5.0, as I was just reminded by my cousin beta testing it.  Notably, sometimes playing sounds will completely lock up the engine, from which the only way out is to kill the process.  It's a hard deadlock due to a race condition in Allegro's streaming audio code, nothing minisphere can do to work around it. :(

If worse comes to worst I'll have to statically link Allegro for the final Linux release.  This will likely disqualify it from official Debian/Ubuntu packaging, but it'd just be a stopgap measure until a new stable Allegro release comes out.

I hope they release Allegro 5.2 soon... I'm not really up for trying to port the whole thing to SDL right now. :P  Although it might be an interesting experiment to do in my spare time, I'd like to try to get 3.0 out the door first. :P
Title: Re: minisphere 3.0b1 (stable: 2.1.6)
Post by: DaVince on February 13, 2016, 01:08:38 pm
Yeah, I remember those bugs too. Thing is, the engine hasn't crashed where it would before, so I figured things have gotten at least a *little* better with Allegro 5.0 somehow. Still, I can imagine the earliest minisphere would be able to be included in any official repo is Ubuntu 16.04 or so. On Ubuntu and related distros, anyway.
Title: Re: minisphere 3.0b1 (stable: 2.1.6)
Post by: Fat Cerberus on February 15, 2016, 11:22:47 pm
New SSJ feature coming in minisphere 3.0b2: the Examine command.  It's like Eval, but more verbose and shows Duktape runtime data, which can help in identifying objects:

Normal Eval:
Code: [Select]

scripts/main.js ssj$ e Image.prototype
= {
   prop "toString" = {...}
   prop "height" = { get }
   prop "width" = { get }
   prop "blit" = {...}
   prop "blitMask" = {...}
   prop "createSurface" = {...}
   prop "rotateBlit" = {...}
   prop "rotateBlitMask" = {...}
   prop "transformBlit" = {...}
   prop "transformBlitMask" = {...}
   prop "zoomBlit" = {...}
   prop "zoomBlitMask" = {...}
}


Examine:
Code: [Select]

scripts/main.js ssj$ x Image.prototype
= {
   meta "heapptr" = { heap:"0000019a70a80620h" }
   meta "heaphdr_flags" = 1342177408
   meta "heaphdr_type" = 2
   meta "refcount" = 2
   meta "reachable" = 0
   meta "temproot" = 0
   meta "finalizable" = 0
   meta "finalized" = 0
   meta "readonly" = 0
   meta "extensible" = 1
   meta "constructable" = 0
   meta "bound" = 0
   meta "compiledfunction" = 0
   meta "nativefunction" = 0
   meta "bufferobject" = 0
   meta "thread" = 0
   meta "array_part" = 0
   meta "strict" = 0
   meta "notail" = 0
   meta "newenv" = 0
   meta "namebinding" = 0
   meta "createargs" = 0
   meta "envrecclosed" = 0
   meta "exotic_array" = 0
   meta "exotic_stringobj" = 0
   meta "exotic_arguments" = 0
   meta "exotic_dukfunc" = 0
   meta "exotic_proxyobj" = 0
   meta "class_number" = 10
   meta "class_name" = "Object"
   meta "internal_prototype" = { obj:"0000019a6e86eba0h" }
   meta "props" = { ptr:"0000019a6e911750h" }
   meta "e_size" = 14
   meta "e_next" = 14
   meta "a_size" = 0
   meta "h_size" = 0
   prop "toString" = { obj:"0000019a70a67e30h" }
   prop "height" = { get: { obj:"0000019a70a68070h" }, set: null }
   prop "width" = { get: { obj:"0000019a70a67a70h" }, set: null }
   prop "blit" = { obj:"0000019a70a68430h" }
   prop "blitMask" = { obj:"0000019a70a68010h" }
   prop "createSurface" = { obj:"0000019a70a68af0h" }
   prop "rotateBlit" = { obj:"0000019a70a681f0h" }
   prop "rotateBlitMask" = { obj:"0000019a70a67ad0h" }
   prop "transformBlit" = { obj:"0000019a70a68610h" }
   prop "transformBlitMask" = { obj:"0000019a70a67e90h" }
   prop "zoomBlit" = { obj:"0000019a70a68850h" }
   prop "zoomBlitMask" = { obj:"0000019a70a67c50h" }
}
Title: Re: minisphere 3.0b2 (stable: 2.1.6)
Post by: Fat Cerberus on February 22, 2016, 02:03:27 pm
minisphere 3.0b2 for Windows is up, with a vastly improved SSJ debugger. :D  I recommend testing it out on real Sphere games - by my guess, minisphere 3.0 Final is getting pretty close so testing would be much appreciated.

I'll post the tarball and deb downloads later.
Title: Re: minisphere 3.0b2 (stable: 2.1.6)
Post by: Fat Cerberus on February 22, 2016, 02:52:54 pm
@DaVince The 64-bit deb package is up.  Could you do some quick testing?  SSJ has a full manpage now if you need a primer. ;)
Title: Re: minisphere 3.0b2 (stable: 2.1.6)
Post by: DaVince on February 23, 2016, 12:26:18 am
Both seems to be working great, for as far as I've tested them! (Only tested SSJ as far as Print/DebugPrint and backtracing a game that crashes on it (an old special Kefka's Revenge winter demo I have yet to upload anywhere).)

The crash happened in "undefined:0", but at least the backtrace ensured it was clear it was in the map engine and exactly what line in the scripts started that map engine with which map. That is really useful. Thanks a ton for making this! :)

Edit: should say, though, if this could somehow report which line/script in the map file is doing that, that would be cool, because... the map it errored out on has like fifty entities.
Title: Re: minisphere 3.0b2 (stable: 2.1.6)
Post by: Fat Cerberus on February 23, 2016, 12:43:03 am
If the error is in an embedded map script, it should be reporting the filename as something like Test.rmp:onEnter or Test.rmp:Entity1:Talk.  You mean it's not doing that?

Note that it doesn't (currently) show source code for embedded map scripts, although that may be possible to do.
Title: Re: minisphere 3.0b2 (stable: 2.1.6)
Post by: Fat Cerberus on February 23, 2016, 01:06:25 am

The crash happened in "undefined:0", but at least the backtrace ensured it was clear it was in the map engine and exactly what line in the scripts started that map engine with which map. That is really useful. Thanks a ton for making this! :)

Edit: should say, though, if this could somehow report which line/script in the map file is doing that, that would be cool, because... the map it errored out on has like fifty entities.


I just realized, if it says "undefined:0" that means the error was thrown by a Sphere API (e.g. Abort()), not directly by the script.  That's something I need to fix before the final release: It should automatically select the next stack frame up if the error occurs in an API function (the API is throwing it on behalf of the game anyway).  For now if it drops you into "undefined:0" just enter the command "up" to switch to the function that actually caused the error.

And hey, no problem - A symbolic debugger is something I always wished Sphere had and the lack of one always held it back as serious game development tool for me.  Finally having it at my disposal is awesome--even more awesome because I wrote it. ;D
Title: Re: minisphere 3.0b2 (stable: 2.1.6)
Post by: DaVince on February 23, 2016, 01:29:43 am

I just realized, if it says "undefined:0" that means the error was thrown by a Sphere API (e.g. Abort()), not directly by the script.  That's something I need to fix before the final release: It should automatically select the next stack frame up if the error occurs in an API function (the API is throwing it on behalf of the game anyway).  For now if it drops you into "undefined:0" just enter the command "up" to switch to the function that actually caused the error.

Oh! You're right! I didn't see it at all, but it *does* say this:

Code: [Select]
FATAL UNCAUGHT - TypeError: number required, found '0' (stack index 1)
   at: [nutcracker1 : queued script]:1
=> # 0: SetPersonFrame() at undefined:0
'undefined': source file could not be located.


I guess what threw me off is that it's not giving the map file name, so I wasn't looking properly for the "nutcracker : queued script" bit.
Title: Re: minisphere 3.0b2 (stable: 2.1.6)
Post by: Fat Cerberus on February 23, 2016, 01:37:04 am
Dammit, I think I'm going to have to bite the bullet in minisphere 3.0 and allow API functions to accept 0/1 in place of true/false.  Quite a few Sphere games seem to do that but minisphere doesn't like it because it's not actually a JS boolean value.  I suspect that's the cause of your error.

The reason it doesn't show the map file name is because at the time the script is queued (using QueuePersonScript) only the person name is known.  I could probably fix that by tracking which map transient persons are created for.
Title: Re: minisphere 3.0b2 (stable: 2.1.6)
Post by: Fat Cerberus on February 23, 2016, 09:45:00 am
Hm, on second look it actually looks like error is that the game passed a string for the second argument to SetPersonFrame() which expects a number in that slot.  Since this is based on Kekfa's Revenge code I shouldn't really be surprised. :P
Title: Re: minisphere 3.0b2 (stable: 2.1.6)
Post by: Fat Cerberus on February 23, 2016, 02:19:54 pm
Next (pre)release of minisphere I want to add the ability to send source to the debugger directly from the running game so that:



My goal is to have minisphere 3.0 go gold on the first anniversary of the minisphere 1.0 release, March 28.  So that gives me about a month.  Looks like 2016 will be the year of the Sphere debugger! :)
Title: Re: minisphere 3.0b2 (stable: 2.1.6)
Post by: Fat Cerberus on February 25, 2016, 01:14:44 am
@DaVince
I implemented source download in SSJ (after solving a nasty segfault mentioned in the Programming board that ruined my night...), and using it, proceeded to track down the cause of your KR crashes:

Code: [Select]

C:\Users\fatce\Documents\Sphere Studio\Projects>ssj kr
SSJ 3.0a3 minisphere Console Debugger (x64)
a powerful JavaScript debugger for minisphere
(c) 2016 Fat Cerberus

starting C:/Users/fatce/Documents/Sphere Studio/Projects/kr/... OK.
connecting to 127.0.0.1:1208... OK.
verifying... OK.
querying target... OK.
    game title: Kefka's Revenge
    author: KRTeam

=> # 0: eval() at scripts/game.js:12
12: GetSystemFont().drawText(15,10,"LOADING...");

scripts/game.js:12 eval()
(ssj) c
FATAL UNCAUGHT - TypeError: number required, found '83' (stack index 1)
    at: maps/Aresidence1.rmp/onEnter:2
=> # 1: global() at maps/Aresidence1.rmp/onEnter:2
2: SetPersonX('daughterslaughter', '83');

maps/Aresidence1.rmp/onEnter:2 global()
(ssj) l
      1: dispTown = "Family home";
=>    2: SetPersonX('daughterslaughter', '83');
      3: SetPersonX('workdude', '277');
      4: SetPersonY('workdude', '212');
      5: SetPersonDirection('workdude', 'west');
      6: IgnorePersonObstructions('kid', true);


Unfortunately KR does things like this a lot, which is what makes it so hard to support.  But now you can see source for map scripts directly in the debugger, which is awesome!
Title: Re: minisphere 3.0b2 (stable: 2.1.6)
Post by: DaVince on February 25, 2016, 01:35:38 pm
Wow, thanks! I really don't think you needed to 'fix' this, since it would kinda promote bad coding practice, but... hey, you did it! :P
Title: Re: minisphere 3.0b2 (stable: 2.1.6)
Post by: Fat Cerberus on February 25, 2016, 01:39:04 pm
I didn't fix the KR bug if that's what you mean - I mostly just wanted to track down the cause since I wasn't able to do this even with the Sphere Studio debugger.  Since the classic map engine is still supported in minisphere, it was kind of dumb that you couldn't see map code in the debugger.  Now you can!
Title: Re: minisphere 3.0b2 (stable: 2.1.6)
Post by: Fat Cerberus on February 25, 2016, 02:13:03 pm
It even works for scripts set up at runtime (e.g. update scripts), for example here it shows the GenCommands stub installed by analogue.js:

Code: [Select]

src/main.js:53 game()
(ssj) w
   # 0: global() at maps/Testville.rmp/maggie/genCommands:1
1: analogue.runPersonEvent(GetCurrentMap(), 'maggie', 'generator');
Title: Re: minisphere 3.0b2 (stable: 2.1.6)
Post by: DaVince on February 25, 2016, 03:33:26 pm

I didn't fix the KR bug if that's what you mean - I mostly just wanted to track down the cause since I wasn't able to do this even with the Sphere Studio debugger.  Since the classic map engine is still supported in minisphere, it was kind of dumb that you couldn't see map code in the debugger.  Now you can!

Ah, okay! That makes a LOT more sense. In any case, this just makes it more powerful!
Title: Re: minisphere 3.0b2 (stable: 2.1.6)
Post by: Fat Cerberus on February 25, 2016, 05:11:49 pm
Another useful feature I added is that if execution stops in a system call, SSJ will automatically select the next stack frame up that actually contains JS code.  This avoids the need to do "up" first.
Title: Re: minisphere 3.0b3 (stable: 2.1.6)
Post by: Fat Cerberus on February 29, 2016, 02:50:10 am
Just posted another beta, minisphere 3.0b3.  SSJ has a brand-new feature: It pulls source code for the game being debugged directly from minisphere.  This means you can debug games, even those packaged as SPKs, without having access to the original source tree: So long as the scripts weren't minified or otherwise mangled before being compressed, you can now debug any Sphere game past, present and future.

I also enhanced the output of SSJ's "examine" command to make it more useful this release: It now shows property attributes for all properties and produces a nice listing like Unix ls -l:

Code: [Select]

scripts/main.js:30 game()
ssj: x GetGameManifest()
ewc- name                "Spectacles: Bruce's Story"
ewc- author              "Fat Cerberus"
ewc- summary             "Follow Scott Starcross in his quest to stop the Primus."
ewc- resolution          "320x240"
ewc- script              "scripts/main.js"
ewc- minimumPlatform     {obj:"00000187b9161c10h"}
ewc- frameRate           60
ewc- sceneRenderPriority 99
ewc- logPath             "~usr/Spectacles Saga/Console Log.txt"
ewc- consoleBuffer       1000
ewc- consoleLines        10
ewc- disableAnimation    false
ewc- disableBattles      false
ewc- disableSplash       true
ewc- disableTitleScreen  true
ewc- directory           "C:/src/spectacles-i/dist/"


That's "ewc" for "Enumerable, Writable, Configurable".  The last slot which is clear here is "a" for Accessor (a property with a getter/setter).  All properties are listed, even non-enumerable ones.  This is in contrast to eval which only lists enumerable properties.  If you do examine global be prepared for an absolutely massive listing!
Title: Re: minisphere 3.0b3 (stable: 2.1.6)
Post by: Fat Cerberus on March 03, 2016, 01:14:51 am
@DaVince: Have you tried the new beta yet?  SSJ is much more useful now. :) (there might be a few crashes which I've since fixed in the git repo)
Title: Re: minisphere 3.0b3 (stable: 2.1.6)
Post by: DaVince on March 03, 2016, 02:52:53 pm
Not yet, I haven't really had much time to dedicate to game dev lately! Also not sure where/how I would use all this shiny new stuff, will definitely have to read the manpages and try things out.

To be honest I'm not used to debuggers in general, so it's going to take a bit for me to get used to it all. :)
Title: Re: minisphere 3.0b3 (stable: 2.1.6)
Post by: Fat Cerberus on March 03, 2016, 02:59:57 pm
Cell is most likely going to get an overhaul before the official release (March 28), the codebase is not very modular making any changes difficult, and writing a Cellscript isn't particularly intuitive even with the manpage.

SSJ probably won't change any further, I'm very satisfied with how it turned out. :D

minisphere itself hasn't gotten many changes at all, the 2.1 codebase was already quite mature.  The only major change I made was to support source code download by the debugger.  Other than that it's just minor bug fixes.
Title: Re: minisphere 3.0b3 (stable: 2.1.6)
Post by: Fat Cerberus on March 04, 2016, 03:08:07 am
Hm, on second thought I think I'll hold off on that Cell overhaul until v3.1.  Development time would be better spent improving the Sphere Studio debugger UI, which has kind of fallen behind compared to SSJ's feature set, particularly w.r.t. variable and object inspection.
Title: Re: minisphere 3.0b4 (stable: 2.1.6)
Post by: Fat Cerberus on March 04, 2016, 04:56:55 pm
I just posted the fourth and final beta for minisphere 3.0.  This one fixes a few SSJ crashes and has vastly improved object inspection in Sphere Studio.  See screenshot attached.

The rest of the time before release will be spent improving and polishing off the documentation, particularly the Linux manpages which are still a bit incomplete.
Title: Re: minisphere 3.0rc1
Post by: Fat Cerberus on March 06, 2016, 02:14:34 am
As the minisphere 3.0 release is only 3 weeks away, I decided to do a code freeze.  minisphere 3.0rc1 has been posted, and if no showstopping bugs are found, that build will be officially released as minisphere 3.0.0 on March 28.  I took down the links for 2.1.6 to encourage testing the new version.  As with all major minisphere releases, the previous one will remain available in the Spherical download repository.

Sphere Studio is no longer bundled: For Windows users, it is highly recommended to download Sphere Studio 1.2.1 as a companion to minisphere 3.0.

To the Spherical regulars:
I know you guys don't have much free time, but if some testing could be squeezed in on the RC before the 28th it would be much appreciated.  I will keep an eye out for bugs myself in the meantime.
Title: Re: minisphere 3.0rc1
Post by: N E O on March 06, 2016, 10:40:10 pm
I'll try to find time over the weekend to give it a go on Mac.
Title: Re: minisphere 3.0rc1
Post by: Fat Cerberus on March 06, 2016, 10:49:11 pm
Thanks, NEO.  By the way you don't need to build Allegro manually after all: It turns out Allegro 5.1 is available through homebrew, you just have to use the --devel switch:
https://github.com/fatcerberus/minisphere/blob/master/INSTALL.md#mac-os-x
Title: Re: minisphere 3.0rc2
Post by: Fat Cerberus on March 07, 2016, 01:12:56 am
Well, now we're at release candidate #2.  There was a change I had to make to SSJ otherwise it would have driven me bonkers, the help command didn't recognize abbreviated command names.  Now it does!

...yeah, I'm bad at this whole "code freeze" thing. :P
Title: Re: minisphere 3.0rc2
Post by: DaVince on March 07, 2016, 07:13:05 pm
Testing it out! It seems VERY stable; hasn't crashed once, even with the deb build that uses allegro 5.0. It's also fast, so far.
Now just coding random stuff (see attached file :P) and coming across the following:

I used TypeScript for a bit and it seemed to work fine. Classes worked properly and stuff. :)

LoadSound("it file").play(true) didn't work, but I think I remember this being an Allegro 5.0 specific problem, not a 5.1 one. Similarly, I think music keeps looping even if I tell it not to (there are several tunes in my test game and it's supposed to pick a random new one after finishing one song, but it always sticks to the same one tune it started out with).

surface.filledCircle(), and probably the other circle functions too, only accept integers. It errors out if I give it any radius that is a floating point value. It also doesn't seem to antialias them even when I pass true to the antialias argument.

Is there any way for the screenshot function to take a screenshot at the game's native size rather than the window size? I personally always thought that Sphere screenshotting at the native size was a strength, because it makes for really easy quick screen capping.

Finally... I still haven't played around with any of the new functions yet, other than trying TypeScript for a little bit. This is because this thread is huge and I don't know where I could find a list of the new functions specifically!
Title: Re: minisphere 3.0rc3
Post by: Fat Cerberus on March 07, 2016, 07:26:03 pm
You'll have to look through the changelog to see what's new.  That should be much more manageable than trying to sift through a nearly 70-page thread! :P  Also check minisphere-api.txt, I make it a point to add all new APIs to that file.  It's missing some Sphere 1.x stuff mostly related to the map engine, but it's comprehensive otherwise.

Thanks for the testing, especially trying out TypeScript, I didn't expect that. :)

No antialiasing on circles is due to Allegro limitations, it's a known issue that I don't have any fix for at present.  Floating point radii causing an error is unexpected though, I'll have to look into that.  As for the screenshots: This is implemented by taking a snapshot of the backbuffer.  For low resolutions, the backbuffer is actually enlarged and all rendering is run through a transformation matrix.  So getting an actual-size screenshots is actually pretty difficult.  At one point I tried to have it scale down the screenshots before saving, but that caused loss of quality, so I decided to leave it as-is.

I'll look into the music issues, I think I touched the Audialis code during 3.0 development at some point and may have fouled something up.
Title: Re: minisphere 3.0rc3
Post by: Fat Cerberus on March 07, 2016, 07:57:06 pm
@DaVince: I did some digging.  IT looping was an Allegro bug:
https://github.com/fatcerberus/minisphere/issues/17

One of the many reasons I made the switch to A5.1 for the Windows builds.  Unfortunately most of the bugs fixed in 5.1 never got backported...
Title: Re: minisphere 3.0rc3
Post by: DaVince on March 07, 2016, 09:18:36 pm
Thanks for the tips. And yeah, I was pretty sure that was a 5.0 bug. I'm obviously testing the 64-bit deb so that basically means I'm stuck with 5.0 until April. :P
Title: Re: minisphere 3.0rc2
Post by: Fat Cerberus on March 07, 2016, 09:46:34 pm
Just noticed this:


LoadSound("it file").play(true) didn't work, but I think I remember this being an Allegro 5.0 specific problem, not a 5.1 one.


This is not a bug, per se, and actually nothing to do with Allegro.  It's probably by sheer accident that it even works in Sphere 1.5.  What happens is: You're loading a sound, calling .play() on it and then immediately losing your reference to the sound object.  The garbage collector then finds it, sees it's unreachable, and finalizes it.  I'm guessing the old SpiderMonkey in Sphere 1.5 had a pretty lazy garbage collector and didn't free objects immediately, so that little trick ends up working.  Duktape primarily uses reference counting, so the second you lose the last reference, the refcount hits zero and the object is freed.

Working around it is possible: I could probably have the engine temporary bump the refcount of the sound while it's playing so that it doesn't get freed unless it stops (or the engine is closed).  That shouldn't be too difficult.  Sounds aren't intrinsically linked to the lifetime of the JS Sound object--they have their own independent refcount and everything.  That was done to allow assets to be passed around internally without causing segfaults galore when their JS objects go out of scope... those were just loads of fun to debug during early engine development. :P
Title: Re: minisphere 3.0rc3
Post by: DaVince on March 07, 2016, 10:07:31 pm
Actually? Don't fix that. In hindsight, what you said about throwing the reference away, it might actually be good for the engine to fail at accomplishing this so people will be forced to do it the 'right' way instead. :)
Title: Re: minisphere 3.0rc3
Post by: Fat Cerberus on March 08, 2016, 01:02:30 am
Huh, weird.  I changed the line below to remove the Math.round():

Code: (javascript) [Select]

this.size = Math.round(4+Math.random()*7);


And it still worked fine on my end, drew the balls and everything.  What kind of error are you seeing when giving a non-integer radius?

By the way, a tip: minisphere has a far better random number generator than Math.random() built right in, based on Mersenne Twister and allowing manual reseeding.  In this case what you'd want is:
Code: [Select]

RNG.range(min, max);

  Returns a random integer uniformly distributed within the range [min,max].


To wit:
Code: (javascript) [Select]

this.size = RNG.range(4, 11);


There's also a drop-in replacement for Math.random, called RNG.random, along with a bunch of others (search for "RNG" in the API doc).  My favorite is RNG.normal - it gives you a random number from a normal distribution with a range of about 6 standard deviations.  I use it in Specs to calculate when bosses change phases.  I was going to use it for damage calculation too, but then I figured the critical hits from that would be brutally unfair and decided against it. :P
Title: Re: minisphere 3.0rc3
Post by: Fat Cerberus on March 08, 2016, 01:22:51 pm

Actually? Don't fix that. In hindsight, what you said about throwing the reference away, it might actually be good for the engine to fail at accomplishing this so people will be forced to do it the 'right' way instead. :)


I fixed it anyway.  While it's probably bad to use that for playing looping music (since you can then never stop it), it's useful to be able to throw away references to sound effects and still have them finish--say you have a function that loads and plays a sound then returns: the sound object goes out of scope but you still want it to play through.  Without the fix you'd have to keep the reference somewhere globally accessible, which adds extra complexity (and prevents it from being GC'd ever).
Title: Re: minisphere 3.0rc3
Post by: DaVince on March 08, 2016, 02:34:09 pm
Quote
What kind of error are you seeing when giving a non-integer radius?

...Okay, I don't understand why, but suddenly it IS accepting the value. I don't know what changed that made it work, but, well, if I encounter the specific error message again I'll let you know right away.

Also, thanks for the RNG tip! That seems a lot better. I'll use it right away. Seems to work great! :)

Speaking of the API doc - where does the deb drop this file, anyway? It doesn't seem to be in /usr/share/doc/minisphere/...
Title: Re: minisphere 3.0rc3
Post by: Fat Cerberus on March 08, 2016, 02:36:50 pm
Hm... I'll have to check the makefile, it might not be installed on Linux.  In the meantime:
https://github.com/fatcerberus/minisphere/blob/master/docs/minisphere-api.txt
Title: Re: minisphere 3.0rc3
Post by: DaVince on March 08, 2016, 02:45:04 pm
Thanks! I'm seeing some things I can replace my old code with already. (Like LoadSound.)
Title: Re: minisphere 3.0rc3
Post by: Chad Zechs on March 08, 2016, 03:22:29 pm
Gentlemen. I performed a fresh install of minisphere 3.0rc3 and Sphere Studio 1.2.1, but I get an error when trying to create a new project when it tries to find a directory that doesn't seem to exist "C:\Program Files\minisphere\assets\template"

(http://i.imgur.com/w0XqinQ.png)

Is this due to something I'm doing wrong? Hope it's not wrong of me to post this on this topic.

Thanks for any assistance you can provide. I'll probably continue to fkc around with settings.

Edit: Forgot a part of my problem, bolded it haha...
Title: Re: minisphere 3.0rc3
Post by: Fat Cerberus on March 08, 2016, 03:34:38 pm
That might be a packaging bug on my part.  If so, my bad.  I'll fix it and post 3.0rc4, but in the meantime you can unzip this file into C:\Program Files\minisphere to hopefully make it work:
https://drive.google.com/open?id=0BxPKLRqQOUSNalNkdml5R1YxdXc

Never feel bad about reporting bugs - I'm always willing to fix them and this is the reason it's a release candidate and not the final release yet. :)
Title: Re: minisphere 3.0rc3
Post by: Fat Cerberus on March 08, 2016, 03:39:07 pm
@DaVince: I also recommend looking into using the S2GM format if you're going to commit to minisphere - Unlike normal game.sgm you can put arbitrary properties into it and access them using GetGameManifest().  Useful for keeping debug settings and such in a central location. 8)
Title: Re: minisphere 3.0rc3
Post by: Chad Zechs on March 08, 2016, 03:57:13 pm

That might be a packaging bug on my part.  If so, my bad.  I'll fix it and post 3.0rc4, but in the meantime you can unzip this file into C:\Program Files\minisphere to hopefully make it work:
https://drive.google.com/open?id=0BxPKLRqQOUSNalNkdml5R1YxdXc

Never feel bad about reporting bugs - I'm always willing to fix them and this is the reason it's a release candidate and not the final release yet. :)

Created project without it yelling at me, so... so far so good :) Thanks Lord English!!

Edit:
Trying to test project to see if it runs (I just left main.js to what it defaults to just to make sure it runs) and I receive the following lovely message in the Build Log:
Code: [Select]
processing Cellscript.js rule 'default'... 
  ERROR: no Cellscript rule named 'default'
================== Failed to build: Platscrol ==================


I look at Cellscript.js and nothing in there is referencing default, so I'm not sure where the disconnect is here :P
Title: Re: minisphere 3.0rc4
Post by: Fat Cerberus on March 08, 2016, 05:37:04 pm
Yeah, that's a bug in the Cellscript template.  I fixed it in 3.0rc4 (which is up).  For the already-created project you can get it to work by changing $sphere to $default at the top of the file.
Title: Re: minisphere 3.0rc3
Post by: DaVince on March 08, 2016, 06:53:02 pm

@DaVince: I also recommend looking into using the S2GM format if you're going to commit to minisphere - Unlike normal game.sgm you can put arbitrary properties into it and access them using GetGameManifest().  Useful for keeping debug settings and such in a central location. 8)

Me using SGM or S2GM is actually just directly related to which editor I use since I just let it do the work. So I'm sure this will change in the future... For now, I'm good. :P
Title: Re: minisphere 3.0rc4
Post by: Fat Cerberus on March 08, 2016, 07:17:16 pm
Ah, I guess you're still using the 1.5 editor.  I'll take another look at getting Sphere Studio to run on Linux once 3.0.0 is officially out the door.  That's really the definitive experience for minisphere development and it sucks that you have to miss out on it!

I uploaded 3.0rc4.  It installs the API docs in /usr/share/doc/minisphere now.  It turns out I never added those to the makefile because I didn't know the proper place to install them, so thanks for the tip on that. :)

I'm also hoping this is the last RC.  Thanks to my OCD I'm up to rc4 already, even Microsoft doesn't put out this many release candidates. (That doesn't excuse you from testing duty mind you! ;) )
Title: Re: minisphere 3.0rc4
Post by: Flying Jester on March 08, 2016, 07:30:10 pm
I'm also still interested in Sphere Studio on Linux/Unix!

I still tinker with Sphere-like engines from time to time, and I use a number of its formats in my other projects. I would be interested in helping debug/test it out, as well!
Title: Re: minisphere 3.0rc4
Post by: DaVince on March 09, 2016, 01:24:18 am
I've been using some new functions and object prototypes (new Font, new Color etc) and their methods and properties and it's all been working great so far.

One thing I did notice that's a thing to fix in a new minor version is that when I made a 1280x720 game it stretched in fullscreen without any regard to the aspect ratio on this 1280x1024 monitor. Result is the screenshot. (By the way, what's with the randomized filename for the screenshot? Game-name-timestamp-01.png would seem a lot more intuitive to me...)
Title: Re: minisphere 3.0rc4
Post by: Fat Cerberus on March 09, 2016, 01:30:50 am
The way minisphere's fullscreen scaling works (remember what I said about enlarged backbuffer and transformation matrices above?), it's actually a bit difficult to do letterboxing without ending up with weird artifacts where stuff gets drawn outside the screen, so I got lazy and just stretched it.  I do want to fix it eventually, but the 3.0 release is already quite big enough and I'm still busy fixing little bugs I find (SSJ's "help" command crashes in 3.0rc4, for instance), so yeah, that might have to wait till v3.1 or something.

As for the randomized screenshots, that was again due to laziness--I didn't feel like formatting a timestamp at the time so I just used RNG.string(), hehe.  I'll fix it before release.
Title: Re: minisphere 3.0rc4
Post by: DaVince on March 09, 2016, 04:48:39 pm
Okay, I can get the aspect ratio thing. That sounds pretty troublesome! (Maybe an easy solution is to force drawing two black rectangles in the appropriate areas? In any case, future feature!)

I've started actually developing a full game now, and it will specifically target and use minisphere functions whenever appropriate. I'm sure I'll be using the debugger too. I probably won't encounter many problems while this RC is happening, but at the very least there'll probably be feedback I can give you at a later stage. :)

Edit: tried creating an s2gm file according to the API documentation, but I'm getting an error when trying to run the game:
Code: [Select]
minisphere was unable to load the game manifest or it was not found.  Check to make sure the directory above exists and contains a valid Sphere game.


My s2gm looks like this, which I'm guessing is probably out of date? It's directly copied and modified from minisphere-api.txt...
Code: [Select]
{
  name: "A Game",
  author: "DaVince & SarahB",
  summary: "Our description goes here",
  resolution: '1280x1024',
  script: 'scripts/main.js',

  minimumPlatform: {
    recommend: "minisphere 3.0 or later",
    apiVersion: 3.0,
    extensions: [
      "sphere-legacy-api", //By the way, do I need these?
      "sphere-obj-constructors",
      "sphere-obj-props",
      "sphere-map-engine",
      "sphere-rng-object",
      "sphere-s2gm",
      "sphere-spherefs",
    ]
  }
}
Title: Re: minisphere 3.0rc4
Post by: Fat Cerberus on March 09, 2016, 05:02:45 pm
You only need the extensions you actually use, the engine will check them on startup to see if they're supported (minisphere-api.txt has the full list).  As for API version, that should be 2.0.  That refers to Sphere 2.0, not the specific engine.  I'll add a note in the documentation clarifying that.

The error message is wrong though (it should be something like unsupported engine), I'll look into that.
Title: Re: minisphere 3.0rc4
Post by: DaVince on March 09, 2016, 05:12:04 pm
I see. Even setting that back to 2.0 makes it return the same error message, though. I'm not sure why. Also, it can't hurt to have the full list of extensions in there, right? I think I'll be using pretty much all of them anyway. (Except for maybe legacy-api, but that depends on what that specific extension includes.)
Title: Re: minisphere 3.0rc4
Post by: Fat Cerberus on March 09, 2016, 05:17:56 pm
I'd include legacy-api just to be safe.  It's basically a catch-all for any functions directly taken from the Sphere 1.x API that weren't reassigned to a Sphere 2.0 extension, so I don't really have a concrete list of what it covers. :P  One thing for future work would be to standardize exactly what constitutes Sphere 2.0 and go from there.  Ah well, something for another day.

Anyway, I'll look into the S2GM issue tonight.  Thanks for testing as always. :D
Title: Re: minisphere 3.0rc4
Post by: Fat Cerberus on March 09, 2016, 07:19:49 pm
Okay, that's a documentation bug and is on me. :-[  There are actually several things wrong with the example: JSON requires property names to be quoted, double quotes used throughout, and doesn't allow a trailing comma after the last array entry or property.  Here's a properly-formatted file:

Code: (javascript) [Select]

{
    "name": "Hunger-Pig Feeder 5000",
    "author": "Some Weird Guy",
    "summary": "Get eaten by the hunger-pig in your closet",
    "resolution": "3840x2160",  // in awesome 4K HD!
    "script": "scripts/main.js",

    "minimumPlatform": {
        "recommend": "minisphere 3.0 or later",  // note: for display purposes only
        "apiVersion": 2.0,
        "extensions": [
            "sphere-legacy-api",
            "sphere-obj-constructors",
            "sphere-obj-props",
            "sphere-map-engine",
            "sphere-rng-object",
            "sphere-s2gm",
            "sphere-spherefs"
        ]
    }
}


I'll update the documentation.  I also added a log line when an S2GM file can't be parsed to avoid confusion in the future.
Title: Re: minisphere 3.0rc4
Post by: Fat Cerberus on March 09, 2016, 07:38:41 pm
Follow-up note: JSON also doesn't allow comments. :o
Title: Re: minisphere 3.0rc4
Post by: DaVince on March 09, 2016, 07:49:26 pm
That made it work, thanks! :) Man, I didn't know JSON parsing was so much stricter, I thought it was pretty much just a JS object...

On a related note, the deb package associates sgm files with minisphere (at least, I *think* so... if I didn't do this before by myself). But not the s2gm. That opens with a text editor by default, and is recognized as a regular text file (so even associating it with minisphere will make *all* text files associate to minisphere).
Title: Re: minisphere 3.0rc4
Post by: Fat Cerberus on March 09, 2016, 07:56:59 pm
That's weird... the debs are built using pbuilder-dist which just runs "make" and "make install" in a chroot and then packages the installed binaries.  I didn't add any file association logic to it.  Somehow the package manager must know that .sgm files should be associated with minisphere, but I have no idea how. ???

And yeah, JSON is ridiculously strict.  I could have just eval'd the manifest but that leaves open the possibility of making malicious (but ultimately harmless of course) S2GMs that enter infinite loops or other such shenanigans.  Since it's just metadata, I figured parsing it as pure JSON was better.
Title: Re: minisphere 3.0rc4
Post by: Flying Jester on March 09, 2016, 08:04:48 pm

Follow-up note: JSON also doesn't allow comments. :o


The "traditional" way around this is adding "comment" elements to objects.
Some parsers accept comments anyway, though. I personally wish they all did  :-\
Title: Re: minisphere 3.0rc4
Post by: Fat Cerberus on March 09, 2016, 08:07:51 pm
We have Doug Crockford to blame for that.  He was apparently all "OH NOES people might put nonstandard parsing directives in the comments!!!1111"
Title: Re: minisphere 3.0rc4
Post by: DaVince on March 09, 2016, 08:28:53 pm
Quote
That's weird... the debs are built using pbuilder-dist which just runs "make" and "make install" in a chroot and then packages the installed binaries.  I didn't add any file association logic to it.  Somehow the package manager must know that .sgm files should be associated with minisphere, but I have no idea how.

Never mind me, then -- I might have associated the filetype myself at some point. It works perfectly and is definitely something to add by default if you ask me. :)
Title: Re: minisphere 3.0rc4
Post by: Fat Cerberus on March 10, 2016, 12:01:20 am
I guess I'll look into it before release, then.

By the way, true to form, I decided to tackle the letterboxing issue now.  minisphere's window scaling/resizing logic was in need of some refactoring anyway.  main.c being the oldest file in the codebase, it's quite a mess of spaghetti code compared to the rest of the engine and could definitely use some cleanup sooner rather than later.
Title: Re: minisphere 3.0rc5
Post by: Fat Cerberus on March 11, 2016, 05:05:06 pm
minisphere 3.0rc5 is now available, with fixes for several bugs found in 3.0rc4 by DaVince, and one fairly large change that really shouldn't have been done during code freeze but oh well: I added letterboxing support.  Linux deb packages also now automatically associate Sphere file types (.sgm, .s2gm, .spk) with minisphere.
Title: Re: minisphere 3.0rc6
Post by: Fat Cerberus on March 17, 2016, 01:30:08 am
Just posted 3.0rc6, the final release candidate.  miniRT has been overhauled and is now provided in module form, loadable using require('miniRT/threads'); etc.  Full API documentation for miniRT is finally included as well, so hopefully that'll make the library more discoverable.  It's definitely worth looking into if you don't want to reinvent the wheel--it includes a lot of useful stuff like my threading library, a version of Scenario, and a text console with built-in command parser (you just have to provide the command names and implementations!).

This will be the final 3.0 release candidate.  I don't see any further changes being needed and the engine has been bug-free in my own use, but if anything else comes up I'll just make the fixes to the final release without doing more RCs.  If I don't draw the line here, my perfectionism is going to be the death of me. :P

So anyway, go download rc6 and have fun!
Title: Re: minisphere 3.0rc6
Post by: HopeMetal on March 19, 2016, 08:47:21 am
I'm running into an issue when I try to put a game into windowed mode with F10 - it stays fullscreen, but the windowed game goes in the corner without any window border and everything else is black.
Title: Re: minisphere 3.0rc6
Post by: Fat Cerberus on March 19, 2016, 09:44:25 am
What's your graphics card?  Is it an Intel iGPU?  I have this too on my laptop (Core i3-5500U), but it affects all OpenGL games, not just minisphere--I think it's a driver issue with the newer Intel chips.  So there's not a lot I can do short of putting Allegro in D3D mode (which disables shaders).
Title: Re: minisphere 3.0rc6
Post by: HopeMetal on March 19, 2016, 01:40:42 pm
It works fine when I made minishpere use my dedicated nVidia card. Thanks for the lead.
Title: Re: minisphere 3.0rc6
Post by: Fat Cerberus on March 24, 2016, 12:35:16 pm
I'm finalizing building the binaries for minisphere 3.0.0 to be released on the 28th.  If anyone has encountered any issues with the RC, now is the time to speak up.  ;)
Title: Re: minisphere 3.0rc6
Post by: Radnen on March 24, 2016, 04:33:12 pm
I've been using this version and have not ran into any serious issues. I think I got it to crash once, but I haven't been able to reproduce it... I'll run stress tests later in the week and get back to you.
Title: Re: minisphere 3.0.0
Post by: Fat Cerberus on March 27, 2016, 11:42:07 pm
minisphere 3.0 is finally out! ;D  It's worth noting that this is minisphere's birthday - version 1.0, the first version to be almost fully compatible with Sphere 1.x, was released a year ago on this day, March 28.  Such a momentous occasion warrants a momentous release, and minisphere 3.0 delivers!  New in this release: The SSJ command-line debugger, TypeScript support, a fully documented miniRT, many, many undocumented bug fixes, and official support for Ubuntu Linux!

I decided at the last minute to bundle Sphere Studio in the (Windows) release after all.  And a note to users of 3.0rc6: Download 3.0.0.  As I suspected would happen, I had to make a few last-minute bug fixes before the release.

Anyway, go download minisphere 3.0.0 and have fun!  See the OP for a list of breaking changes.

edit: I forgot to mention, minisphere is also available on Ubuntu via PPA:

To install minisphere from PPA, open Terminal and run the following commands:
Title: Re: minisphere 3.0.0
Post by: Eggbertx on March 28, 2016, 04:34:55 pm
Just built 3.0 in Linux, and with few exceptions (like it segfaulting if you run it with a nonexistent folder as the game argument) it seems to be running perfectly.
Title: Re: minisphere 3.0.0
Post by: Fat Cerberus on March 28, 2016, 04:35:56 pm
If you use spherun instead of minisphere it will run windowed by default since that's used for debugging where fullscreen is generally undesirable.  This enables the debugger and other development features so there may be a slight performance hit, but it shouldn't be significant.  Do note however that spherun is designed for command-line use and therefore requires a game path--it won't run the startup game automatically.  What I can do for 3.0.1 is have the engine save the window/fullscreen state from the last run, perhaps per-game (spherun would still default to windowed).  That wouldn't be too difficult to do.

I'll look into that segfault, thanks for testing. :)
Title: Re: minisphere 3