Download Game! Currently 100 players. Last logged in:TaikaLexelalexSolvikBauglir

Blitzer's Blog >> 72687

Back to blogs index
Posted: 22 Sep 2026 11:34 [ permalink ]
Using a filesystem hierarchy to store granular game state is a fascinating
approach. It applies the classic Unix philosophy"everything is a file"directly
to your game architecture, and it perfectly mirrors the structure of a RESTful
API URI.
Instead of treating the game state as a monolithic blob, you are treating the
filesystem itself as a document database.
This architectural choice has distinct advantages and a few critical risks you
will need to manage.
The Advantages
 * Ultimate Granularity: This perfectly solves the payload overhead problem we
discussed. If a routine only requires players.a.inventory, the middleware only
needs to read the files inside /players/a/inventory/. It never touches the
broader world state.
 * Targeted Concurrency: Because the state is fragmented into separate files,
Player A can update /players/a/inventory/item1.json at the exact same
millisecond Player B updates /players/b/inventory/item2.json without requiring
a global file lock.
 * Developer Ergonomics: Debugging becomes incredibly easy. You can inspect
the game state in real-time using standard terminal commands like cat, ls, or
grep without needing a database client or parsing a massive JSON string.
The Risks and Bottlenecks
 * The Atomicity Problem: This is the biggest hurdle. If a routine handles a
trade or an attack, it might need to delete /players/a/inventory/missile.json
and update /players/b/health.json. Standard filesystems do not support
multi-file atomic transactions. If the power fails or the process crashes
between those two disk operations, the missile is gone, but the damage was
never appliedresulting in a corrupted game state.
 * Disk I/O Overhead: Opening, reading, and closing 50 tiny files per turn
requires significantly more operating system overhead (inode lookups, file
descriptors) than reading a single 2MB file. On a network drive, this latency
compounds quickly.
 * Directory Traversal: Reconstructing the "full world state" for the client
to render requires traversing multiple directories and parsing many small JSON
files, which could slow down the response time for the frontend.
A Practical Compromise
To get the best of both worlds, you might want to raise the granularity level
just slightly. Instead of a file for every individual item, you could use a
file for every entity's core domain:
 * /sessions/match_1/players/a/inventory.json
 * /sessions/match_1/players/a/stats.json
 * /sessions/match_1/world/market.json
This drastically reduces the number of file descriptors needed per turn while
still allowing the middleware to load only the specific domains a routine
requests. To solve the atomicity problem, your middleware could write all
modified files to a temporary /staging/ directory first, and then execute a
quick shell script to move them into the live directory simultaneously.
If you use this hierarchical storage, how do you plan to handle the
client-side pollingwill the frontend request the entire state every second, or
will it only request the specific directories that have changed?