Docs/Realms/DarkerDB

DarkerDB

A community data realm for Dark and Darker, hosted as part of the KATFORGE API. All observation data lives in katforge.darkerdb.* schema alongside the other realms (stumper, lextris, gear_goblins).

The public surface is api.darkerdb.com/v2/* and identically api.katforge.com/v1/realms/darkerdb/* — same Symfony controllers, same DB, dual mount.

The complete API reference lives at API Reference → DarkerDB. Everything below describes the realm itself: how data flows, what feeds it, what the schema looks like.

What's in it

Two data sources feed the realm. The Ghost bot owns writes through a dedicated DB role; the API runs on a SELECT-only role.

Ghost bot — a single-Steam-session observer that connects to the live game server and watches packet broadcasts.

SurfaceTableSource packet
Market listingsdarkerdb.marketS2C_MARKETPLACE_ITEM_LIST_RES (and register/cancel events)
Server populationdarkerdb.server_populationS2C_PLAYERLIST_RES (population fields)
Trade chatdarkerdb.trade_chatS2C_CHAT_MESSAGE_NOT on the global trade channel
Leaderboardsdarkerdb.ranking_*RANKING_INFO_RES (auto-discovers seasons/sheets) + RANKING_RANGE_RES (entries)
Merchant snapshotsdarkerdb.merchant_stock, merchant_questsPeriodic merchant captures
Character profilesdarkerdb.characters, character_levels, character_ranksPlayerlist + leaderboard observation

Codex pipeline@katforge/codex's extractor pulls structured game data out of the patch's signed .pak files. See Codex → Dark and Darker extraction.

SurfaceTableSource
Itemsdarkerdb.itemsFull attribute matrices, icons, descriptions
Mapsdarkerdb.mapsGameplay map metadata + minimap PNGs
Loot tablesdarkerdb.loot_tables, loot_entriesDrop weights, conditions, tier filters
Spawnersdarkerdb.spawnersWhere each loot table / monster spawns on each map
Monstersdarkerdb.monsters, monster_abilitiesStat blocks, abilities, behaviors, family / tier
Monster modelsdarkerdb.monster_modelsBinary glTF meshes for in-browser 3D rendering

Architecture

text
                          ┌─────────────────────────────────┐
                          │       Dark and Darker           │
                          │       game server               │
                          └────────────┬────────────────────┘
                                       │ (Steam-authed single session,
                                       │  request/response correlated
                                       │  by sequence number)
                          ┌────────────▼────────────────────┐
                          │       Ghost bot                 │
                          │   realms/darkerdb.com/ghost     │
                          │                                 │
                          │   Market stream                 │
                          │   Leaderboard auto-discovery    │
                          │   Population poll               │
                          │   Trade chat subscribe          │
                          │   Merchant capture              │
                          └────────────┬────────────────────┘
                                       │ Knex (searchPath: darkerdb)
                          ┌────────────▼────────────────────┐
                          │      katforge-db (Postgres)     │
                          │      schema: darkerdb           │
                          └────────────▲────────────────────┘
                                       │ Doctrine (default EM, schema-qualified entities)
                          ┌────────────┴────────────────────┐
                          │      api.katforge.com           │
                          │   src/Realm/DarkerDB/           │
                          │                                 │
                          │   /v1/realms/darkerdb/*  (canonical)
                          │   /v2/*                  (shadow on api.darkerdb.com host)
                          └─────────────────────────────────┘

API surface at a glance

Eleven endpoint groups under /v1/realms/darkerdb — full request/response shapes are documented in the API Reference.

GroupEndpointsSource
HealthGET /healthstatic
PopulationGET /population, /population/historybot
ItemsGET /items, /items/{id}codex
MapsGET /maps, /maps/{id}, /maps/{id}/imagecodex
MonstersGET /monsters, /monsters/{id}, /monsters/{id}/abilities, /monsters/{id}/loot, /monsters/{id}/portrait, /monsters/{id}/modelcodex (+ join to bot for loot)
LootGET /loot-tables, /loot-tables/{id}, /spawners, /spawners/{id}codex
MerchantGET /merchant/stock, /merchant/stock/{merchant}, /merchant/stock/history, /merchant/questsbot
LeaderboardsGET /leaderboards/seasons, …/{season}, …/{season}/sheets, …/{season}/sheets/{sheet}, …/periods, …/entries, …/characters/{name}/historybot
Leaderboards (legacy shim)GET /leaderboards, /leaderboards/{id}bot, mapped from old CSV ids
Trades (planned)global trade chat queriesbot
Characters (planned)per-character history queriesbot

How patches roll forward

When @katforge/codex's extractor picks up a new patch:

  1. bin/protodump <build> — extracts fresh protobuf descriptors from the game binary (DungeonCrawler.exe). Output is committed to the codex repo under protos/<build>/.
  2. The ghost bot is rebuilt and restarted; it picks up the new protos via the symlinked ghost/src/packets/ directory.
  3. bin/console codex:bootstrap dark-and-darker --patch-version=<current> re-imports static content (maps, loot, monsters, models) into the darkerdb.* schema.
  4. Leaderboard schema doesn't need a touch — the bot auto-discovers seasons and sheets from RANKING_INFO_RES on the next cycle.

See Codex → Dark and Darker extraction for the full operator runbook (including the protodump and gltf sub-pipelines).