Here's a demo of a multiplayer 2D top-down shooter I've been working on. I like to think of it as the next-gen Counterstrike/Half Life The only things holding it back are my artistic and 2D (let alone 3D) graphics skillz. Requires java 5 or better.

It's not much fun on your own since there's no computer players. I've tested it on a LAN with 4 players and it worked well. I haven't tried it on the internet yet - it only copes with maximum 1/2 a second lag using the default settings (but you can change them in the options menu).

If you're interested, this is the long-winded story of how it copes with lag. Background: in the old buggy version I made a few months ago, when an event (like a mouse click) came from a client that was in the past, in the old version I would update the World by a negative time, and relied on the game logic being so clever that it would reverse everything. That was too difficult since reversing a bullet past the point that it was shot would kill the player that shot it, etc, so I gave up.

Then a good fellow gave me the idea of saving a copy of the World to go back in time. So what this game does is have 2 Worlds. The first World (which I call the head) is the one which is displayed on the screen and is kept up to the current time. The other world (the tail) is slightly behind the head in terms of the time that it is updated to - in my game it's half a second behind the head. When a lagged mouse click comes through from a client, ithe event's timeStamp is read by the server and other clients and they do headWorld.makeEqualTo(tailWorld). So the head world is made to be exactly equal to the tail (as in head.equals(tail), not head == tail) so the head World has effectively gone back in time by half a second. Then the head World is advanced up to the time of the mouse click, the event is applied, and the head world is advanced to where it should be and then it's rendered! Smooth eh?

To keep the tail world 0.5 seconds or a bit more behind the head world, periodically I call headWorld.makeEqualTo(tailWorld), then advance the head a little so that it's 0.5 seconds behind the current time, then I do tail.makeEqualTo(head), then I advance the head world up to the current time.

And another benefit from this system which is quite neat - it allows synchronisation updates to be sent from the server to the clients. By that I mean that the server is able to make sure that its World is the one being seen by all of the clients. You see, every second or so the server sends its tail world to the clients and they do clientTailWorld.makeEqualTo(tailWorldFromServer). Then the clients do headWorld.makeEqualTo(tailWorld), and advance the head to where it's meant to be to be displayed. So everyone is re-sync'ed every second.

But the devil is in the detail and it wasn't easy to implement. This game uses reflection (http://java.sun.com/javase/6/docs/api/java/lang/reflect/package-frame.html) to do the makeEqualTo method and despite the reputation of java.lang.reflect to be slow, it isn't the bottleneck at all (rendering is). By using reflection, I didn't have to hard-code the makeEqualTo method so that it assigned every field properly, which would be difficult to do when adding new features all the time. If this games new features and bugs settle down then I could over-ride the default makeEqualTo method so that it uses code (object1 = object2 etc) instead of reflection (object1Field.set(Object obj1Parent, object2)), but I can't see that becoming necessary.

Unfortunately the network API is still crappy but at least it works (I've been meaning to work out the issues I've had with Riven's kindly-provided framework but I haven't had time, maybe I'll go with Sunset's JGN API).

I've kind of dumped the idea of making a network game engine, at least until I've made a few games which work well and discovered what parts of the code are re-usable. But if anyone really wants to extend this game or make a cool RTS or something out of it then be my guest, grab the source.

