Simulator¶
Stub — no code exists yet
simulator/ contains only a .gitkeep. This page records what it is
for, so whoever picks it up does not have to reconstruct the intent.
What it is meant to be¶
A C++ telemetry ingestion service: the thing that takes event streams from game servers and gets them into Hakutaku.
It is tracked as TODO.md item 7 and explicitly scoped as a stretch goal,
not part of the core backend. It should not block anything else.
The decision that has not been made¶
There are two ways to get telemetry into the database, and the choice has real consequences:
One source of truth. Validation, timestamping and the schema all stay in the ASP.NET app. The simulator only has to speak HTTP and JSON.
Slower per event — HTTP overhead, plus whatever the server does — and it makes the API a hard dependency of ingestion.
Faster, and ingestion survives the API being down.
But it duplicates validation logic in a second language, and every schema change now has two places to update. Nothing stops the two from drifting apart.
The current lean in TODO.md is toward the API, for the single-source-of-truth
reason. Not decided.
What has to exist first¶
1. A stable event contract¶
POST /api/events exists and works today. Its shape:
timestamp is always set server-side in UTC; anything a client sends is
overwritten. data is JSON held as text, not jsonb.
See the API reference.
2. Non-admin authentication¶
This is the blocker, and it is not small.
/api/events is currently gated by .RequireAdmin(), which means it needs an
admin session cookie. A game server has no business holding one — those
cookies are minted by a human typing a password, expire after 12 hours, and
carry admin privileges across the whole API.
So ingestion needs a server-key path: a credential issued per game server,
scoped to writing events and nothing else. The planning documents mention a
server_keys table; no schema for it exists.
3. A public route¶
/api/events is not reachable from the internet — caddy/Caddyfile is
default-deny and only publishes /Health. A real game server, which is not
inside an SSH tunnel, needs a handle block.
See Caddy.
Open questions¶
- Is this a long-running service or a batch job?
- Does it buffer locally and retry, or drop on failure?
- One process per game server, or one aggregator for all of them?
- Does it need backpressure handling if the API is slow?
- How are server keys provisioned and rotated?