Skip to main content

News

Topic: TurboSphere (Read 192728 times) previous topic - next topic

0 Members and 2 Guests are viewing this topic.
Re: TurboSphere
Reply #510
I hit a couple issues with listening on ports. I'm not quite sure where the actual bug is, maybe in the Network plugin, maybe in the plugin tools, perhaps even in SpiderMonkey.

A fairly annoying part is that Sphere's API is very close, but not the same as the BSD socket API. ListenOnPort makes sense--but for some reason, you don't `accept' a new connected socket out of that listening socket, you just use that same socket as the connection. It makes the script-side nicer, but only if you only need a single connection to the server side.

But I have been working on adding a Poll() API (sometimes similar APIs are known as Select, as in lua). Basically, just wait for an event from a group of sockets. This is already a part of libfjnet, and in reality is uses Select on Windows or ancient Unix (theoretically), Poll on Linux or more modern Unix such as Solaris, or KQueue on FreeBSD or BSD derived systems such as OS X.

On a side note, the KQueue/KEvent API is just miles ahead of Linux's Poll, even the more advanced Epoll system. Kernel APIs don't need to be abstracted for no good reason. KEvent and KQueue are very nice to work with. And Select is just kind of this sad little half-baked idea compared to either of them--I guess it made sense back in the 1990s. But I suppose this all makes sense, almost every one stole their TCP/IP stacks from BSD originally, so BSD has the most mature implementation.

I've worked out having a single Shape belong to multiple Groups. This was always supposed to be possible, but there were a few issues when using more than a single Shader.

Re: TurboSphere
Reply #511
I've updated to the newest version of SpiderMonkey. That's the first upgrade, and to be fair, the API changed.

But it was small and simple changes.

I had to replace this
Code: [Select]
 JS::RootedObject obj(ctx, JS_NewObjectWithGivenProto(ctx, &clazz, proto, global)); 

with this
Code: [Select]
 JS::RootedObject obj(ctx, JS_NewObject(ctx, &clazz)); 
JS_SetPrototype(ctx, obj, proto);


SM's api, from a pure ABI standpoint, may change fairly constantly, but conceptually it certainly looks more stable than V8's.

***

I also have been working on WindowStyles. As with many of the old APIs, it's difficult to properly compare the performance of TurboSphere with Sphere 1.5, SphereSFML, or MiniSphere directly. The new API enforces caching by enforcing persistence of objects and state. In the Turbo runtime, drawing a WindowStyle no longer looks like this

Code: [Select]
 // In the initialization
var window_style = LoadWindowStyle("windowstyle.rws");
// In the drawing loop...
window_style.drawWindow(16, 16, 128, 128);


Instead, it looks like this

Code: [Select]
 // In the initialization
var window_style = new WindowStyle("windowstyle.rws");
var window = window_style.createWindow(16, 16, 128, 128);
// In the drawing loop...
window.draw();


The WindowStyle.createWindow() function generates a Group that contains the specified window, all cached into a new Surface and uploaded as an Image for convenience.
This is equivalent to drawing a WindowStyle to an Image and then only drawing that.

  • Fat Cerberus
  • [*][*][*][*][*]
  • Global Moderator
  • Sphere Developer
Re: TurboSphere
Reply #512
Don't worry, you'll probably be able to compare them soon enough. ;)  minisphere is damn close at this point to being a drop-in replacement for Sphere 1.5--in fact, my compatibility at this point is higher even than SphereSFML due to using the original Sphere 1.x engine source as reference.  I might have mentioned this before, but once I'm happy with 1.x compatibility I'm going to branch the minisphere repo and work on a more Pegasus-y version of the engine.

I'm assuming the TS API is meant to be Pegasus also?

On a side note, I've actually been trying to get Aquatis to run in minisphere as the final compatibility test but with all the German text in the scripts, Duktape doesn't want to parse them.  I keep getting "char decode failure", preventing script compilation.  I'm assuming it's trying to interpret the accented characters as UTF-8 and failing...
neoSphere 5.9.2 - neoSphere engine - Cell compiler - SSj debugger
forum thread | on GitHub

Re: TurboSphere
Reply #513

Don't worry, you'll probably be able to compare them soon enough. ;)  minisphere is damn close at this point to being a drop-in replacement for Sphere 1.5--in fact, my compatibility at this point is higher even than SphereSFML due to using the original Sphere 1.x engine source as reference.  I might have mentioned this before, but once I'm happy with 1.x compatibility I'm going to branch the minisphere repo and work on a more Pegasus-y version of the engine.


That would be cool! The new API naively looks like a lot of work to use, but a lot of it just makes it more work to write things that are less efficient. Case in point, it becomes super annoying to redraw an entire WindowStyle window every frame, an operation that can bring several engines to their knees. At the same time, making the state persistent and caching the result become simple.


I'm assuming the TS API is meant to be Pegasus also?


This part is a part of the purely JS Turbo runtime. Ideally, any Pegasus-compliant engine would be able to use the Turbo runtime without any issue.
Some parts of the runtime are also things that should properly be a part of Pegasus, and that I have implemented in script. A Pegasus compliant engine could still use it, it would just overwrite those exposed components with its own.

If this is to become a part of Pegasus, it isn't in the spec yet :)


On a side note, I've actually been trying to get Aquatis to run in minisphere as the final compatibility test but with all the German text in the scripts, Duktape doesn't want to parse them.  I keep getting "char decode failure", preventing script compilation.  I'm assuming it's trying to interpret the accented characters as UTF-8 and failing...


That assumes Aquatis is really UTF-8, or UTF at all. Many european languages used to use codepages (oh, the glory days!), and from what I've seen I believe that the Sphere editor uses them--as an example, Sphere fonts are kind of wonky if you expect them to really be UCS-indexed. Using ascii for an extended codepage (or any codepage, really) will almost always make invalid UTF strings (unless you are very lucky: "Bush hid the facts" type scenarios)
  • Last Edit: March 06, 2015, 03:02:00 am by Flying Jester

  • Fat Cerberus
  • [*][*][*][*][*]
  • Global Moderator
  • Sphere Developer
Re: TurboSphere
Reply #514
That's what I meant, the Aquatis scripts aren't actually UTF-8 but Duktape is trying to parse the files as though they are and getting hung up on the extended characters.  Not sure if that's a bug or not, maybe I should report it to the Duktape devs.
neoSphere 5.9.2 - neoSphere engine - Cell compiler - SSj debugger
forum thread | on GitHub

Re: TurboSphere
Reply #515
I would consider it a bug of the old editor.

As much fun as I think codepages are (I really do enjoy working with them), I think that it would be more worth everyone's time to convert old CP strings to UTF-8 strings in scripts and resources.

Actually, a UTF converter for the resource formats may be a good idea.
  • Last Edit: March 06, 2015, 03:25:38 am by Flying Jester

  • Radnen
  • [*][*][*][*][*]
  • Senior Staff
  • Wise Warrior
Re: TurboSphere
Reply #516

in fact, my compatibility at this point is higher even than SphereSFML due to using the original Sphere 1.x engine source as reference.


Hey, I use the source as reference too! Especially for people and the command queue. I might not have as many data types loading just yet since I only focused on the most recent versions of each filetype, and windowstyles aren't even anywhere near full support. But still, I think with what I got there it's pretty dang close.
If you use code to help you code you can use less code to code. Also, I have approximate knowledge of many things.

Sphere-sfml here
Sphere Studio editor here

  • Fat Cerberus
  • [*][*][*][*][*]
  • Global Moderator
  • Sphere Developer
Re: TurboSphere
Reply #517
That's interesting, the command queue is one of the few persons-related things I didn't need a reference for.

Where I do tend to refer to it is to hammer out little subtleties, like how edge scripts work.  See, instinct would be to implement those working identically to triggers, right?  But no, it turns out Sphere will keep calling the edge script continuously as long as the input person is past the edge.  Non-intuitive, but for full compatibility the behavior has to be replicated.
neoSphere 5.9.2 - neoSphere engine - Cell compiler - SSj debugger
forum thread | on GitHub

  • N E O
  • [*][*][*][*][*]
  • Administrator
  • Senior Administrator
Re: TurboSphere
Reply #518

Instead, it looks like this

Code: (javascript) [Select]
 // In the initialization
var window_style = new WindowStyle("windowstyle.rws");
var window = window_style.createWindow(16, 16, 128, 128);
// In the drawing loop...
window.draw();


The WindowStyle.createWindow() function generates a Group that contains the specified window, all cached into a new Surface and uploaded as an Image for convenience.
This is equivalent to drawing a WindowStyle to an Image and then only drawing that.



If the API isn't yet finalized, can you also add window_style.createWindow(width, height) and window.draw(x, y) ?

Re: TurboSphere
Reply #519
You can always change a group's X and Y by directly setting it's `x' and `y' values:

