Skip to content

Add a discovery-driven hunting journal #24

Description

@zoeyrose

Important

This issue is implemented in the fresh MIT-licensed Go server under the replacement program. Its gameplay and content-design decisions remain authoritative. C, CPython, classic packet, file-path, and enum details in the preserved specification are historical evidence only; do not copy, translate, or structurally port GPL implementation code.

Replacement implementation contract

Implement a Go discovery service consuming durable metrics and encounter events. Send a structured journal model to Rust rather than server-rendered classic book markup, while preserving every disclosure limit.

The server remains authoritative, consumes versioned compiled content, and exposes bounded generated Game Protocol 1 messages. Pure rules may use a specifically approved typed CEL environment. Starlark is not part of this issue unless the separate residual-scripting decision explicitly approves it.

Required verification

  • Preserve every observable rule, balance decision, disclosure boundary, and anti-exploit invariant from the specification below.
  • Add deterministic Go unit/property tests and wrapper-managed scenario coverage at the appropriate integration boundary.
  • Add bounded malformed-input and persistence-failure cases where this feature accepts content, network, or stored data.
  • Add Go/Rust protocol conformance fixtures for every new cross-process field; the client must not reconstruct authoritative rules from prose.
  • Demonstrate that implementation and tests contain no copied GPL source/test material and execute no runtime Python.
Preserved product/design specification and historical implementation notes

Summary

Add a discovery-driven hunting journal that turns observed monsters, damage types, counterplay, regions, and known reward leads into durable in-game knowledge.

The playtest repeatedly needed external source inspection to answer basic preparation questions: what lives in a region, which damage type a dungeon uses, whether a skill can progress there, and what targeted reward might justify the danger. Recent named-variant work (#137, atrinik/content#22) also needs a discoverable player-facing home that is more durable than transient rumor text.

The journal should reveal knowledge through play and authored rumors, not expose exact hidden stats, secret drops, or live rare-monster coordinates.

Existing building blocks

Proposed MVP

Authored family registry

Create a collected and validated bestiary-family source with stable IDs. A family entry can define:

  • eligible archetype IDs and optional variant IDs;
  • display name and broad role/behavior;
  • authored counterplay and hazard hints;
  • region hints and unlockable reward leads;
  • staged unlock policy.

Do not key persistence by display name, map path, or mutable array position. Reuse the family and variant identity established by atrinik/content#23/#140 rather than introducing competing registries.

Staged observation

Record bounded, idempotent discoveries such as:

  1. seen/targeted;
  2. fought;
  3. defeated;
  4. damage type experienced;
  5. resistance or behavior demonstrated by an actual interaction;
  6. reward item identified or an authored rumor learned.

Only reveal facts the character has observed or unlocked. Receiving fire damage can reveal "uses fire"; attacking into a meaningful resistance can reveal a broad resistance hint. Do not reveal exact HP, protection percentages, spawn timers, secret loot probabilities, or current rare coordinates.

Define which discoveries are character-scoped and which, if any, are account-scoped through #33. A conservative MVP can keep combat observations per character while allowing explicitly authored lore/collection unlocks to be account-wide later.

Server-rendered journal surface

Implement /bestiary (or /journal bestiary) using the existing CLIENT_CMD_BOOK path. Support deterministic filters such as:

  • family/name;
  • region;
  • encountered/defeated/unknown;
  • suitable for the active skill.

The suitability filter should consume the same authoritative XP-band helper as atrinik/atrinik#149, not duplicate level math. The server-rendered book keeps the MVP small and avoids a new packet; a dedicated client journal/map overlay can follow after the content model proves useful.

Show silhouettes or counts for authored unknowns only where doing so is intentional. Preserve mystery for excluded story encounters.

Integration

  • Named elites: show encountered/defeated variants, approximate learned region, counterplay, and reward leads without live location disclosure.
  • Achievements (#125): consume stable discoveries later; the journal must not hard-code achievement logic.
  • Preparation content: elemental-readiness quests, NPC rumors, signs, books, and identified ward items can unlock entries.
  • Target XP: journal suitability uses the player's active action-source skill and clearly labels it.

Acceptance criteria

  • A stable family registry maps eligible monster archetypes/variants without using display names.
  • Discovery state persists through Implement QUIC transport, sessions, and authentication #33's bounded stable-ID storage and is idempotent.
  • Seeing, fighting, defeating, receiving a damage type, and identifying/learning a reward lead can unlock separate documented facts.
  • Unobserved exact stats, protections, loot odds, timers, secret encounters, and live coordinates are not leaked.
  • /bestiary renders through the existing book interface with family, region, state, and active-skill-suitability filters.
  • Entries name the active skill used for suitability and distinguish unknown from no-XP.
  • Display-name and descriptive-text changes do not invalidate saved discoveries.
  • Add roaming named elites and counterplay-driven rare combat encounters content#23/#140 family and variant IDs are reused rather than mirrored.
  • Markup from authored and object-derived text is escaped safely and long entries paginate predictably.
  • Content authors receive actionable validation for duplicate IDs, invalid archetype/region/reward references, and unreachable unlock rules.

Validation

  • Unit-test registry loading, duplicate/reference validation, discovery transitions, idempotency, persistence bounds, and stable-ID behavior after display-name changes.
  • Test observation hooks for targeting, damage dealt/received, kill credit, resistance evidence, and item identification without revealing facts early.
  • Test book markup escaping, pagination, deterministic ordering, empty states, and every filter combination.
  • Collect affected resources/interfaces, build the server, and runtime-smoke discovery and persistence with two characters on one account.

Relevant areas

Related: #33 (durable metrics), #31 (achievements), atrinik/content#23 and atrinik/content#22 (named variants), #26 (treasure sense), atrinik/atrinik#148 (skill XP attribution), atrinik/atrinik#149 (target XP suitability).

Metadata

Metadata

Assignees

No one assigned

    Fields

    Priority

    None yet

    Start date

    None yet

    Target date

    None yet

    Effort

    None yet

    Projects

    Status
    Backlog

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions