Codex Bonuses

Codex bonuses are persistent meta-progression buffs intended to reward the player for collection milestones (enemies scanned, weapons mastered, biomes cleared). The shape lives on RunDefinition.context.codex and is read by the run-assembly path so that an active codex tier can apply scalar multipliers to damage against specific enemy types or to specific weapon families for the duration of a run.

In the current build the structure is wired through the pipeline but is stubbed and not consumed by the engine: the interface is declared in data/run-config.ts, DEFAULT_RUN initializes both maps as empty {}, and no engine system (damage chain, weapon stats, enemy stats) reads context.codex at runtime. The field exists to reserve the slot in the run schema so the metagame can begin populating it without a separate engine change.

Interface

Defined in src/starship-survivors/data/run-config.ts:

/** Codex knowledge bonuses */
export interface CodexBonuses {
  /** Damage multipliers vs specific enemy types: { 'scout': 0.1, 'juggernaut': 0.15 } */
  damageVs: Record<string, number>;
  /** Per-weapon bonuses: { 'rifle': 0.05 } */
  weaponBonuses: Record<string, number>;
}

Both fields are additive percentage bonuses keyed by ID:

  • damageVs keys are enemy-type IDs (e.g. scout, juggernaut). Value 0.1 is intended to mean +10% damage against that enemy type.
  • weaponBonuses keys are weapon IDs (e.g. rifle). Value 0.05 is intended to mean +5% damage or scaling for that weapon family.

There is no rarity tier, no expiry, and no per-mission scoping on the interface — the maps are flat dictionaries.

Where it lives in the run shape

CodexBonuses is one field on the context block of a RunDefinition, alongside facilities (building bonuses), worldKnobs (difficulty multipliers), and bonuses (daily/session multipliers):

context: {
  // ...
  /** Facility bonuses from metagame buildings */
  facilities: FacilityBonuses;
  /** Codex knowledge bonuses */
  codex: CodexBonuses;
  /** World difficulty knobs */
  worldKnobs: WorldKnobs;
  /** Session/daily bonuses */
  bonuses: SessionBonuses;
}

The context block is the metagame’s contract with the engine: the engine reads these values but never writes them.

Default values

DEFAULT_RUN in data/run-config.ts initializes the codex block with empty maps:

codex: {
  damageVs: {},
  weaponBonuses: {},
},

A run assembled from defaults therefore has no codex effect. Validation in validateRunDef() does not check context.codex — empty maps are valid.

Current status: stubbed

A grep across src/ for context.codex, CodexBonuses, damageVs, and weaponBonuses confirms:

  • The interface and default initializer are the only producers in the codebase.
  • No reader exists. Neither the damage chain, the weapon stat pipeline, nor the enemy stat pipeline looks up runDef.context.codex anywhere.
  • The two existing comment references in the engine (engine/core/types.ts and engine/bridge.ts) only mention codex as one of several context fields callers may read from game.runDef — they don’t actually read it.

In other words, the slot is reserved but inert. Populating damageVs or weaponBonuses from assembleRunService today would have zero gameplay effect.

Why the slot exists

The codex block belongs to the same family as FacilityBonuses — a metagame-owned bag of additive percentages that the engine applies at run start. Keeping the shape declared and threaded through the run schema means:

  1. The metagame UI for a collection / codex system can be built and start producing values without an engine change.
  2. When the engine wiring lands (apply damageVs[enemyId] in the damage chain, apply weaponBonuses[weaponId] in the weapon stat resolution), no shape migration is needed — existing saves already serialize an empty codex block.
  3. The schema validator already accepts the field, so test fixtures and dev scenarios don’t need updating.

Read path (intended)

The intended consumer is the run-assembly path:

  • services/assembleRunService.ts builds a RunDefinition from player state, mission selection, ship loadout, and metagame progression. It is the canonical place to populate context.codex from a player’s codex-tier state.
  • The engine would then apply damageVs[enemy.id] as an additive damage multiplier in the damage chain and weaponBonuses[weapon.id] in the weapon stat resolution at fire time.

Neither half of that read path is implemented yet.

  • FacilityBonuses (data/run-config.ts) — building-derived additive bonuses, fully wired and consumed.
  • WorldKnobs (data/run-config.ts) — multiplicative difficulty knobs on enemy stats and rewards.
  • SessionBonuses (data/run-config.ts) — daily / rare-signal / death-defiance flags.
  • RunDefinition (data/run-config.ts) — the parent shape.