This is a list of features that a modern 3D game engine should have, with indicator of whether World Foundry
supports this feature completely (YES), partially (PARTLY), or not at all (NO). Details can and should be added to each entry.
Executive summary: World Foundry
is strong in toolset and deployment, meaning the actual production of a real game (including evolutionary issues - ease of changing game object attributes over time - as well as tools for designers, and deployment issues) is very well supported. Many common game behaviors (objects moving on paths, object generators, weapons, platforms) are already programmed and can be easily included. World Foundry
is mainly geared towards indoor platform-type games. Racing games also appear suitable. Vast outdoor areas are probably difficult but can be faked with lots of statplats and suitable geometry.
is weaker in rendering and its physics system is simple (but usable for a wide class of applications not requiring fully simulated rigid body dynamics). Level layouts must also currently be mostly linear (one room after another, though within a room nonlinear branches can occur).
Animation of 3D game objects
- Script-controlled animation: YES
- Physics-controlled animation: YES
- * Only uses AABB for collision, simple impulse-based model
- * Need to add rotation, full rigid body support, constraint-based physics
- * "Handler"-based approach
- Path-controlled animation: YES
- Particle-system animation: YES
- Character-animation: PARTLY
- * Mesh deformation
- * No real-time IK or skinning
- * Animation blending (e.g. 25% of walk animation, 50% of draw-gun animation, 25% of sneeze animation)? Probably not possible (?).
- **KevinSeghetti -- the engine cannot currently blend animations, but since it uses deformation animation, and the deformations are stored as deltas (I am pretty sure, easy to change if not), then more than one deformation animation could be applied to a single render object (order of application would be important, of course). Note that Sony claims to have a patent on some variation of this, since I have an old NDA with Sony it would be best if someone else wrote the code to handle this.
- * cal3D library is a GPL library for charater animation - maybe it could be used. It supports real-time skinning, IK, animation blending, etc.
Visibility determination / scene graph
- Arbitrary scene layout: PARTLY
- * Logical progression from "room" to "room" must be linear, though within one logical room physical sub-parts can be non-linear; allowing room-dividing walls to intersect room boundaries allows for a larger form of nonlinearity, see next note.
- **KevinSeghetti -- Note that it the logical rooms that must be linear. WF Rooms are what is used to allow more graphics than fit into video memory to be used in a single level. They are also used to partition the world so that we don't try to execute everything all of the time. So it is possible to make levels which appear to have some non-linearity to them, like 2 separate hallways from a room which run in parallel and each go through several small rooms before meeting up again (this would be done by having both branches be contained in one larger WF Room (I see now that Room was a bad name for the partition space, too easy to confuse with the visible rooms in the level). Example: at point X the user appears to have a non-linear choice of rooms to go to, whereas in actuality he is choosing between (parts of) Room1 and Room2.
- Support for variety of visibility schemes: NO
- * Portals, octree, view frustum culling, BSP traversal
- * The question is if it is possible to support multiple traversal schemes in a general way while still freeing the programmer from the burden of writing the traversal completely manually. For instance the Nebula Device provides no traversal scheme, meaning you are free to add any traversal scheme, but you have to write it yourself and integrate it into the main game loop (which, in Nebula, you also have to write).
- * Simple support for non-linear levels (see Idea For Non Linear Levels) could alleviate much of this concern and is probably general-purpose enough for many cases.
Game tools and middleware
- Very good support in WF, add details here (attribedit, evolutionary system when new attributes/classes are added, more than just a raw 3D engine)
Interaction with the game world
- Player and enemies can push objects around: YES
- * However physics is all AABB based
- Player knock over objects: NO
- Player can stack objects: ???
- * Possibly, since AABB collision model is easier, there is no "resting contact" issue which is a problem in full rigid body simulations for box stacking. However there is some unresolved issue about "chain of execution" issues or pushing boxes through other boxes because of incorrect propagation of impulses, or something like that.
- * Example question. Say there is a box on the floor, and a box (apparently) suspended from a rope on the ceiling, positioned over the first box. By shooting the rope the top box falls down onto the second box, making a climbable platform high enough to solve some puzzle. How could this be done in WF?
- Climbing on objects: YES (Climb Handler?)
- Stepping over objects: YES
- * Can specify max height that the player can "step" over
- Explosions can send objects flying: ???
- Player moving through water: PARTLY
- * Can make a new physics movement handler
- Vehicles: YES (see Cook Book)
- Player can pick up weapons: YES
- * More about weapon support? Types of weapons, how to aim, how damage is calculated?
- Gold/Economic units: YES
- Player shield: YES
- Spikes: YES
- Static and moving Platforms: YES
- Keys/Collectable artifacts for game flow: ???
- Particle systems: YES
- * Both object-generators as well as pure-geometry-generators (for smoke, fire, etc). The latter has not been tested well.
- Multi-pass rendering: NO
- Material properties (reflectance, etc): ???
- Alpha channels: YES
- Dynamic lighting: YES (uses Open GL? lighting)
- Lightmaps: NO
- Shadows: PARTLY - Crude, objects which follow other objects around
- Lens flares: NO
- Sky box: NO
- Fog: YES (Fogging is just mixing in a different color as objects get further away from the camera, in the superhero level the mixin color is set to black, so things just fade away, but the engine supports any color. See attribute Fogging Color? of the Camera type).
- Scrolling matte background: YES (for Play Station?, must be re-implemented for Linux/Windows builds)
- Sprites/billboards/scarecrows: YES
- Visualizing collision geometry: YES (edit wfsource/GNUMakefile.bld)
- Environment mapping: NO
- Bump mapping: NO
- Streaming data dynamically from CD-ROM: YES
- none. Engine is designed to be entirely deterministic, so there is currently no support for revisionist history. Therefore currently the only posibility would be to run all clients frame-locked, so would only be feasable on a LAN.
- * Kevin Seghetti - I haven't really seen any complicated games do anything better, all of the revisionist history games I have seen are like Doom, with few moving objects, not much game state.
- * Mr Lin - Possible hack using dead reckoning. Assume a client/server model - one instance of the game engine is a "server" to which other clients connect. A client must receive frame-locked updates from all networked players before he is allowed to move. If the server registers no input from a client he is assumed to be temporarily lagged and the server dead reckons (extrapolates) his movement, and that is considered to be his "true" position. Fake joystick inputs are generated for the lagged player to give the extrapolated position, and these fake joystick inputs are sent to all other non-lagged clients. During the lag, the lagged player's client switches off all physics, AI, and any change in gamestate. But the lagged player is allowed to "run around", i.e., change his position and orientation, but not change anything (including not changing his current room for instance). This allows for a limited form of apparent interactivity during lag (but everything, including falling objects, etc, is "frozen in time" Matrix-style for the lagged player). When the server detects that the lagged player is again connected, the server's extrapolated position for the lagged player is taken as the real position, and the player is dragged back (over several frames) to the server-computed position (which hopefully is not far from the real position due to the server-side extrapolation of movement), and the gamestate-changing-joystick-inputs from other players, which the lagged client has not yet received, get sent down the line to the lagged player. Thus, everything is back as it was, and all clients are again frame-locked. Comments?
- ** Freezing everything except player movement for the lagged player during lag is necessary because of the richness of WF game state. For instance one input can cause a tiny change in an object's acceleration which causes totally different physics behavior which moves the object to a new position which sets off a trigger which activates a script which changes a mailbox which starts a timer which sets off an explosion - if that input is not sent to a lagged client, trying to blindly continue running the engine on the lagged client can lead to massive differences in game state which need to be synchronized (all changed position, all changed mailboxes, all changed ANYTHING). Simpler game state such as only keeping track of a few players' positions makes such syncing easier (and is the basis of the above comment about Doom being more amenable to revisionist history). By freezing everything during a lag we are not revising history, we are dictating the future on the server by extrapolating the lagged client's movement and saying "that is what you did this frame, whether you know it or not." When connection is reestablished, the only thing which might have changed is the player position and orientation, which, as mentioned above, are dragged back to their old position and the queued, lagged inputs from other players are all then processed, leading to exactly the same game state again across all clients. In theory.
- ** The sudden arrival of several queued inputs on the lagged client's machine after reestablishing connection can cause an abrupt change in gamestate, with abruptness increasing as the down-time for the connection increases. One solution is to playback the queued inputs not all at once then do one frame update, but to play them back incrementally over a period of time proportional to the lag (e.g. if connection dropped for 10 seconds, playback all queued inputs over 3 seconds and 60 frames, only after that point can the player again change game state). This has the same end effect, but allows for some visual feedback of what happened during those 10 seconds (albeit played back in fast-forward in 3 seconds on the lagged client).
- ** During lag-time, the player can also be restricted to move around only in a small "cage" so that it is clear to the lagged player that he is lagged - yet he does not feel completely helpless and annoyed because at least he can turn around and move a tiny bit inside of his cage. In the most restrictive case the cage could be zero-size, meaning the player can spin around and look but not move at all during lag. The server of course also has to know about the cage size so it doesn't dead-reckon the lagged player's movement outside of the cage. The cage is an error-limiting device during lagtime which still allows limited interactivity. I think Rainbow 6 uses this approach.
- Single-file deployment of game: YES
- * Fully supported; the build system compiles all game assets into one cd.iff file, which is then read by the game engine at run-time.
- deterministic, always records user input and time stamps, so the programmer can always re-create a run exactly.
- engine contains a LOT of assertions, problems are usually caught near their source
- test suites: each library has a stand alone test program, by adding tests for bugs as they are found a regression suite is formed
- debug stream system: Every sub-system in the engine has a C++ stream it writes debugging information to. By default most of these streams are sent to a null stream, but each can be set on the command line to go to cout, cerr, a file, or a window on the monocrome display (windows only)