106 lines
6.1 KiB
Markdown
106 lines
6.1 KiB
Markdown
|
|
# Розділ 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.
|
|||
|
|
- `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 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
|
|||
|
|
|
|||
|
|
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
|