Ramblings of a Flash game programmer

ElectroServer 5.1 was released today with tons of updates that you can read about in the release notes. Aside from added examples and documentation, the biggest enhancements are noted below.

Bandwidth optimization
The bandwidth used for the most common message types was reduced significantly. It was already light weight but we were able to optimize it much further. In addition, messages can be set to automatically compress if over a certain size threshold.

Increased performance
We tuned the low-level messaging layer to achieve unprecedented performance. We’ve done testing to more than 100,000 messages per second with very low CPU impact (on EC2). This level of performance gives the server-side portion of your game plenty of room for its own logic to be executed.

JavaScript client API
A JavaScript client API was added to the arsenal. This is an important addition to the server to give it the broadest cross-platform reach of any multiplayer game server out there. ElectroServer has client APIs for ActionScript 2, ActionScript 3, Java, JavaScript, C#, and Objective-C. These APIs gives developers multiplayer support for Flash, AIR, Unity, .Net, XNA, iPhone/iPad, Android, native browser, and more.

New Game Examples
This release adds two new games to the examples list.

Zombie Race – A real-time multiplayer Flash game. From a top-down perspective, 2-4 players try to navigate their zombie through the maze to reach the brain first!

Iron Mongery – This is a single player puzzle game written with a Java client. Other players can chat with you and watch you play your game.

Creating a chat in Flash is easy using ElectroServer and MXML. If you are interested in creating multiplayer games, then first creating a simple chat application can help you learn the basic API calls used to communicate with ElectroServer. After building something like this you will have enough confidence to take the next step toward making a multilayer game!

After many months of hard work by the team at Electrotank, I’m pleased to say that ElectroServer 5 (ES5) is out the door and ready to power tons of new multiplayer games and MMOs! It is available now for download and comes with a free 25 concurrent user license (with no other restrictions). In addition to the great new features with the 5.0 release, we have a ton of additional features that we’ll be adding and releasing over time.

Over ElectroServer’s 8+ year life it has primarily been used for Flash applications. We’ve now introduced APIs across several languages keeping them as similar as possible. You can now have players play against each other across a multitude of platforms. The supported languages and platforms are,

AS2 and AS3 – Flash, AIR

C# – Unity3D, .Net, and XNA

Objective-C – iOS

Java – for any Java enabled client

UDP

For the fastest and most light weight message transfer, ElectroServer 5 provides the option for UDP messaging. UDP is needed for first-person shooters and racing games.

Message encryption is just one extremely effective means in which ES5 secures client-server communications. ES5 also supports cryptographically hashing passwords used to log onto the system.

Full-featured Sleek Admin

ElectroServer’s admin tool has been completely revamped to be more user-friendly (and attractive!). With it you can configure every aspect of the server. In addition, there are new reporting features built right in. You can view and configure graphs showing up-time, bandwidth usage, CPU usage, and more. There is also the ability to browse snapshots of the server to inspect which rooms exists and who is in them.

Extensive Documentation & Tons of Examples

We invested a lot of time in creating thorough documentation for every server feature. There are tutorials and more than 30 examples! ES5 also comes with a handful of complete multiplayer games.

Screenshot of ES5 game example

Screenshot of Es5 game example

I hope to post more on ES5 and multiplayer game development in the near future.

The setup

I’m currently building a shooter game. There are lots of walls and at any time there may be lots of bullets. For the sake of simplicity, think of this game as 2D (with a top-down view). For collision detection purposes the walls have no thickness. The walls can be visualized as thin lines drawn anywhere at any angle. This does not restrict the position or movement of anything based on tiles.

Since there are bullets and walls I had to figure out the best approach for bullet-wall collision detection. The basic approach is easy to understand.

Imagine a line that a bullet would draw as it moves from one time step (or frame) to the next.

Take this line and do a line-to-line collision check against all of the walls.

Collect a list of all collision points that were found.

Do a distance check against the position of the bullet last time step (or frame) against the collision points found, and take the smallest distance as the true collision.

The above works great. However, the bigger the map and the more bullets on-screen the more time it takes to perform the collision detection. What I wanted to do was to find a way to run the collision check steps just described above, but instead of running it against all walls on the map, just run it against a small subset of the walls – the ones most likely to have been hit. Essentially, I wanted to find a way to cut down from what could be thousands of checks to a small handful of checks.

Initial attempt at culling

Imagine for a moment that there are tiles of an arbitrary size used to cover the entire map. Nothing is restricted by these tiles, and the user cannot see the tiles, they are just used as a convenience for us to cull walls. First we want to pre-process the map:

When the map initializes

Run a Bresenham line search against the grid with the two points that make up every wall.

For every tile that a wall touches, push a reference to that wall into an array stored in that tile.

Then for a specific bullet that is in motion:

Take the line that the bullet made between the last time step (or frame) and this one, and run a Bresenham line search against the grid.

Loop through every tile that is returned and check to see if any walls are referenced within it.

Use this collection of walls with the collision detection described at the top of this post.

The problem

Bresenham’s line algorithm is intended to give a best approximation of which tiles a line drawn between the center of any two tiles touches. This presents a problem for us because the line a bullet makes can originate and end at any point within a tile. In the image below you can see that Bresenham’s line algorithm gives us most of the tiles that the bullet travels through, but not all of them.

