Rox 3D: Game Simulation Design


Greetings from GDC!  My involvement has been pretty low key so far, so I’ve had a little time to dedicate to my test game.  I’m using this game as both a learning experience, and as a test application to try various performance techniques and API features.


 


The refactoring work on Rox is mostly complete, though I’m still determining how to split up may game logic into internal and external entitiy functionality.  External classes in this case can be split into 2 distinct types: those that provide inputs into the entity data and those that strictly read from the entities.  The latter type includes the graphics and audio – they are passive elements that shouldn’t inform any aspect of gameplay.  When the world is updated events are triggered in the audio engine.   When the world update has reached a complete frame, the graphics engine reads the states of the entities and renders them appropriately.


 


Of course, nothing is quite this easy.  First there’s the issue of collision geometry.  Up until now, the game engine has retreived a simple collision sphere from the Models loaded from the content manager.  Those bounding spheres are then fed back to the game engine and the world has been scaled around the art assets.


There were a couple of ways to go from here.   The obvious route was to create a content processor that would normalize the incoming assets into something that made sense in my world coordinates.  However, remembering my desire to detach from the SpaceWar assets I have decided to remove all traces of external meshes for now.


My “asteroids” are now procedurally generated spheres.  Eventually I’m planning to alter the entire look of the game to turn them into something a little more threatening, but for now the stand-in geometry helps me quickly move into my next phase – the game simulation.


 


I now have a static Singleton class that is the center point for all game data collaboration.  The Game superclass has been pretty much stripped clean, but it will not remain that way; I plan to use the Game class to house my multithreading code.  The Singleton class has a public static GameSimulation called “server” that is the centerpoint for all game state and gameplay logic. 


I’ve decided not to differentiate between AI, physics, and animation.  All of thise kind of “internal” state logic is being handled by functions within the entity classes.


 


I’ve decided not to use an object hierarchy for my entities for a few reasons.  First, I want to use structs for many types of entities to avoid heap garbage and reduce the number of live objects in my game world by storing arrays of value types.  Next, I’m planning to have only a few kinds of entities: players, spawners, rox, projectiles, and statics.  Each has a fairly different set of priorities and variations in subclasses of object are probably best served using switch statements.


 


·         Statics are elements that don’t move during update such as large immobile obsticles and powerup items.


·         Projectiles are entities that share the common property that they have a time-to-death and they all behave the same.  There may be more than one projectile, but due to their short lives and volitiliy, I don’t plan for them to share data.  This gives me the flexibiliy to heavily optimise this system to support thousands of projectiles simultaniously in game.   I found lots of weak, innacurate projectiles to be much more satisfying than solitary, powerful weapons that fire straight forward.


·         Rox are the bad guys in the game, and will all share the same class.  Their behaviors will vary using switch statements.  The Update() part of the entity will call functions that do certain behaviors which can be used in serial to get a desired behavior.  For example, an entity that is always attempting to orient towards the player while moving straight forward would appear to chase the player.


·         Spawners make roxs.   They are very different from other classes as their setup and rox generation code is enormously more complex than their update code, wich will leave them stationary or mobile along a path.  The configuration of Spawners and Statics in the game arena determines the content of a “level”.


·         Players contain a lot of information relating to UI and other feedback to the player.  There is only ever one kind of player for this simple game, so I’m not going to rat hole my game with lots of complex capabilities.


 


Now that I have a plan, I’ll be busy turning it into an enjoyable game.  I’m not messing with graphics or sounds until I have a satisfying game experience.  I’m a coder by trade and the only person working on the game.  For me, the entity code is still a data-driven part of the design.


 

Skip to main content