SimEthereal basic example - plus public server

Much of this was already discussed in this other thread but now that the release is “official”, I thought it deserved its own topic for further evolution.

The full version release can be found here:
Latest version:

Old versions:

Along with this comes new releases of Lemur, SiO2, and SimEthereal and all of those have been pushed to jcenter. So it’s now possible to build the source for the example with building other dependencies first.

Reminder screen shots…

Main menu:

Four clients logged in:

For those who want to see just the changes that were necessary to integrate SimEthereal on top of the basic networking example:

Host-side integration:

Client-side integration:

Visualization interpolation:

I kept detailed notes as I did those changes so I can factor those into proper documentation… hopefully sooner rather than later.

Next steps for this app might be to add a chat bar. But I really want to fork it into a “basic + ES” version so I can start adding other objects than the spaceships, properly support colored ships, etc… These things are too hard to add to this non-ES version.

Also, I want to add some stats collection inside of SimEthereal and add debug displays of this information on the “game host”. Chat and stats I may add to this basic example (though it starts to become less basic then… so I may still fork an interim version.)

And I’ll just drop this here in case:

I have released version 3 and put up a public server.

To connect to the public server use as the host name.

You must use version 2 or 3 to connect. It includes the chat service and also ship labels.


When I have a version with a chat bar, I’ll probably put up a public server that folks can login to try out. Without chat, it’s a little too pointless.

1 Like

Pasting this here in this thread…

Pasting this from another thread because it’s probably even more relevant here:
I use UDP to send the deltas from a known good baseline that the client and server have agreed upon. The client acknowledges the messages that it gets (and keeps acknowledging). When the server receives one of these ack messages, it moves the baseline up to where the client’s messages say it should be and then starts sending a double-ack for those messages. That way the client knows that the message receive is based on a new baseline.

This is different than a true reliable protocol because stale data is still discarded and overwritten. A reliable protocol (like TCP) will deliver everything even when it’s crusty and old and no longer relevant.

The protocol also means that for objects not moving, that object’s individual state update is only 28 bits or something. (zone ID + network ID plus a few bits indicating that the data has not changed.)

Rotation and position are packed into bit streams…with the resolution of position greatly reduced since all positions are relative to the zone. For example, my SimEtheral example packs a Vector3f
position into three 16 bit values. Quaternions are packed into 4 12 bit values. So 48 bits each for position and rotation plus another bit each for ‘no change’ or not. So even a normal object update takes only about 124 bits… ie: 16 bytes with four bits to spare. Since everything is packed into a bit stream (which by the way are completely usable outside of SimEthereal) those four bits add up also. After 31 objects, I can fit a 32nd one in for free, basically.

But that’s why I can fit so many object updates in a small UDP packet. I think by default I clamp it at ~1400 to try and stay under a typical MTU size (so the UDP packets are less likely to be split in the network stack). In theory that lets me send 90 object updates in a 1500 byte message… there may be some additional frame protocol stuff that I’m forgetting.

If they can fit in the message, then I try to pack three frames at a time (this actually depends on how you call the network code but that’s the default). But I will defer a frame’s state to a new message or even split a frame to try to keep it under the current estimated MTU.

Edit: bitstream classes if anyone is curious:

Ability to pack Vector3f/Quaternions/etc. easily into bitstreams is part of my SimMath package:


Finally setup the documentation wiki for SimEthereal… see the topic on it here:

…or just go directly to the docs here:


Started adding a command console that will be used for chats.

And the commit that added that so you can see how little/much it took to do:

The only thing left to do there is to intercept the entered text in a configurable way.

Later today I will implement the chat network services then add the plugin function to the command console that will send the text to the chat service. Then: chat will work


Create a simple an generic Chat service that can be plugged into any SpiderMonkey-based application. It provides basic chat services but could easily be expanded with different methods or whatever since it used the RMI services.

Here is the commit that added just the service so you can see the classes. I put them in their own package to make it easier to extract them later if we want:

To be able to intercept the text the user enters on the new command console, I modified the CommandConsoleState to take a pluggable CommandEntry object:

And finally, this is hooking up the chat service. Plugging it into the networking was pretty much one line each on client and server. The rest of the changes are just hooking up the chat listener to the message display and the console entry to the chat sending.

I want to tweak what the messages look like and do a bit more testing then maybe I’ll setup a public server.

I have released version 2 and put up a public server.

To connect to the public server use as the host name.

You must use version 2 to connect. It includes the chat service and also ship labels.


thanks man
It was a nice feeling in space . :grinning:
I want to integrate my recently finished chat GUI for may game which is written with Lemur to networked chat system.
Lots of fun is waiting for me.

Well, presuming your networking is based on SpiderMonkey you can probably drop in my chat classes directly and just hook them up to your UI.

Thanks for connecting… it was nice to see someone else able to connect and fly around. :slight_smile:

1 Like

Yep, works (connected) well. Just want to inform :smiley: .

Works. Nice. Only two people in space, but still managed to crash into each other. Luckily there’s no physics (yet). ^^


Gotta give this a try tommorow. Also a read of the source.

Glad you guys were able to try it out… and that it actually worked. Heheh.

In your textfield - how’d you get the position for the cursor?

I’m currently struggeling with BitmapText having everything declared private - so I can’t access the individual glyphs. I thought maybe observe the quads from the vertex buffer - but that may be missleading since some quads have smaller xadvance than their width. But if everything else fails I will try to read that vertex buffer and use that as a hint to where individual letters are.

The code is available. Look for TextEntryComponent in the Lemur source code.

I think I do a “get size” with the characters up to the cursor. It is less than ideal.

Someday I will refactor how BitmapText outputs its glyphs so we can do more advanced stuff. As it stands, characters can overlap so even my approach is kind of broken.

→ uses:

// We add an extra space to properly advance (since often
// the space character only has a width of 1 but will advance
// far) then we subtract that space width back.
float x = font.getLineWidth(row + " ");
x -= font.getLineWidth(" ");

Ah, I completely forgot that you could do that with BitmapFont.

Tried to clone, then built the prerequisite Si02

gradlew install

and got:

:compileJava FAILED

FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':compileJava'.
> Could not find tools.jar

Seems like you don’t have JAVA_HOME set for your JDK.

1 Like

simethereal install

1 error
51 warnings
:javadoc FAILED

FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':javadoc'.
> Javadoc generation failed. Generated Javadoc options file (useful for troubles

What was the error?