Monkey Trap

So, about four weeks ago I started writing a “simple” maze RPG rougelike using whatever existing models and stuff I could find. This was supposed to be kind of an example of a more complicated ES-based game than Asteroid Panic while also making a good framework to implement networking.

…then the project kind of took on a life of its own and became a way to test a bunch of ideas out. I should have guessed that when after the first two nights I already had a title screen and had written some ambient music that I wasn’t going to settle for stupid-simple. :wink:

Anyway, the single player game is finally functional to the point where I’m going to start working on the networking. It’s not a “game” yet, really, but it has all of the engine parts necessary. It only misses the actual combat resolution piece and that AI actually attacking the player.

You can see a video of the current version here:
[video]http://www.youtube.com/watch?v=7PUYgXQfl_E[/video]

You can pretty much just run around exploring and bashing things… collecting temporary and permanent power-ups as you go. The power-ups are not currently applied to combat strength because the real combat rolls are not implemented.

The game follows a pretty typical sort of “turn based” mechanic but then applies real time input on top of that. I remember when Bioware first did something like this for Neverwinter Nights reading some articles on how tough it was… and I now understand the full depth of their pain. At any rate, for a “dice rolls” style of RPG splitting things into turns and actions sort of becomes necessary… but moreover I was going for a more Rogue-like mechanic than a real-time shooter mechanic. It works better with networking to not have to work about FPS-style twitch… and dice roll style RPG combat is good for that (which is why pretty much every one of them does it that way).

The code is still a bit “raw” but if you are curious you can find it here:
http://code.google.com/p/jmonkeyplatform-contributions/source/browse/trunk/zay-es#zay-es%2Fexamples%2FMonkeyTrap%3Fstate%3Dclosed

Or if you just want to download and play with it, you can get releases here:
https://jmonkeyplatform-contributions.googlecode.com/svn/trunk/zay-es/examples/MonkeyTrap/release/
…or to save you some clicking:
Windows: https://jmonkeyplatform-contributions.googlecode.com/svn/trunk/zay-es/examples/MonkeyTrap/release/MonkeyTrap-Windows.zip
Linux: https://jmonkeyplatform-contributions.googlecode.com/svn/trunk/zay-es/examples/MonkeyTrap/release/MonkeyTrap-Linux.zip
Mac: https://jmonkeyplatform-contributions.googlecode.com/svn/trunk/zay-es/examples/MonkeyTrap/release/MonkeyTrap-MacOSX.zip

Obviously not much platform testing has been done so I will be pleasantly surprised if it doesn’t blow up.

Edit: Update… new release was posted with networking. This post has more details: http://hub.jmonkeyengine.org/forum/topic/monkey-trap/#post-248034

…code is still very raw.

13 Likes

For fun, here is also an animation tester app (also embedded in the game code) that I used to test the animation sequencing:
[video]http://www.youtube.com/watch?v=7BefBUzBdbc[/video]

When combat is done, the dice rolls will determine hits/misses/dodges/etc. and the appropriate animations run.

1 Like

Hey @pspeed,

This example is very valuable for one who just start with game making. Welldone, very welldone!

Cool! :slight_smile:
I am particularly interested in this fog/discovery system, as it happens in so many games. I see that the map is not known to player prior to discovering it, but later when some part is discovered and the player avatar is not there, it is just “fogged” but still present.
I am interested on how to implement that for a multiplayer game, because basically each player would then need to have its own representation of the world that would get synced with his/her client. Ok maybe for such discrete world isn’t so much of a problem, but how would this be done in case of lets say AOE style of a world is still a mystery to me. Would be nice if someone could explain the basic idea behind. :slight_smile:

@InShadow said: Cool! :) I am particularly interested in this fog/discovery system, as it happens in so many games. I see that the map is not known to player prior to discovering it, but later when some part is discovered and the player avatar is not there, it is just "fogged" but still present. I am interested on how to implement that for a multiplayer game, because basically each player would then need to have its own representation of the world that would get synced with his/her client. Ok maybe for such discrete world isn't so much of a problem, but how would this be done in case of lets say AOE style of a world is still a mystery to me. Would be nice if someone could explain the basic idea behind. :)

In this case, each client will already have their own copy of the maze that is just an n x n array of ‘cells’. I create a parallel array of cells that contains bitmasks that keep track of what the player has seen and what they can see right now. I use this to tint the mesh with a runtime generated texture (I do it as an overlay mesh but it could have been a lightmap, too).

I will also (someday) use this to show what the ogres/other players can see tinted as red or something. Eventually I want one of the power-ups to be some kind of perception potion that lets you know what parts of the maze can be seen by others. For when you want to be sneaky.

That’s all on the client, though.

I will do something similar to keep track of monkey smell in the maze to give the ogres a fighting chance at tracking. Just a ‘long’ in each cell saying what the last game time a monkey was there was. The AI could then use recent game times to track the monkeys/players.

Anyway, for a larger world I don’t think the problem is any harder. You already have world data so you just pick some granularity of resolution for keeping track of where a player has been… either you keep it cached on the client or you store it in compact data structures (recommend RLE bit strings, personally).

1 Like

Hmm, but why is this all on the client?
Wouldn’t it be better for authoritative server to send out to the player what he/she has just discovered/can see?

@InShadow said: Hmm, but why is this all on the client? Wouldn't it be better for authoritative server to send out to the player what he/she has just discovered/can see?

The client already has the whole maze to build the mesh. They know everything so there is no point in keeping it on the server.

Ok, but regarding that the client knows everything, the player would then be able to cheat and somehow hack the game to show him the whole map already at the beginning? :slight_smile:
If true, the “proper” solution would then be to dynamically generate mesh on the client when message from the server is obtained? Would like to clarify if I understand these problems correctly … :slight_smile:

