Skip to content

White Album 2 text visual novel (PSP/Web) — Japanese + furigana text engine#17

Draft
doodlewind wants to merge 1 commit into
mainfrom
artistic-belief
Draft

White Album 2 text visual novel (PSP/Web) — Japanese + furigana text engine#17
doodlewind wants to merge 1 commit into
mainfrom
artistic-belief

Conversation

@doodlewind

Copy link
Copy Markdown
Owner

Warning

DRAFT — do not merge/release as-is. Copyright-sensitive content.

  • framework/src/wa2-script.ts embeds White Album 2 script text — © Leaf/Aquaplus.
  • framework/src/wa2-font.ts embeds glyphs rasterized from Hiragino (Apple/SCREEN-licensed, not redistributable).

To make this shippable: set WA2_FONT to a libre OFL font (Noto Sans JP / Source Han Sans / BIZ UDGothic) and re-bake, and replace the bundled WA2 script text with content you have the right to distribute. Both baked modules are 100% regenerable from the two bakers below, so they could also be dropped from the tree and produced locally.

A text-only visual novel (ADV) running on the existing DreamCart runtime (QuickJS + rust-psp), playing the opening of White Album 2: the snowy airport flashback and the classroom prologue (scenes 1001–1004). No CG/sprites — Japanese text on a per-scene gradient + falling snow, with furigana.

What's here

Native text engine (Rust-first, JS orchestration). The PSP 2D pipeline has no textures — everything is solid-colour sprite quads, and the stock drawText is ASCII-only 8×8. This adds an optional native path that scales to a large Japanese atlas:

  • gfx.vnUploadFont(slot, rows, count, cellW, cellH, bpr) + gfx.vnDrawGlyphs(slot, glyphs, count, rgb) — JS does layout (wrapping, ruby centering, typewriter, scene flow); Rust rasterizes 1-bit glyph cells (MSB=left) into batched run-length sprites, flushing when the scratch fills.
  • Implemented on PSP (runtime/src/gfx.rs, atlas on the heap), Web (web/engine.js Canvas), and the golden mock (framework/test/golden.ts); typed optional in framework/src/host.ts. 3DS skipped (not in CI). Two slots: base + ruby.

Two standalone bakers (like bake-osm/bake-bsp, not wired into bun run bake):

  • framework/bake/bake-wa2.ts — parses the raw WA2 script (raw/*.txt; furigana <R base|reading> only survives in raw/) → framework/src/wa2-script.ts (typed scenes + the exact used charset). WA2_DATASET env overrides the source path.
  • framework/bake/bake-wa2-font.tsopentype.js rasterizes only the used glyph subsetframework/src/wa2-font.ts (base 18px + ruby 13px 1-bit atlases, base64). WA2_FONT overrides the font.

Game framework/games/wa2.js — title, chapter cards, dialogue box + speaker nameplate, typewriter, auto wrap + paging, furigana, gradient/snow.

Verificationscripts/render-wa2.ts headless render harness; all 21 goldens pass; builds and boots in PPSSPP (title / chapter card / dialogue / typewriter / furigana all confirmed on-device).

Build & run

```sh

regenerate data (needs the WA2 dataset + a Japanese font):

WA2_DATASET=/path/to/wa2_dataset_script bun framework/bake/bake-wa2.ts
WA2_FONT=/path/to/font.otf bun framework/bake/bake-wa2-font.ts
bun framework/build.ts # bundle
PSPJS_GAME=wa2.js bun runtime/build.ts # -> EBOOT.PBP
bun run serve # or play it in the web playground
```

Files

  • New: framework/games/wa2.js, framework/bake/bake-wa2.ts, framework/bake/bake-wa2-font.ts, framework/src/wa2-script.ts, framework/src/wa2-font.ts, scripts/render-wa2.ts (*=copyright-sensitive, regenerable)
  • Changed: runtime/src/gfx.rs, web/engine.js, framework/src/host.ts, framework/test/golden.ts, package.json/bun.lock (adds opentype.js devDep, baker-only)

Notes / follow-ups

  • Bundle ~327 KB (font+script base64-in-JS) — under the QuickJS boot-cost wall; if it grows, move to the .dcpak container.
  • Add scenes via the SCENES list in bake-wa2.ts + re-bake (font auto-subsets).
  • A 雪菜 "talk" mode could reuse the dataset's character chatbot JSON.

🤖 Generated with Claude Code

…a engine

A text-only visual novel (framework/games/wa2.js) playing the WA2 opening:
the snowy airport flashback + classroom prologue (scenes 1001-1004). No CG/
sprites — Japanese text on a per-scene gradient + snow, with furigana.

Engine (Rust-first, JS orchestration):
- New native 2D text path gfx.vnUploadFont / gfx.vnDrawGlyphs, extending the
  existing solid-rect sprite model (the 2D pipeline has no textures): JS does
  layout (wrap, ruby centering, typewriter, scene flow); Rust rasterizes 1-bit
  glyph cells to batched run-length sprites. Implemented on PSP
  (runtime/src/gfx.rs, heap atlas), Web (web/engine.js Canvas) and the golden
  mock (framework/test/golden.ts); typed optional in framework/src/host.ts.
  3DS skipped (not in CI). All 21 goldens still pass.

Data pipeline (two standalone bakers, like bake-osm/bake-bsp):
- bake-wa2.ts parses the raw WA2 script (furigana <R base|reading> only
  survives in raw/) -> framework/src/wa2-script.ts (typed scenes + used charset).
- bake-wa2-font.ts (opentype.js) rasterizes ONLY the used glyph subset ->
  framework/src/wa2-font.ts (base 18px + ruby 13px, 1-bit atlas, base64).
- scripts/render-wa2.ts: headless render harness for visual verification.

Verified booting + rendering in PPSSPP (title, chapter card, dialogue,
typewriter, furigana) and on web.

COPYRIGHT — DRAFT ONLY, do not merge/release as-is:
- framework/src/wa2-script.ts embeds White Album 2 script text (c) Leaf/Aquaplus.
- framework/src/wa2-font.ts embeds glyphs rasterized from Hiragino (Apple/SCREEN
  licensed, NOT redistributable). Set WA2_FONT to a libre OFL font
  (Noto Sans JP / Source Han Sans / BIZ UDGothic) and re-bake to ship, and
  remove the third-party script text.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant