Strap in, folks, this is going to be a wild ride.

Not really. It’s more development talk, so it’s about as wild as a walk in the park, which this project is turning out not to be.

I have mentioned that a lot of otherwise simple development tasks seem to take me longer than it would competent developers, and this round is no exception. Let me set the scene:

I am at the point in the Project Galaxy…project…that I need to start working with Colyseus as nature intended. In order to do that, I need to define “rooms”. Each sector in the galaxy is a single room, so in order to get a player into a room, and to let a player move between rooms, I need the sector data defined in the database.

Way Back When, I had written code that generates “a galaxy” with [X,Y] total sectors, and in each sector, up to 8 planets of different types. Some of those planets might have stations which the player will be able to dock with. All of this is air-quotes-procedurally generated-air-quotes in the most painfully simple way possible. Since I have written and re-written this for several different platforms, I wasn’t about to reinvent the wheel, but the question is: how do I adapt this one-time “big bang” for this current attempt at the game?

Naturally this is a sensitive piece of code. I don’t want it to be publicly available so some hacker can find an API endpoint and trigger a galactic Armageddon after the game has been started. Since the process deals with the initialization of data and doesn’t have any effect on the running game, I had originally thought it would be Wise to sequester access via a desktop app (hence the previous post), but that turned out to be a nightmare.

Instead, I fell back on Nodejs and React. I have my custom database connector code, which is working well, and my Last Known Good big bang code was Javascript anyway, so it was a short hop between what did work and what does work. In the process, I learned a few things.

Server Sent Events

I hate myself for only discovering this now.

Javascript has a native feature called EventSource. This ‘lil chestnut is a middle-finger to the stateless web; by providing an endpoint, a connection will be maintained to a server and a listener can be set up to accept and deal with messages from said server.

const events = new EventSource('http://MYSERVER/ENDPOINT');
events.onmessage = (event) =>{

     //Parse event.data to get a string message from the server.
}

On the server, we have a little more work to do. I am using ExpressJS with Node, so I have written some middleware that accepts all traffic at a specific endpoint and passes it through the handler.

module.exports = bigBangEventsRouter.get('/:cmd', (req: any, res: any, next: any)=>{

    if (req.params.cmd === "do-it"){
        //Required headers
        const headers = {
            'Content-Type': 'text/event-stream',
            'Connection': 'keep-alive'

        };
        res.writeHead(200, headers);

        //DO STUFF

        //Any time I need to send a message, I encode it like this:
        res.write('data: THIS IS MY MESSAGE\n\n');
   }
});

Those headers tell the client to keep listening for event-stream content by keeping the connection alive.

The ramifications for this are pretty amazing. In fact, I have a project at work that can totally benefit from this, and I will be looking at how to integrate this into that project.

Layouts Galore

Originally, I had just wanted this app to perform the big bang on the universe, but then I thought about it and realized I’d probably have to do some massaging of the data once the procedural generation was complete. For example, I’d need a way to ensure that all systems are linked via jump gate. While I could (and plan to) write some sanity code to check this, being able to manipulate the data to “clean up” situations where content is bulking up in one corner of the galaxy when others are more anemic.

Long Ago I found a UI package called Golden Layout, and to say that I was enamored would be an understatement.

Golden Layout allows for the compartmentalization of content inside panels which can be dragged and dropped, docked, maximized and minimized, added and removed. For a dashboard style project, it’s very slick and extremely powerful.

It also sucks for React. A while back I read that they were dropping React support, but I didn’t find that disclaimer this time around. I tried implementing it with my project, but it simply did not work.

I found another option back when I learned GL was dropping React, called FlexLayout.

It works almost exactly like Golden Layout, but isn’t as attractive out of the box, but that’s Ok because it’s designed to work with React and it was fairly simple to implement once I wrapped my head around the JSON design paradigm. It does present a challenge in getting reactions from panels based on actions taken in other panels, but I do have a big bang system in place that works really well already.

The list items above are sent from the Node server to the client via the Server Sent Events system, and they come through in real-time (not at the end of the entire process), so I’m pretty happy with the results this far.

Leave a Reply

Your email address will not be published. Required fields are marked *