Stage 1 (shop scene, customer, siphon brew minigame, serve loop) and the M2 day spine: day counter, three-phase day, event-driven clock, journal line, and a SaveState with magic/version/checksum. Saving to disk is NOT working yet. A cartridge ROM can reach the Disk ROM only from RAM (both PHYDIO and CALSLT switch page 1 out from under the caller), and ROMDelayBoot is required so the Disk ROM's INIT runs at all. With both in place the disk is detected, but sector I/O returns carry-clear without transferring — proven with a sentinel. Probe now verifies the buffer actually changed, so a non-working disk degrades to "no save" rather than corrupting anything. Full findings in the project CLAUDE.md. Also documented: keyboard reads need interrupt protection (the BIOS ISR scans the matrix too), and BankedCall must stay off until banked data exists. Docs: PLAN.md (ten milestones, per-stage requirements, decision queue), SCRIPT.md (all four character arcs, 60 beats, checked against the 26-character box), and amendment notes in DESIGN.md. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
7.6 KiB
Kissaten Yūgure — Design document
Working title: Kissaten Yūgure ("Twilight Coffee Shop") Platform: MSX2 · Library: MSXgl (C) · ROM: ASCII16 MegaROM
Amendments. This document still describes the game's intent and is the place to start. A few specifics have since been decided differently — where they conflict, the documents below win:
- Cast size: four, not six to eight (§3). The four examples in §3 became the entire roster. Rationale in
PLAN.md§6; full arcs inSCRIPT.md.- Endings: one, not several (§8 stage 5).
PLAN.md§6.- Saving: a real save disk (
.dsk), not yet working — see the disk section in../CLAUDE.md. Note the RP-5C01 CMOS holds only 6 bytes through MSXgl, so it is not an alternative for a ~40-byteSaveState.- Music (§7) is out of date. It describes a PSG / MML → NDP pipeline; the working pipeline is
msx-music-generator→ lVGM + ayFX. Which chip this game targets is still open —PLAN.md§8 item 15.- The brew minigame is coffee-only. Aki's cream soda is poured, not brewed, so her visits skip it —
SCRIPT.md§8.Build order and per-stage requirements live in
PLAN.md, which supersedes the scope ladder in §8 below with a finer ten-milestone breakdown.
1. Concept
You inherit a small kissaten (coffee shop) in a fictional provincial Japanese town in 1987. A cozy, no-fail-state game about serving regulars, learning their stories, and watching the town and seasons change.
Audience: adult retro gamers with a love of Japanese art, computers, and late-80s Japan nostalgia. The MSX2 itself is part of the fantasy — the game should look like it came off an MSX magazine cover.
Tone references: A Short Hike (pace and warmth), Konami/Compile-era MSX2 pixel art, Showa-era kissaten culture, gentle city-pop-adjacent PSG music.
The cozy contract: no fail states. You cannot go bankrupt. Money gates cosmetic and menu upgrades (better grinder, jazz records, a cat), not survival. Progression = unlocking regulars' stories and seasonal change.
2. Core loop
One in-game day ≈ 5–10 real minutes, in three phases:
- Morning (prep): choose today's menu focus (coffee blend, toast set, curry), check the radio for weather (weather affects who visits), buy stock.
- Open hours (the heart): customers arrive one or two at a time. Take orders, brew/cook via a timing minigame, and — most importantly — talk. Regulars have multi-day story arcs told in short dialogue beats.
- Evening (close): count the till, journal entry summarizing the day, save.
Brew minigame: a siphon coffee brew with a "release at the right moment" mechanic. One-button friendly, thematic, satisfying to master. Quality result feeds into customer affinity slightly (never punishingly).
3. The regulars
Six to eight recurring characters; this is where the game lives. Examples:
- The retired stationmaster
- A high-schooler studying for entrance exams
- A manga artist missing deadlines
- A widow who orders the same thing daily
Each has a story arc of ~12–20 short scenes, triggered by day count, season, weather, or what you serve them. Serving the right thing at the right moment advances arcs — the player learns preferences by paying attention, which mechanically rewards the "regulars at my shop" fantasy.
Visitor logic per open-hours tick: roll against a weighted table filtered by (season, weather, time-of-day, days-since-last-visit). Simple, tunable in a spreadsheet, and it naturally produces patterns players notice and love ("the stationmaster always comes when it rains").
4. Screen layout — SCREEN 5 (256×212)
| Region | Height | Contents |
|---|---|---|
| Status bar | 16 px | Day + season · clock · money (¥) |
| Shop scene | 132 px | Tile/bitmap background: window, shelves, radio. Door zone (customer entry), counter zone (16×16 layered customer sprites), siphon rig zone (brew minigame). |
| Dialogue window | 64 px | 48×48 portrait left; 3 lines × 26 chars text with typewriter reveal; choice cursor on line 3 when needed. |
Deliberately static-heavy: only sprites move, so the MSX2's weak scrolling is sidestepped entirely. Status bar and dialogue window redraw rarely — only the scene needs per-frame attention. This is the single biggest scope-saver.
5. Hardware / MSXgl mapping
Video. SCREEN 5 (G4), 16 colors from 512.
- VRAM page 0: visible shop background bitmap.
- VRAM page 1: asset warehouse — customer sprite frames, portraits, UI tiles, blitted with VDP commands (HMMM); dialogue box open/close is HMMV rectangle fill + font rendering, never touching the scene.
Seasonal palette trick. Author the background once, designed around palette slots: sky-through-window colors in slots 8–11, wood/warm tones in 4–7. Each season and time of day is then just a 32-byte palette table — morning spring light vs. rainy autumn dusk on the same bitmap, basically free. Optionally lerp between palettes across the in-game day for a slow ambient shift. This is the most atmospheric feature in the game.
Sprites. Sprite mode 2 (per-line colors on 16×16). Two layered sprites per customer (outline + fill) for the classic MSX2 look. Max two customers on screen plus player hands/steam effects — nowhere near the 8-per-line limit.
Portraits. 48×48 with three expressions per character (neutral, happy, troubled), copied from page 1 into the dialogue box. Portraits are where the pixel-art budget goes; they sell the characters.
ROM. ASCII16 MegaROM from day one — dialogue, portraits, and music banks will not fit in 32KB. MSXgl supports banked ROMs well.
6. Data model
typedef struct {
u8 id;
u8 arc_stage; // progress through their story
u8 affinity; // 0-255, raised by right orders
u8 last_visit_day;
} Regular;
typedef struct {
u16 day;
u8 season; // derives palette set
u8 weather; // affects visitor table
u16 money;
u8 unlocked_items; // bitmask: grinder, records, cat...
Regular regulars[8];
} SaveState; // ~40 bytes → trivial to save
Dialogue is the biggest data mass. Scenes stored in a flat script format:
(trigger conditions) → (portrait id, expression, text lines,
optional choice, effects)
Authored in YAML/JSON; a small Node.js compiler (tools/compile_dialogue.js)
emits C arrays or a binary blob for a MegaROM bank. Budget: ~8 characters ×
~15 scenes plus ambient lines.
7. Music
PSG via the MML → NDP compiler → ndp_player pipeline, with AI-assisted MML
generation through tools/generate_mml.js (Anthropic API).
Needs: 6–8 short cozy loops rather than driving action tracks — morning, afternoon, evening, rain, plus one theme per major story beat.
Diegetic jukebox: the record-player upgrade lets the player choose the shop's background track — a feature and a home for all generated music in one.
8. Scope ladder
Build in this order so every stage is a playable game:
- Shop scene + one customer + brew minigame + serve loop, no story
- Day/night + save + money
- Dialogue engine + two regulars with short arcs ← the real milestone
- Seasons/weather/palettes
- Remaining cast, upgrades, endings
If serving the exam student his usual and getting one new line of his story feels good at stage 3, the game works.
9. Other principles
- Lean hard into palette work — the MSX2's superpower.
- Keep text minimal or bilingual-friendly; the Japanese retro community is a big chunk of the real audience.
- Let the soundtrack carry the mood — cozy games live or die on music.
- Marketing hook: "run a coffee shop on real MSX2 hardware."