This project is an eternal work in progress.
Code is here.
This time I wanted to do something real and usable for real games. The examples are a bit on the ugly side (lots of programmer art!), but my intention was always to concentrate on the code. Here are some of the current features:
- Written mostly in ANSI C, with a few C++ bits;
- Client-server model for both single player and multiplayer with client-side prediction for latency hiding (only for the player or full client-side world simulation and reconciliation);
- Asynchronous player input for even lower network latency;
- Bullet physics engine fully integrated with various object types, including four-wheeled vehicles;
- Clear modularization: host/core, client, server, system (for easy porting), client game and server game. Dedicated servers are trivial;
- Client game and server game modules make it easy to create any type of game without having to modify the rest of the engine, everything can be changed: from server entity scripting to client input and HUD. Custom game-specific network messages are supported;
- Quake 3 BSP maps supported with features like PVS, tracing, light volume direction for model lighting, etc, supported;
- Network code supports reliable and unreliable messages, both via UDP. Differential snapshots (interpolated at the client side) for the game state done through the unreliable messaging system. Cross platform play supported. (example: PC playing against Android);
- Entities are event-based: spawn, touch, think (timed ticks), use;
- Spatial sound via OpenAL;
- OpenGL 3.x+ renderer with realtime lighting and shadows, capable of z-sorting where necessary;
- Voxel support (currently realtime for a few dozens of millions of voxels, needs physics optimizations);
- Inter-Quake Model (IQM) support for 3d models, with animation blending with weights (for blending different animations) and animation masks (for having different animations controlling different bones);
- Quake 1 MDL and Quake 2 MD2 support, with frame blending. Added mainly for being an easy source of test models that need no set-up;
- In-engine console for entering commands and changing variables, with tab-completion and command history, along with limited scripting support (waiting a certain number of frames, for example);
- Heightmap support with smooth transitions between textures based on height and/or masks. Level-of-detail (LOD) supported;
- Various culling methods (using frusta and occlusion queries), for renderer and CPU optimization, including culling for the lights’ POV. Also culling from the server side with PVS to lighten the network traffic;
- Particles and sprites/billboards;
- Very easy porting, currently runs on Windows, Linux and Android, so porting to other systems should be straightforward;
- Support for saving/loading the game at any point;
- Game code can be either in C or in Lua. Both interfaces are maintained;
- Independent update rate for game logic, network and video.
Still missing, but planned:
- Material support. Currently only diffuse surfaces and sounds per model.
- Still need to create support for Quake 3 BSP cpu shaders and contents/surface flags other than solid, empty and water;
- Need to expose to the game code the joint system for bullet bodies;
- Some legacy code using fixed function GL (like the physics debug lines);
- Need for fix some endianness issues (almost everything is assumed to be little-endian);
- Need to use the already implemented player unique identification for reconnect after timeouts without losing data and saving multiplayer games.
In its current state, it’s very usable. I’d say a game like Quake 3 could be fully implementable.
The best part, for me, is the entity system. This makes the server game work the way I like and makes me very productive. I can implement any gameplay feature I want very quickly and cleanly!
Here is a slightly outdated paper describing the engine in detail, written in brazilian portuguese:
Engine Paper (2017/03/10) (removed until I update it)
In the screenshot: and old test version with a sample Quake 3 BSP Map is loaded with two clients connected. The player model was a 2D sprite and the collision shape was a capsule. The engine instance which runs the server also has the capability to draw debug lines representing the physics shapes and bounding boxes in the physics engine.
This test game had a working status bar, some weapons, one enemy, items, triggers, multiplayer, doors, buttons, voxel manipulation, sound effects and other stuff.
In the screenshot: A voxel world so big (running in real time, white mountains not hollow) that the two players can’t even see each other.
In the screenshots: dynamic lighting and shadowing. On the last one the effect of additive light blending can be seen. Z-sorting wasn’t implemented for transparent entities at the time of this screenshot, as can be seen with one sprite being drawn on top of a nearer one.
In the screenshot: cross-platform play between Windows PC and Android (with the android emulator, to make it easier to see.)
In the screenshot: console example.
In the screenshot: heightmap example.
In the screenshot: mixing heightmap with a sealed BSP map to test physics and rendering, everything went well (except for the fact that the sealed BSP map had no outer faces, but that was expected).
In the screenshot: two test animated IQM models, one as an enemy and one as a weapon view model.
In the screenshot: testing heightmap level of detail from several kilometers away.
In the screenshot: heightmap + voxels + vehicle from the point of view of a remote controlled missile fired by the player who is on top of the vehicle. (Just like the weapon Slayer from Perfect Dark(tm) on the Nintendo 64.)