Code: [Select]

// In the initialization
var window_style = new WindowStyle("windowstyle.rws");
var window = window_style.createWindow(16, 16, 128, 128);
// In the drawing loop...
// Move it somewhere...
window.x = GetMouseX();
window.y = GetMouseY();
// Now it draws at the mouse's coordinates
window.draw();


One major drawback of Sapphire's current implementation is that changing the properties repeatedly in between multiple draws within a single frame can cause certain combinations to not draw correctly.
That's because, while drawing is pipelined, state changes such as the texture, coordinates, and rotations, are executed immediately. I can change this, but it results in a fairly decent increase in latency.

I decided that it would be better to just have multiple Groups, one for each distinct 'thing' to draw each frame, since Groups are rather lightweight compared to Shapes or Images. Plus, that kind of practice makes the object model more logical. Each Group represents some group of Shapes that is a part of your current scene.
  • Last Edit: March 07, 2015, 08:06:22 pm by Flying Jester

Re: TurboSphere
Reply #520
I finally fixed map obstructions.

The issue is that I was reading the obstruction data after reading all headers. So, like this:

Code: [Select]

for(var i in tiles){
    tiles[i].loadHeader(stream);
}

for(var i in tiles){
    tiles[i].loadObstructions(stream);
}


That's totally not right. I had misread the documentation (or just interpreted it differently). In reality, it's like this:

