MonkeyZone – a jME3 game from the core
So I wrapped up my ideas and started off with a blank BasicGame project in jMonkeyPlatform and one week later I already had a first version of a game including networking running. Yes, one week. I was baffled myself about how efficiently and fast one can write games in jME3. In that one week I got more done than in one full year messing with jME2 RenderStates Have a look at the first results:
It looks very simple and plain but in the background most of the system detailed below is already implemented and the best thing is the design makes it possible for others to edit maps, vehicles etc. in jMP w/o changing the code, allowing designers to contribute easily, if you feel like contributing assets or working on parts of the game code, drop me a note!
So keep your eyes open for updates and news and in the meantime read about the game implementation details below.
Table of contents
- The Game
- Implementation Details
- Manager Classes
- Use of Controls
- Artificial Intelligence
- Use of jMonkeyPlatform tools
- The Future
Since the time I started working with jME I always wanted to create a game like Activisions “BattleZone” from 1998. This was actually the initial reason I started working with jbullet physics and because the idea was floating around for some time its also the reason why @nehon created the awesome HoverTank model. BattleZone was a FPS game with RTS elements or vice versa, however you want to look at it To get an impression of the original game, have a look at some gameplay of the original version.
MonkeyZone is a physics-based networking game. Both clients and server run the physics simulation, the clients send input data from the human and AI players to the server where they are used to control the entities and also broadcast to the clients. Additionally the server sends sync data in intervals for all objects in the game to prevent drifting.
When a human user or an AI presses a button/performs an action the actual logic is done on the server and the results are broadcast as data messages for the entities. When the entity is controlled by an AI the actual AI code that determines where the entity should move and when it should perform an action is executed on the client.
Note that the way MonkeyZone is implemented is just one of the many possible ways to do a game like this in jME. Some things might be done more efficiently, some might be done in another way completely. MonkeyZone tries to do things the way that are most appropriate to implement the game at hand and it shows nicely how jME3 and the standard Java API can make game development easier and faster. Also note that the way MonkeyZone is designed is not scalable to a MMO style game, it will only work in a FPS style environment where the whole game world can be loaded at once.
The game uses certain terms that might be familiar to you but maybe used in another way, so heres a quick rundown on the terms being used.
PlayerLogical human or AI player that can enter entities and generally act, only exists as PlayerData “database” with an id.EntitySpatial with UserData, a world object like character, vehicle, box or factory. The base form is defined only by a String pointing to the j3o which already has all userdata like hitpoints, speed etc.UserHuman player using clientGroupGroup of players that play together (human and AI), for now thats the same as client_id of human player for all AIControl’d players originating from that client.ClientComputer connected to server
The WorldManager does the main work of organizing players, entities and the world and synchronizing them between the server and client. Both client and server use this class. Some other managers like ClientEffectsManager only exist on the client or server and manage e.g. effects display.
The gameplay is largely controlled by the ServerGameManager which does gameplay logic on the server, combined with the actions issued by the AI and user on the client (see below) it implements the gameplay. It extensively uses the functions exposed by the WorldManager to perform actions and gather data. This is also the class where the actions of the players are actually executed on the server to determine the outcome (ray testing for shooting etc.).
Use of Controls
Controls are used extensively in MonkeyZone for many aspects of the game. When a player enters an entity the Spatials Controls are configured based on the player that enters. For example when the human user enters an entity, Controls that update the user interface (DefaultHUDControl) or user input (UserInputControl) are added to the current entity Spatial.
As entity capabilities
Controls attached to Spatials are generally used like an “array of capabilities” that the entity posesses. So when an entity has a VehicleControl its expected to be a vehicle, when its got a CharacterControl its expected to be a character.
Other Controls work completely on their own, like CharacterAnimControl which just uses the CharacterControl of the entity to check if the character is running, jumping etc. and then animates the entity if it has an AnimControl.
Furthermore theres special interfaces for Controls that allow abstraction of different Controls into one base interface. For example ManualControl and AutonomousControl are interfaces for controls that manage the movement of a spatial in a generalized way. This way AI code and e.g. the UserInputControl only have to check for a valid AutonomousControl or ManualControl on the spatial to control and move it. The details of the movement are handled by classes like ManualVehicleControl and AutonomousCharacterControl.
For AI functions
A special Control called CommandControl handles the Commands that can be executed by user controlled players, see below.
MonkeyZone includes simple AI functions based on a command queue.
To implement autonomous AI players MonkeyZone uses a system of Commands that are managed by a CommandControl that is attached to each AI player entity controlled by the user. This CommandControl manages a list of Commands that are executed based on priority. For example theres a MoveCommand, a FollowCommand and an AttackCommand, Commands can however implement more complete behavior than that, e.g. the complete logic for a scavenging entity.
The SphereTrigger is a TriggerControl that is also attached to each AI players current entity. It consists of a GhostControl that checks the overlapping entities around the entity its attached to. It can be assigned a command that is checked with every entity entering the SphereTrigger and executed if applicable (e.g. normal “attack enemy” mode).
For each map a navigation mesh is generated that allows the entities to navigate the terrain. Autonomous entities automatically get a NavigationControl based on the current map. The AutonomousControl implementations automatically recognize the NavigationControl attached to the Spatial and use it for navigation. The NavMeshNavigationControl implementation contains a reference to the levels NavMesh and implements a navigation algorithm similar to the A* algorithm.
Networking is realized in the PhysicsSyncManager which we hope to extend to a state where it can serve as a general sync system for physics based network games.
The sync manager basically puts a timestamp on every message sent from the server and then buffers all arriving messages on the client within a certain time window. This allows to compensate for messages arriving too soon or too late within the constraints of the buffer, a future version might step the clients physics space different to compensate for network delays without “snapping”.
Use of jMonkeyPlatform tools
All assets used in the game, like entity models and loaded maps can be preconfigured and edited using jMonkeyPlatform. For example, to add a new vehicle type, a vehicle is created in the jMP vehicle editor and UserData like Speed, HitPoints etc. is applied directly in the editor. When the model is loaded in the game it is automatically configured based on these settings, the same accounts for maps that are loaded, special Nodes that mark e.g. player start locations are recognized automatically etc.
Entities that are loaded from disk have certain UserData like HitPoints, Speed etc. that is used to configure the entity at runtime. jMP allows adding and editing this UserData so entity properties are editable visually.
VehicleControls, CharacterControls and RigidBodyControls with mesh collision shape for terrain and objects are generated in jMP and saved in the entity j3o file. When an entity is loaded, the type of entity is identified based on the available controls and UserData and it is configured accordingly.
I hope to get to talk about MonkeyZone some more when it gets more mature, for now have a look at the code and feel free to ask about it, if you want any new features, you are free to implement them
MonkeyZone is hosted at GoogleCode, where you can checkout the jMonkeyPlatform project via svn:
Team->Subversion->Checkout and enter the URL http://monkeyzone.go....com/svn/trunk/
After downloading and opening the project, run a server first and then a client.
The jMonkeyEngine Team