The fix

To fix the above problem we just add to what the search does. Instead of doing the search one time, we do it 5 times. Assume that the line originates on tile (x1, y1) and ends on tile (x2, y2). We run this search against:

(x1, y1), (x2, y2)

(x1-1, y1), (x2-1, y2)

(x1+1, y1), (x2+1, y2)

(x1, y1-1), (x2, y2-1)

(x1, y1+1), (x2, y2+1)

Run all of the searches listed above and then filter the results by:

Removing any tile duplicates.

Removing any tile that lies beyond the bounding box made up of (x1, y1) , (x2,y2)

And then sort the results based on tiles that would be touched by the line moving from the originating tile to the destination tile (see source code for sorting logic). The end result is a list of tiles that could be touched by a line drawn from any point within the starting and ending tiles. In many cases you’ll have extra tiles that the line will not have passed through. That is fine. The benefits far outweigh the check against an excess tile.

It seems like there is a lot going on to perform the search and sort the results. That is because there is. But the search is very fast. Only integers are used, no trig functions used, and there are no square roots. Running this search against a bullet that crosses a large map in a single frame is might take 2 milliseconds. And you are left with a small subset of all the walls in the map to run your collision math against.

There is another benefit here I didn’t mention yet, and you can see by the numbered tiles above. The tiles are returned in order of the possibility of them being touched by the line. That means that you can run the actual collision detection against the walls found within a tile as you loop through the tiles. If you find a collision within a tile – you can stop processing any more tiles. You still have to finish processing the current tile because there may be more than one wall in that tile, and the walls within the tile are unordered. So that is a nice advantage! If you have a line that crosses an entire map, it could still have dozens or hundreds of tiles returned. But you might only have to process a few of them.

Final notes – over-drawing

I just wanted to point out one final thing. As mentioned above, this approach can return more tiles that the line actually passes through. But it doesn’t always. Vertical lines and horizontal lines return the exact tiles touched, and 45 degree angles return the most excess.

Bresenham’s line algorithm is a fairly simple algorithm that takes two tile positions in a grid and returns a list of all tile positions that a line drawn between the two positions touches. It is well described along with easy-to-read pseudo code here.

When is this useful? According to what I’ve read, this algorithm and variations of it are useful in graphics programs. I’m sure you’ve seen programs that let you draw icons in a zoomed-in view. While you draw lines it just colors in boxes. It is likely this algorithm was used for that. However, I use this algorithm for game-related purposes. The last time I used it was probably 5 or 6 years ago in a Flash pool game. I set up a grid with an arbitrary tile size on the pool table (that the user can’t see). Every frame I determined in memory which tiles a ball covered as it moved (assuming no collisions). Then I would only run collision detection against balls that touched the same tiles. This let me cut down on the number of collision checks per frame.

I’m coming back to this algorithm again now because of a first person shooter game I’m working on. I hope to create a blog post on how the algorithm is used in that game (on the server) to keep the collision detection calculations to a minimum.

This post is slightly related to my previous post, Referencing Classes Outside of Your Project in Visual Studio. What I describe here for Unity will also work for Visual Studio. I am very new to Unity development. By new, I mean that I’ve probably only invested about one day into it so far. That’s my disclaimer in case there is a vastly easier way to this.

Coming from a ActionScript/Flash background I’m used to being able to just add classpaths to a project that point to any arbitrary locations on my hard drive to reference code. My project code would generally be located right there with the project, but utility code that is used across many projects would be located in another location.

In Unity (as far as I can tell) the only classes that you can reference are those that exist within the [project]Assets/Scripts directory, or sub directory. I haven’t discovered anything that is similar to adding a classpath in Flash. Also, while Visual Studio let’s you add an existing item ‘as link’ (see this post) Unity doesn’t appear to have that feature.

So what is the solution? A solution in Windows Vista or Windows 7 is to use symbolic links to add the directories that contain the source files to your [project]Assets/Scripts directory. If you create a symbolic link to a directory then for all intents and purposes that directory is seen as existing in two places (obviously there really is only one version of it though).

You can create a symbolic link in a directory by using the command prompt, navigating to that directory, and then running a ‘mklink’ command. If you just run ‘mklink’ by itself you’ll see the options:

The option you want to use is /D for creating a link to a directory. Here is an example usage:

‘my_new_dir_name’ is the name that will show up in the current location when this command is run. ‘path_to_real_dir’ is the absolute path to the real directory you are linking to.

That title is a mouthful, but I couldn’t think of how to else to phrase it. Coming from a pure Flash development background I’m new to C# and Visual Studio/Web Developer. And there was something about Visual Studio that was driving me nuts for the first few weeks. In Flash I’m used to being able to have a project which would contain source files and may reference SWCs (compiled code like DLLs). And I’m used to being to reference source code from anywhere on my computer that is outside of my project by simply adding that location as a classpath. This would allow me to work on my current project, but still suck in the source code to other APIs and utilities as a code so that I can work on them all at the same time.

In Visual Studio I wasn’t able to figure out how to reference code that lives in some arbitrary location outside of my project. Doing this is actually pretty easy, but it was weeks before someone filled me in. Here is what you do (see images below also) :