Code: [Select]


for(var i in tiles){
    tiles[i].loadHeader(stream);
    tiles[i].loadObstructions(stream);
}


This was made MUCH more difficult to spot because the three test maps I usually use--Radnen's 'old school' map, the 'Astral' map from Trial and Error, and an early battlefield map from Attack!--all  exhibit almost correct behaviour when I read the obstructions this way. I had long assumed I was not performing segment intersections correctly.
On the bright side, my line intersection code is rather nice now :)

Tile animations are next. I have a few different ideas on how to handle these.
  • Last Edit: March 12, 2015, 04:20:46 am by Flying Jester

  • Fat Cerberus
  • [*][*][*][*][*]
  • Global Moderator
  • Sphere Developer
Re: TurboSphere
Reply #521
How did you finally figure it out?  Did you look at minisphere's source or...?
neoSphere 5.9.2 - neoSphere engine - Cell compiler - SSj debugger
forum thread | on GitHub

Re: TurboSphere
Reply #522
I took a break and worked on other projects. When I came back, I added some debug code to draw the obstructions on the tiles themselves. When I did, I accidentally changed the order to be correct.

  • Fat Cerberus
  • [*][*][*][*][*]
  • Global Moderator
  • Sphere Developer
Re: TurboSphere
Reply #523
The only thing I can't figure out is how it went unnoticed for so long.  The way you were doing it, wouldn't you just end up getting back garbage tile headers after reading the first tile with any obstruction data?
neoSphere 5.9.2 - neoSphere engine - Cell compiler - SSj debugger
forum thread | on GitHub

Re: TurboSphere
Reply #524
I haven't yet implemented much that would use the headers. I was trying to just do obstructions first, and my test maps just happened to make almost-valid looking obstructions using their header data that way. That was why it took so long to figure out--it looked like I had obstruction data, but I was misinterpreting it or having issues with collision detection.