A big problem is that there is no physics yet. When you crash into a wall you just stop (i do line-circle or line-line intersection testing and if there's an intersection, the player or bullet just stops or explodes). I tried to get the Box2D physics API to work with my network API but it uses Enums (darned things) which I haven't been able to get to work with my serialization code yet.

Any comments appreciated

Cheers,Keith

PS: I did most of the game's menus using the Netbeans GUI builder which isn't bad (but it's a bit fiddly and I struggled to get it to work with java 5 but in the end I won). The menu's look and feel uses Kirril's great Substance skin RavenGraphiteGlass. You can try other skins too in the game menu.

Thanks, I hadn't heard of that. I didn't know that this field was already such a fine science. Sounds like they propose to use multiple tail worlds and they use the tail worlds to sync not just the clients with the server, but also the mirror servers (which apparently help lower latency) with a central server.

Looks very cool and complete with features. I like how you can so easily zoom in and out (good use of vector graphics)

It would be cool if when one clicks the JNLP link some kind of lobby appears to help find opponents.

Thanks, yeah i thought zooming was pretty important since other wise people who can run the game in a maximised window, or people with bigger screens, could see more and have an advantage. Luckily it's pretty easy to zoom using Java2D.

I'd really like to do a lobby too but I think I'd need my own server which all games connect to to find out the IP of what games are being hosted. Unfortunately I don't even have the internet at home

How about some non-lethal ones? Such as a gravity bomb which draws all nearby players towards itself, or an air blower which blows players/bullets away, or some things for stunning the players - for example a flashbang which blinds the screen of everyone who is looking at it.

Nice one! The concept has great potential and it seems you tackled most of the startup obstacles of getting there. Will you target a vector graphics style or will you "dress up" the objects with sprites later?

Thanks, I hadn't heard of that. I didn't know that this field was already such a fine science. Sounds like they propose to use multiple tail worlds and they use the tail worlds to sync not just the clients with the server, but also the mirror servers (which apparently help lower latency) with a central server.

There has been done a lot of research in this field, the academic term under which a lot of research is done is called NVE (Network Virtual Environment).These are some good lectures available that walk you though them (with the focus on games):

Unfortunately the network API is still crappy but at least it works (I've been meaning to work out the issues I've had with Riven's kindly-provided framework but I haven't had time, maybe I'll go with Sunset's JGN API).

I'm sorry I didn't ahve any time to fix that newly crafted API. I haven't had a few hours of spare time (that I didn't spend falling asleep) for the last few months, and it seems it will stay this way for at least three more months. Oh well. In the future I'll need a proper networking-API myself, and then I can work on it in the boss' time

Quote

A big problem is that there is no physics yet. When you crash into a wall you just stop (i do line-circle or line-line intersection testing and if there's an intersection, the player or bullet just stops or explodes).

Yup, I noticed that, it a bit annoying at time. It's actually quite easy when you simplyfy the whole problem, and using Verlet-Integration (google for it, on site:gamasutra.com) combined with stupid-simple collision-response: in case you hit a wall, simply move the 'offending shape' out of the line/plane/triangle/sphere/whatever it bumped into, and just continue like nothing happened, the verlet-integration will make the object loose speed, bounce off (with bullets), or whatever suits the gameplay, without any sin/cos/tan/dot/cross anywhere. Like in the real world, physics just happen, they are the result of extremely simple math, not dealing with angles at all.

(blah blah blah)

You can implemnt it in a few hours, you really can't fail.

Hi, appreciate more people! Σ ♥ = ¾Learn how to award medals... and work your way up the social rankings!

How about some non-lethal ones? Such as a gravity bomb which draws all nearby players towards itself, or an air blower which blows players/bullets away, or some things for stunning the players - for example a flashbang which blinds the screen of everyone who is looking at it.

An air-blower, that's a great idea. hmm, I'll need to work out some physics though. Stun guns and flash-bangs should be easy, thanks.

You can get a SSH account on my own VirtualPrivateServer, if you wish. It's hosted in a datacenter near Amsterdam, 100mbit.

Gee, thanks for the offer Riven, that sounds fantastic . So how would it work? I haven't got any experience in these sorts of things sorry. So when someone starts my game and they create a server it would write to a small file on your server, recording its IP and port? And then when someone else starts another game and enters the lobby they would download that small file to see what games they can join? I haven't got much experience with the specifics of internet hardware, security, IPs or anything unfortunately.

I know what you mean about the physics, bumping into stuff is really annoying, that's the main reason why I haven't got vehicles like tanks and jeeps. I'll check out vertlet integration, thanks.

Nice one! The concept has great potential and it seems you tackled most of the startup obstacles of getting there. Will you target a vector graphics style or will you "dress up" the objects with sprites later?

There has been done a lot of research in this field, the academic term under which a lot of research is done is called NVE (Network Virtual Environment).These are some good lectures available that walk you though them (with the focus on games):

Cheers Thijs! Well I'm not really sure where I'll take this game in particular. I only made it to see if the network engine code performed in a twitch game where every mouse move sends an event to the server and all other clients. My true motivation, like everyone else, is to make a MMORPG before I die In the meantime, I want to make a modest 2d Runescape type of game, and hopefully I can re-use this code to do the network stuff. 3D graphics are my weakness so yeah I suppose I'll make sprites.

Thanks heaps for the interest guys, I really appreciate all of this feedback

Gee, thanks for the offer Riven, that sounds fantastic . So how would it work? I haven't got any experience in these sorts of things sorry. So when someone starts my game and they create a server it would write to a small file on your server, recording its IP and port? And then when someone else starts another game and enters the lobby they would download that small file to see what games they can join? I haven't got much experience with the specifics of internet hardware, security, IPs or anything unfortunately.

You'll just get a directory, and i'll put a decent JRE in it for you.You are free to do what you want in that directory.

Could you PM me your email-address?

Hi, appreciate more people! Σ ♥ = ¾Learn how to award medals... and work your way up the social rankings!

I have some AI code that maybe could run on the server. Also, there are sprites for humans, lots of bugs, some robots, some aliens and such.Ask and you will get it, source and images.

Gunslingers looks very polished. The line-of-sight is an impressive feature, I would also like to do it. Thanks for the offer of the source code and images, that would be great to have. Is yours a tile-map game? I'd like to see how you did it since I wish to make an rpg too. I don't want to rip off your graphics, but just to see how they're done would be great. The nice explosions would be good to use if that's alright Thanks a lot Markus

I've noticed that some people have started the game and are in the internet lobby, but they never join the dedicated server game. Does joining the game not work for some people? I'd really like to know if it's not working properly, so if you could let me know (or even better, post any output from the console), that would be fantastic.

Hi everyone, thanks for trying my game, there's been about 80 people who have joined over the past day!

Unfortunately I'm taking down the dedicated server for a while until I fix a performance proble Since I know you're itching to play this state-of-the-art 2D 4-colour game, I'll let you know as soon as it's back up...

What did you think of the bots? They're pretty awesome eh? Try setting 'numbots = 9' by typing that into the chat at the bottom of the game window after you create a game. They have a full-on battle with each other, it's amazing! I think the machine gun bots are the hardest, and after that the sniper bots since they've got perfect aiming, you can't stand still when they're anywhere near.

Hey if anyone would like me to explain anything about the game and how it works, I'd be only too happy Something useful in it for network game-makers might be the way I used the excellent Apache MINA to do the network communication... MINA looks like the most solid java NIO framework that's around.

As I said in the JGN post there, JGN worked well and was the easiest network framework to use and understand, and Matt Hicks (Sunsett/DarkFrog) is very helpful with answering questions on the JGN forums.

All networking communication is done using byte arrays (or ByteBuffers which are just a wrapper around a byte array). Mina uses ByteBuffers, but like almost every other network library, it tries to make it seem like you can send whole objects over the network, but in reality it turns the object into a byte array and then sends that and turns it back into an object on the other computer. In my use of Mina, I made (actually I copied it from someone) a special class that is used to just send byte arrays, called sydneyengine.network.ByteArrayCodecFactory. If you want to send Strings, you can use DataOutputStream.writeUTF(String) and then get the byte array from the ByteArrayOutputStream which is inside the DataOutputStream.

I haven't read that particular chapter of David Brackeen's book, but I know it's very good. You'll be happy to know that David frequents this forum so you could ask him dirtectly!

I was thinking about doing something similar, but with a background image for terrain and an underlying elevation map. I'm in the same situation with the lack of graphic skills though and was considering just using vector graphics.

btw, i tried the dedicated ip game and it worked fine, not sure how to capture the enemies flag or if that is implemented?

You're ideas to do terrain would be cool. And vector graphics are easy because you don't have to move and rotate a sprite with the model - just draw the model as a polygon. Also, vector graphics always look crisp once you turn on antialiasing.

The next thing I'd like to do with it is make physics. In the original version I had tanks and vehicles that you could fight in but without physics it didn't work well - like you'd be driving your jeep and then you'd glance a wall and just stop. I'd love to add physics, I just need some time to tweak JBox2D (http://jbox2d.org/) so it uses my network framework.