Resolves decision 8: art is generated in PixelLab from written prompts.
docs/ART.md carries the palette spec, the sky/wood slot rule, per-asset
sizes and return format, and prompts for Aki (needed for M3), the rest of
the cast, and the shop background.
art/palette.png (16x1, one pixel per entry) and art/palette_ref.png
(512x64 swatch strip) are generated from g_Palette so the generator and
the build cannot drift apart.
Flags a constraint the palette had hidden: only one literal skin entry, so
portraits use 6 -> 14 -> 4 as a hue-compatible skin ramp.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Records slot count, naming, presentation, delete guard and the day-length
dial as decision-queue items 16-20 marked "defer": captured so the
reasoning survives, but explicitly not decided now. They only bite at M10
and are all easier to judge against a real slot screen than in the
abstract. Adds a "defer" convention to the queue preamble.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
tool/disk_save already indexes every call by entry, so multiple save files
cost almost nothing on the storage side — KISSAT00.SAV, KISSAT01.SAV, and
DiskSave_Check/Delete/GetFreeEntries already exist per entry. The work is
the boot-time slot screen, which is why it sits late: it is easier to
design once there is real save content to display.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Replaces the hand-rolled PHYDIO/DSKIO sector writer, which never worked,
with engine/src/tool/disk_save.h — added in MSXgl v1.3.0 for exactly this
("save to disk from a ROM application"). Saves are now a real FAT file,
KISSAT00.SAV, on the disk in drive A.
Four non-obvious requirements, all documented in CLAUDE.md:
- LibModules needs both "tool/disk_save" and "dos"
- ROMDelayBoot = true, or the Disk ROM's INIT never runs
- boot then takes 40-90s of emulated time (use `set throttle off`)
- DiskSave_Check() returns SAVEDATA_UNSIGNED for good files: with APPSIGN
it wants the first 4 bytes to be g_AppSignature, but DiskSave_Save()
writes the payload raw and never adds it
Also fixes a save-timing bug: the write now happens in AdvanceDay() after
the day increments, so the file describes the morning the player wakes to.
Saving during the evening made a reload replay that day and double-count
its cups.
Verified: play a full day, cold boot, resume at day 2 with served intact.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
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>