@InShadow said: Ok, but regarding that the client knows everything, the player would then be able to cheat and somehow hack the game to show him the whole map already at the beginning? :) If true, the "proper" solution would then be to dynamically generate mesh on the client when message from the server is obtained? Would like to clarify if I understand these problems correctly ... :)

Yes… then you deal with regenerating the mesh every step, etc… and dealing with the overlap of what was seen last so that it fades to what is seen now. But that’s the gist of it. The complexity did not seem worth it in this case. The client syncs the full world so “knowledge” cheats are trivial for a Java hacker. Game cheats are secure, though, as the server is authoritative for the game logic.

Thank you for your time and effort! :slight_smile:

Other random little things that might be of general interest:
-I used my drop-shadows filter to do the shadows for the objects.
-I have a tweaked lighting shader to do the glass objects (three lines added to standard lighting). That’s what I used for the potion bottles.

The DropShadowFilter and related materials can probably be dropped right into most games directly. It works off of the standard JME Caster shadow mode. Sometimes it will work as is since it uses the casting object’s bounding box… but in Monkey Trap I found for a lot of the objects I had to create and attach an invisible Box mesh to make the real caster.

@pspeed said: For fun, here is also an animation tester app (also embedded in the game code) that I used to test the animation sequencing: [video]http://www.youtube.com/watch?v=7BefBUzBdbc[/video]

When combat is done, the dice rolls will determine hits/misses/dodges/etc. and the appropriate animations run.

The dodge animation might look better if they ducked backwards or something, Right now it doesn’t really stand out from anything else :slight_smile:

@zarch said: The dodge animation might look better if they ducked backwards or something, Right now it doesn't really stand out from anything else :)

Using stock models. I have not modified the animations at all nor would I even begin to know how. You are welcome to add animations to Jaime and Sinbad if you like.

So, I’ve just uploaded a new release of Monkey Trap… now with more networky goodness. The animation is extra-glitchy in the networked version and I haven’t had time to track that down yet. The same problem occasionally happens in the single player version too but something in multiplayer really pokes at the underlying problem.

Anyway, it’s functional and shows that the ES networking is working. I’ve taken too much time off of my other projects while working on this so I’m not sure how deeply I will look into it or how soon. It is kind of nagging at me, though.

The server can be started from the command line by invoking the following command from the directory where you’ve unzipped the game:
java -cp MonkeyTrap.exe trap.server.GameServer

(or on Linux replace MonkeyTrap.exe with MonkeyTrap.jar, etc. I don’t know how you do it on Macs but I would hope it’s similar.)

Then you should be able to connect to it running the regular client and selecting the multiplayer options.

Important notes:
-there still really isn’t a “game”… you can wander around the maze and beat on stuff, collect loot, etc.
-the buffs you collect still don’t affect how hard you can hit or anything. No real combat rolls have been implemented yet.
-if suspect if one player kills another one then very strange things will happen on the client of the dead player. I haven’t tried it.

Download links are the same as above.

Just curious:

You seem to use service and appstates - what seperates them from each other ? Seems to me they are interchangable (in function and how they work).

@asser.fahrenholz said: Just curious:

You seem to use service and appstates - what seperates them from each other ? Seems to me they are interchangable (in function and how they work).

App states require a JME Application or SimpleApplication base… which I find distasteful to use on the server… what with all of its rendering-specific apparatus and so on. I know I can run it in headless but it’s not buying me anything at all.

Right now, all the server needs from JME is the networking and jme.math (there are days I really wish this were a separate jar. ;)). This pleases me.

So, app states where app states live… on the client. Regular Java code on the server and a greatly simplified service model. As a bonus, I get to use a time format that makes more sense to my game logic. Especially for long running games, using float to keep a game time will start to lose precision in just a few days (I think it starts to drop the small decimal places at 18 hours).

Edit: also as an illustration goes, there will never be any mistake which management classes are client-side and which are server-side. Also note: I would have called them “systems” but that’s a bad word to me as it is overused and used improperly for Entity Systems. So I’ve struck the word.

Also note: if I were using bullet on the server then I’d just grit my teeth a little and go ahead and base my server on a headless Application. It’s just easier.

Though important to remember that Application doesn’t run the app states for you for some reason so you have to specifically call stateManager.update and so on.

Hello @pspeed,

I’ve just tried to run Monkey trap and …

Single player or multiPlayer are the same…(multi screenshot here)…no error message… just a full screen normal map and player infos on the top left corner :wink:

I’ve dl the Windows version, and my computer is running a Windows 7 64Bits…anyone else on Windows have the same problem?

@haze said: Hello @pspeed,

I’ve just tried to run Monkey trap and …

Single player or multiPlayer are the same…(multi screenshot here)…no error message… just a full screen normal map and player infos on the top left corner :wink:

I’ve dl the Windows version, and my computer is running a Windows 7 64Bits…anyone else on Windows have the same problem?

Bizarre. I’m going to go out on a limb and guess that you have an ATI card? :slight_smile:

Do the JME post processing tests work for you?

@pspeed said: Bizarre. I'm going to go out on a limb and guess that you have an ATI card? :)

Do the JME post processing tests work for you?

Yep strange enough, i know…why this texture is splat here :S
And nop…no luck with me…i’ve a Nvidia graphic card…a 560 GTX model to be exact.

I’ll re check the post processing tests and i’ll edit this post with the results but no problem for now with those i use.
I’ve planned to checkout the Zay-ES source code (need to study it a bit :wink: )…i’ll take monkey trap source in the same time…if i can investigate a bit…