Abstract
Problem: How did the Arcanum team keep the game engine separate from game-specific mechanics, and why did that matter?
Approach: Tim Cain explains the file-level and library-level separation strategy used during Arcanum's C codebase development, drawing on lessons from his earlier TIG/GNOL abstraction libraries.
Findings: By organizing code into separate C files (engine vs. game), compiling the UI into its own library with one-way data flow, and enforcing strict boundaries, the team was able to reuse the Arcanum engine to build Temple of Elemental Evil in roughly 20 months β replacing all game files and UI while keeping core engine code intact.
Key insight: The UI should never decide game state or be queried by game logic β data flows up to the UI but never back down. This one-way dependency, enforced at the library level, prevents architectural rot and enables rapid engine reuse.
Source
Keeping Engine & Game Separate In Arcanum β Tim Cain's YouTube channel.
Background: TIG and GNOL
Tim's earlier platform abstraction libraries β TIG and GNOL β established the pattern. These libraries abstracted the operating system (Windows, DOS, Mac) so game code never needed to know what platform it was running on. Each platform had its own library implementation that redirected calls to the appropriate API. The same philosophy drove the engine/game separation in Arcanum.
How the Separation Worked in Practice
Arcanum was written in C. The team organized related functions, structures, and private variables into their own C files. Some files were game-related β stats, skills, spells, combat β rooted in the Arcanum IP. Others were engine-related β sector loading, tile loading, sprite loading and animation, script loading and processing β agnostic to what game was being made.
All files were compiled together into a library (.lib), then linked into the final executable. Keeping everything in the same library meant data could flow efficiently between engine and game code. But by maintaining separate files, the team always knew which were engine files and which were game files β making future extraction straightforward.
The UI as a Separate Library
The game's entire user interface went further than file-level separation: it lived in its own folder, was compiled into its own library, and linked separately. The UI was treated as neither game nor engine.
Two reasons drove this decision:
The UI Changes Constantly
Tim describes UI coding as "the bane of my programming existence" β a tremendous time sink. UI code gets written, playtested, rewritten, and rewritten again until the original code is spaghetti. Art changes, resolutions change, platform-specific assets change (Xbox vs. PlayStation vs. Switch controller icons). None of that churn should touch game logic.
One-Way Data Flow
The UI never decides anything. It receives data from the game and displays it. The game never asks the UI for information.
By compiling the UI into its own library and not exposing its internal data back to the game, the team physically prevented programmers from making bad queries like asking the UI whose turn it is in combat. That information comes from the combat module β the UI just displays it however it wants.
The Initiative Example
When turn-based combat started in Arcanum, the combat module rolled initiative and assigned values to all participants. That data was thrown up to the UI. How the UI displayed it β a line of portraits, a single highlighted character, a big arrow β was entirely the UI's business. The game didn't care.
As turns progressed, combat told the UI whose turn it was. The UI could show that progression however it liked. If the team changed their mind about the display, zero game code needed to change.
The Payoff: Temple of Elemental Evil
After Arcanum shipped, the opportunity to make Temple of Elemental Evil arose with an aggressive timeline β 18 months (ultimately 20, partly because D&D 3.5 rules dropped mid-development, requiring a two-month rewrite of all 3.0 rules).
The separation made this possible:
- Engine: Mostly reused. A few new files were added β 2D sprites became 3D models rendered into the scene, tiled backgrounds were replaced with large 3D-rendered images with a separate depth buffer for occlusion.
- Game files: All brand new for D&D β attributes, combat, classes (Arcanum had no class system), and all associated game logic.
- UI library: Entirely replaced. The new radial menu system and different data requirements meant the old UI was thrown out completely and a new UI lib was written and linked in.
Modern Parallels
Tim notes that modern engines do this separation naturally β Unity enforces it by calling user scripts from the engine, naturally encapsulating game code. Unreal lets you modify engine source directly, which means you can stuff game data into engine code (you shouldn't, but you can). In the late 90s and early 2000s, this kind of disciplined separation wasn't common practice, and it gave the Arcanum team a significant advantage.