2PlayerGame/chapter3/DESIGN.md
2026-07-23 17:03:26 +03:00

6.1 KiB
Raw Blame History

Розділ 3 — «Невпізнаний» (working title)

Co-op LAN detective, 2 players, Node + vanilla JS. Every playthrough is a new random case from a seed-based generator. Inspired by Shadows of Doubt.

Premise

A body with no ID is found in the district. You get only starting facts (randomized per case): 24 of e.g. a phone number on a scrap of paper, a footprint size, a fabric fiber, a tattoo, a keyring, a partial fingerprint. From there:

  • Act I — Who died? Identify the victim (DB queries, biometrics, missing persons, phone trace).
  • Act II — Who did it, how, and why? The killer is NOT on any suspect gallery. You build a profile from traces and cross-reference the citizen database until one person fits.

Roles (asymmetric, both required)

Польовий детектив — top-down 2D district

  • Canvas top-down map of a fixed hand-crafted compact district: ~10 buildings (apartment blocks, bar, diner, offices, shop, clinic, police HQ), walkable with WASD/arrows.
  • Enters buildings, searches rooms via hotspots, collects samples: DNA swabs, lifted prints, photos, documents, objects. Samples go to the shared board; analyst processes them.
  • Apartment access is legal-only: public places open; private doors need a key (found on the body, in a work safe, at a relative's — never just lying around) or a warrant (requires pinned evidence pointing at that person/place).
  • Interrogation of any NPC — but evidence-gated: topics unlock only when you hold the relevant pinned evidence (ch2 requires: pattern, generated).

Аналітик (поліцейський хакер) — the terminal

  • Citizen DB: ~50 generated residents. Query by typed name (keyboard — wrong spelling = wrong/no dossier) or filter by attributes (blood type, shoe size, employer, address, print type).
  • City map with addresses — who lives/works where; mirrors the district and shows the partner's live position.
  • Labs & systems (each a hands-on minigame, not a button):
    • DNA lab: gel electrophoresis — pipette sample into lanes, visually match band patterns against DB candidates. Wrong match = confidently wrong lead.
    • Fingerprints: overlay lifted print on candidate prints, rotate/align, mark ridge points. DB narrows only by print type; the final match is your eyes.
    • CCTV archive: scrub recorded footage of the crime night (timestamps, not a live clock), spot a figure matching the profile (height, coat, gait).
    • Phone records + triangulation: call logs for a number, triangulate a phone across cell towers onto the city map.
  • Crypto/logic tasks (analyst has a tech background — difficulty is allowed): base64, Caesar/Vigenère and other classical ciphers, binary/hex conversion, md5 password cracking for a suspect's email/laptop (weak password derivable from dossier facts: pet name + birth year — detective work feeds the wordlist), and one optional multi-stage Cicada3301-style puzzle guarding a bonus master-evidence cache. Puzzles are generated with the case.

No clock

No time mechanic. Citizens have static current locations (at work or at home); all CCTV and phone data is archival (the crime night). Actions cost nothing but thought.

Case generator — standalone library

chapter3/casegen/ — pure JS, no DOM/no server deps, reusable anywhere (generateCase(seed, opts)):

  • Deterministic from seed: same seed → same case. Needed for saves and both-players sync; also lets you share a good case with friends.
  • Generates: citizens (names, homes, jobs, relationships, biometrics, phones, current positions), victim, killer, motive from template pool — jealousy/love triangle, debt/desperation, blackmail turned fatal, silenced witness / mistaken identity, kidnapping-gone-wrong, and more drawn from classic Holmes-style structures — method, and the full evidence chain planted backwards from the solution to the starting facts.
  • Red herrings by design: every case plants 12 plausible false leads (a citizen with motive and no alibi, a second print at the scene). Fair-play rule: every false lead is disprovable by reachable evidence — the game may mislead, never cheat.
  • opts reserved for growth: citizens, districts, difficulty (only seed used at first).
  • Fairness validator in test.js: for many random seeds, prove the chain from starting facts to (victim identity, killer, motive, means) is reachable, and every red herring is refutable.

Shared board & sync

  • Server: Node http for static files + ws for real-time sync (state actions AND live field-player position). Session stores the seed + full state, persisted to a JSON file per session code — quit anytime, resume with the same code (the game is sized for 23 evenings).
  • Evidence list and citizen/suspect list are both interactive for both players: tick, cross out, highlight, hide, keyboard notes — all synced.

Finale — one shot

Form with three pickers fed by the interactive lists: ХТО (from citizens), ЯК / ЧИМ (method/weapon), ЧОМУ (motive), each link requiring attached evidence.

Single accusation. Submitting asks for explicit confirmation from both players. Wrong → you're fired: the real case unfolds on screen, game over. Right → full recap, rank based on evidence completeness and how few false leads you chased.

Dependencies policy

Deps allowed, but only popular well-maintained packages, pinned versions, and only where stdlib genuinely falls short. Current plan: ws only. Explicitly not used: game engines (canvas 2D suffices), express (http.createServer suffices), seedrandom (mulberry32 is 5 lines), md5 libs (node:crypto).

Milestones

  1. casegen lib + fairness tests (the heart — everything else renders its output)
  2. Server: ws sync, sessions + seed + disk saves
  3. Analyst terminal: DB, typed queries, city map
  4. Field: top-down 2D district, movement, search, samples, keys/warrants
  5. Minigames: DNA gel, fingerprints, CCTV, triangulation
  6. Crypto tasks + Cicada puzzle
  7. Interrogations, finale form, firing ending, polish, README