Rethinking Game Architecture with Immutability Jacob Dufault Faculty Advisor: Dr. Phil Bernhard, Dept of Computer Science, Florida Institute of Technology Overview Taking inspiration from functional programming, a new game architecture/framework has been developed and tested that heavily uses immutability. This introduces a large number of benefits not otherwise possible. A game is composed of a set of entities and a set of systems. The entities declare what data they contain with no logic about how that data interacts with the game world. Systems declaratively specify what types of entities they are interested in (for example, only those with a Position and a Velocity) and describe how those entities should operate in the game world. The data inside of entities is immutable per game update. Immutability Gains Update Order Independence Systems process entities and contain all game logic. Bugs are easily introduced because these systems have implicit state regarding their execution order. By introducing immutability, systems can execute independently of one another as there are no changes in game state per frame. This allows for systems to execute in multiple threads automatically, a feature which has been implemented. Deterministic Simulation Multiplayer real-time strategy games have too many simulated entities to send the state changes across the network. Instead, the game is treated as a simulation with each computer simulating the same end result. Multithreading introduces execution order ambiguity into the simulation state, making it seem incompatible with determinism. But if all content that derives the next frame is immutable for the entire frame, then execution order is no longer relevant – the same state will result every time. Minimized Coupling Entities are automatically registered into systems. Systems declaratively specify what kind of entities they are interested in. Entity data is not tied to any particular system. Systems can be ignorant of the rest of the world and only consider their local state. Architecture Gains Unified Serialization Pipeline All games need to save levels. Serialization is cleanly integrated into the entity framework; only simple object annotations are required. Starting a new game is identical to loading a saved game. Replay Support Since the simulated game is deterministic, only input needs to be recorded to replay the game. This allows for a simple replay format with minimal storage size. Generic Rendering with Interpolation The entity system is rendering engine agnostic and exposes APIs as necessary to easily hook into an arbitrary rendering engine with a powerful event system. Renderers for both Unity and XNA have been written. Each entity contains three sets of data instances, split up into a previous, current, and future group. The previous and current groups can be read from, while the future group can only be written to. Runtime allocation and copying is minimal. This architecture neatly allows for interpolation between update frames, a key facet to achieve a believable game where units move smoothly. Architecture System API Entity Filter Triggers Input Filter Entity Design Metadata Data Instance Runtime Implementation Content Implementation Serialization Entity Framework Rendering Engine Unity XNA/MonoGame Unity Editor Game Content Entities/Templates Renderer Specific Content Systems Source Code Framework is at github.com/jacobdufault/forge under the MIT License See also github.com/jacobdufault/forge-unity for the Unity bindings See also github.com/jacobdufault/forge-sample for the sample game