Have any questions about me, my projects or any of my blog posts? Send me a Tweet!
The past two weeks have been dedicated to refining and testing the network engine, XI Networking Engine.
I can finally say that the networking is ready for a full implementation, which has now begun.
Doesn’t look like much (There is much, believe me) so what this is is a client-side console interface to the game, started up with the -console true argument. From here, commands (And cheats) can be entered and remote commands can be sent to the server.
This is, in short, the underneath of the entire game. Every game-related variable, every script function, every map command, can be accessed via this console with the remote server commands. Of course, in this instance the server is not remote, it is local, but the interfacing is all the same.
As for the network code, this is how it looks:
The Create() static method initiates the networking.
The Tick() method would be called on a separate CPU thread.
The Drop() method would be called when the network is being closed.
I’ve been testing this over the past two weeks across different networks and all is looking pretty stable, so moving the game code onto the server-side is the last thing left to do.
This week I’ve been working on collision detection and I’ve come up with some neat stuff.
I had another collision detection system in place, a quick simple one that acted by taking the location of the next position after simulation and checking if it is within bounds before moving it into the offset area, I’d then take the simulation X, Y and Z directions and test them individually, if one were to fail I’d ignore that and only follow the simulations of the others, resulting in the ability to slide along rules, albeit a rather crude system (Where non orthogonal walls had a strange step-collision that would bump the player as they slid along it). This was fine until it failed 2 crucial test cases, at that point it was a failure and I would have to ditch this quick solution for the ‘correct’ solution.
So I’m going to detail this new system.
First of all; The UDMF systems involved in the engine are wholly 2 dimensional, this is the curse of Doom maps (Of which UDMF is derived from), they are 2-dimensional so no rooms-over-rooms and certainly no Marathon-style 5-dimensional portal spaces.
On this limitation we can eliminate any complex collision detection in the 3rd dimension, the Y axis (Up and down), we only need to check the complexity of 2 dimensions, X and Z. What is left is the sector format of UDMF, the mapping system is based on sectors so we can take advantage of this - as well as the binary space sectioning to speed things up.
Imagine that this is a map’s sector with the red large dot being the player and the outer red ring being the width of the player. The collision detection first grabs the sector that the player is within, in this case it’s the black lines representing the walls with the normals pointing into the centre of the sector.
The next stage of the collision detection is to find all the lines of the neighbouring sectors too.
So we have the search-space collected, we then check how far away where the player aims to move to is to each of the walls. The moment the search finds a wall that is within the width of the destination, it will nudge the destination along the normal of that wall until it is beyond said distance. It will repeat this for all walls, nudging the end position until it satisfies the collision rules.
The obvious limitations are;
The bonus of this method; Because the end position is nudged along normals, the player can slide along walls with the step that the original method gave, additionally, this is a 1-time check for each movement, rather than a check for each direction.
What is left to do is add the additional rules for stair-cases and non-standard wall behaviours.
Not much to say besides lots of work with the Network Engine and the UDMF format.
It’s been mostly bug fixes and under-the-hood changes this week. I can show off one thing though, I’ve been using RPG Maker as a testing application for my network engine, and things are going well!
See? Doesn’t look interesting in a screen shot.
Now how do I show a screen-shot of Battle World’s new movement code…
I’ve been back on that network code this week!
So I’m going to write a bit about the plan with this part of the game engine.
The plan is for the network module of the engine to be a separate entity that can be re-used in other projects. The network module will be called XI Networking Engine; XNE as the acronym.
The story is, a couple of years ago I create a network (Online and LAN) FPS game for my second-year university project, but the game was incredibly buggy as it was my first journey into network applications and I was unfamiliar with the networking solution I had chosen; Game Networking Engine (GNE). GNE had taught me a lot and I quickly learnt that it wasn’t a project that was to do what I wanted to do, I wanted an efficient UDP packet sending service with a reliable messaging system with an easy to use API behind it.
An Example XNE Packet
The above image shows an example Connection Request packet with XNE, built with 4 classes, each inheriting from the above class;
From this, we can read an incoming Packet from the socket, peak to read it’s QPacket type code and then cast it to the relevant type for the API, calling FromBytes() to finally build the packet for reading. In the other direction, we can make a new Control Packet, give it some information, and send it as a simple Packet using ToBytes(), so there is a stack between the socket and the packet that sending and receiving needs to go through.
XNE will also provide session control, the engine itself ticks in the background managing reliable messages, sending batches of Game Packets to users and handling connected clients.
In the future I will make a dedicated section on the website for XNE where the project API will eventually be published.