Multiplayer top-down view shooter

Hi

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 :slight_smile: The only things holding it back are my artistic and 2D (let alone 3D) graphics skillz. Requires java 5 or better.

http://www.keithwoodward.com/sydneyengine/SydneyEngineDemo.jnlp
Controls: WASD to move, mouse click to fire, mouse wheel to change weapon. page up/down to zoom. tilde for player hit points and r for reload.

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).

Here’s the source: http://www.keithwoodward.com/sydneyengine/

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? 8) :slight_smile:

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 :slight_smile:

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.

Neat!

Also, your networking approach sounds very similar to Trailing State Syncronisation, have you seen it?

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, 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. 8)

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 :slight_smile:

Hey has anyone got any cool ideas for extra weapons? Right now there’s the pistol, flamethorwer, shotgun, machine gun, sniper rifle and ballistic rocket launcher (which doesn’t explode).

Thanks for the comments!

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?

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):

http://gamepipe.usc.edu/~zyda/courses/ZydaNetworkedGamesFall2005/NetworkedGames.html
http://staff.cs.utu.fi/~jounsmed/mcg_05/

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 :slight_smile:

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.

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

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.

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.

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 :slight_smile: 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 8)

I’m curious as to why it’s called the SydneyEngine ?

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?

Neat!

It works at least in singleplayer.

I have made a very similar game (except no network code, single player roleplaying game instead).
Take a look at:
http://gunslinger-game.mine.nu/

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.

Thanks again Riven, access to the server will make for a proper lobby and internet play 8) woo!

Cheers. You can test out the multiplayer aspects of it by running two versions of the game at once - just click the jnlp twice and then create on one, and then join on the other.

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 :slight_smile: Thanks a lot Markus

Well one day it might be a proper engine, and the Sydney part is just because that’s where I live! (as in Sydney, Australia)

Thanks heaps for the incredible support and comments everyone :smiley:

G’Day mate!
Guess I’d better make a start on my PerthEngine then… :wink:

lol and i should rename my current engine to AdelaideEngine :stuck_out_tongue:

lol, such a small world. Well hello fellow convicts :slight_smile:

Remember to say hi the next time you’re passing by Sydney, it’d be great to meet

rock n roll. very nice!!! loved shooting around, though had no one to shoot.

(haven’t read all posts, so i don’t know what hints have been given)

Two points:

  1. Add minimap
  2. Let player slide along walls

Smooth!
Just had a quick play, no-one else on, so I simply walked around shooting aimlessly…loved the flame-thrower!!

suggestion:

  • some BOTS!

Hi,

There’s a dedicated server game running in Amsterdam, The Netherlands (big thanks to Riven)!! as well as a central lobby from which you can join this game. I’m in there now, come and join up!!!

There’s also some bots which are pretty darn good aimers. To change the number of bots, type in numbots = x (where x is between 0 and 9) in the chat text field and press enter.

I’m looking forward to blast some of you guys to smithereens! :smiley: ;D 8)

Webstart: http://www.freewebs.com/commanderkeith/sydneyengine/SydneyEngineDemo.jnlp

Source: http://www.freewebs.com/commanderkeith/sydneyengine/src.zip
Jars needed in claspath: http://www.freewebs.com/commanderkeith/sydneyengine/SydneyEngineDependencyJars.zip