6.1 KiB
Розділ 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): 2–4 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 1–2 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.
optsreserved for growth:citizens,districts,difficulty(onlyseedused 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
httpfor static files +wsfor 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 2–3 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
casegenlib + fairness tests (the heart — everything else renders its output)- Server:
wssync, sessions + seed + disk saves - Analyst terminal: DB, typed queries, city map
- Field: top-down 2D district, movement, search, samples, keys/warrants
- Minigames: DNA gel, fingerprints, CCTV, triangulation
- Crypto tasks + Cicada puzzle
- Interrogations, finale form, firing ending, polish, README