feat: upgrade city stay exploration

This commit is contained in:
2026-07-28 00:12:10 +09:00
parent 9d67e0ae1d
commit 1a81ce5689
18 changed files with 1733 additions and 218 deletions

View File

@@ -0,0 +1,142 @@
# City-stay immersion upgrade
Date: 2026-07-27
## Why this batch
The playable Xuzhou, Xinye, and Chengdu stays already connected information,
equipment, and companion choices to later battles, but their presentation
still used code-drawn buildings and tactical unit sheets. This made the
between-battle experience visibly regress after the hand-painted prologue and
Guangzong exploration scenes.
The upgrade follows four established design lessons:
- [GDC's wayfinding and storytelling session](https://www.gdcvault.com/play/1022117/level-design-in-a-day)
recommends conveying information through architecture and readable spatial
navigation.
- [GDC's environmental storytelling framework](https://www.gdcvault.com/play/1012696/What-Happened-Here-Environmental)
treats props, materials, lighting, composition, and world reaction as parts
of the narrative rather than decoration.
- [The Tacoma non-linear story-discovery workshop](https://www.gdcvault.com/play/1025178/Level-Design-Workshop-Designing-for)
connects self-directed exploration order to story discovery.
- [The cognitive-map talk](https://www.gdcvault.com/play/1027206/Stop-Getting-Lost-Make-Cognitive)
emphasizes memorable landmarks and navigable spaces when navigation is not
intended to be the challenge.
Applied here, every city retains the same learnable crossroads grammar while
its government office, market, companion residence, materials, climate, and
recovery state communicate a different campaign moment.
## Runtime assets
| Stay | Background | Named companion SD sheet |
| --- | --- | --- |
| Xuzhou | `src/assets/images/exploration/city-xuzhou-stay.webp` | `characters/exploration-mi-zhu.webp` |
| Xinye | `src/assets/images/exploration/city-xinye-stay.webp` | `characters/exploration-zhuge-liang.webp` |
| Chengdu | `src/assets/images/exploration/city-chengdu-stay.webp` | `characters/exploration-huang-quan.webp` |
The three backgrounds are original 1920x1080 opaque WebP assets. The three
named companion sheets are original 3072x768 transparent WebP sheets using the
shared four-direction, eight-idle-frame, and eight-walk-frame contract.
## Built-in image generation prompt set
All six assets used the built-in image generation workflow. No commercial-game
screenshots, logos, character art, or copyrighted layouts were used.
### Common city background prompt
> Original premium late-Eastern-Han walkable city-stay environment for a
> desktop historical RPG, fixed elevated three-quarter top-down camera, broad
> readable north-south avenue and east-west crossroads, government office at
> upper-left, market at upper-right, companion residence at lower-right, and a
> clear bottom-center road back to camp. Preserve the top, right, and bottom
> fixed-HUD regions as dark low-detail safe zones. Rich painterly realistic
> materials and strong landmarks. No people, animals, readable text, labels,
> UI, logo, watermark, modern object, copied architecture, or copyrighted game
> screen.
The Xuzhou variant shows a recently relieved provincial city with cart tracks,
sealed grain crates, and merchant storehouses at warm late afternoon. The
Xinye variant shows a greener autumn frontier town with timber palisades,
scout forecourts, bamboo, and an adviser residence before Bowang. The Chengdu
variant shows a wealthier Yi Province capital after surrender, with damp
stonework, organized granaries, petition space, and restrained new
administration.
### Common named SD turnaround prompt
> Create one completely original 2.5-head-tall painterly cel-shaded SD
> overworld character. Show the same identity exactly three times in equal
> horizontal columns: front/south, screen-right/east with face and toes
> pointing toward the right edge, and back/north. Keep identical
> scale and lighting, a neutral walking-ready stance, and the full body and
> feet. Use a perfectly flat solid `#ff00ff` removable chroma-key background
> with no floor, shadow, gradient, texture, text, label, grid, logo, watermark,
> extra character, or copied commercial-game likeness.
The character variants preserve only identity and palette from the project's
own portrait assets:
- Mi Zhu: cream, navy, and restrained gold merchant-official robes.
- Zhuge Liang: ivory and dark-jade scholar robes with a rolled strategist cap.
- Huang Quan: dark navy and muted bronze Yi Province official robes.
The generated turnarounds were chroma-cleaned with the installed image
generation helper and assembled with
`scripts/build-exploration-character-sheet.py`. Only optimized runtime assets
are tracked.
## Interaction and presentation scope
- Replace code-drawn city blocks with the dedicated original background for
each city while retaining the proven interaction layout and collision
contract.
- Use exploration SD sheets for Liu Bei, clerks, smiths, and named companions;
tactical sprites remain battle-only.
- Use face portraits in dialogue rather than shrinking a full-body field
sprite into the dialogue window.
- Let a pointer click on an activity target complete the old-RPG interaction
loop: walk to a valid nearby position, face the target, and interact without
a second click.
- Preserve keyboard movement and direct interaction, and preserve the
information, purchase, equipment, resonance, save, and later-battle payoff
state.
## Verification
Verification is performed at an explicit 1920x1080 CSS viewport, 100% browser
zoom, and DPR 1. WebGL is the required renderer and Canvas is the compatibility
renderer.
The completed checks cover:
- all three 1920x1080 background dimensions, opacity, and the combined
2.87 MiB exploration-background budget;
- all thirteen exploration sheets at 3072x768 with alpha and the shared
four-direction animation contract;
- CityStayScene type and data integrity, including equipment offers, visit
rewards, resonance links, soundscapes, and lookup helpers;
- real pointer travel to information, market, companion, and exit targets,
automatic one-time interaction, authored NPC positions, low-frame-rate
arrival clamping, collision detours, and distance-gated keyboard interaction;
- face-only dialogue portraits, intentional portrait-free narrator lines,
market purchase, resonance choice, reward idempotence, save/reload
restoration, optional early exit, and next-battle briefing payoff;
- Xuzhou, Xinye, and Chengdu in both Canvas and WebGL at the required desktop
baseline, with representative screenshots written as
`dist/verification-city-*-map.png`,
`dist/verification-city-*-information.png`, and
`dist/verification-city-*-dialogue.png`;
- the complete static, build, loader-lifecycle, interaction, accessibility,
battle keyboard, prologue, pursuit, relief, third-return, third-camp,
audiovisual, release-candidate, and performance gates.
The review also corrected four edge cases before release: legacy invisible
blockers from the former vector city, a portrait crop whose origin followed
the uncropped source image, east/west rows reversed in the three new SD
sheets, and pointer movement that could oscillate across a destination at a
50 ms frame interval. A CampScene browser fixture was also made to wait for
the third-camp exploration button's rendered interactive state instead of
reading it during scene-restart asset loading.

View File

@@ -12,11 +12,13 @@ files.
| Zhuo village and militia camp | `src/assets/images/exploration/prologue-village.webp`, `prologue-militia-camp.webp` | 1920×1080 opaque WebP |
| Second-victory northern village and ferry | `src/assets/images/exploration/second-pursuit-village-ferry.webp` | 1920×1080 opaque WebP |
| Third-victory Guangzong forward sortie camp | `src/assets/images/exploration/third-guangzong-sortie-camp.webp` | 1920×1080 opaque WebP |
| Xuzhou, Xinye, and Chengdu city stays | `src/assets/images/exploration/city-*-stay.webp` | 1920×1080 opaque WebP |
| Exploration SD characters | `src/assets/images/exploration/characters/exploration-*.webp` | 3072×768 transparent WebP sprite sheets |
| First-victory camp Jian Yong | `src/assets/images/exploration/characters/exploration-jian-yong.webp` | 3072×768 transparent WebP sprite sheet |
| City-stay companions | `exploration-mi-zhu.webp`, `exploration-zhuge-liang.webp`, `exploration-huang-quan.webp` | 3072×768 transparent WebP sprite sheets |
| Prologue NPC dialogue portraits | `src/assets/images/portraits/zhuo-*-yellow-turban.webp`, `zou-jing-yellow-turban.webp` | 1254×1254 WebP |
The four backgrounds reserve the exact top, right, and bottom HUD regions used
The seven backgrounds reserve the exact top, right, and bottom HUD regions used
by the 1920×1080 desktop layout. Each playable portion was aligned to the
existing collision and interaction coordinate system before export.
@@ -66,6 +68,22 @@ weapon area on the right. Its final built-in generation request was:
> people, text, UI, logos, modern objects, copied characters, or copyrighted
> game art.
The three city-stay variants use one learnable crossroads layout while changing
their architectural story: Xuzhou is a recently relieved provincial city,
Xinye is a vulnerable autumn frontier town preparing Zhuge Liang's first
command, and Chengdu is a wealthier Yi Province capital settling into a new
administration. Their shared request was:
> Original premium late-Eastern-Han walkable city-stay environment for a
> desktop historical RPG, fixed elevated three-quarter top-down camera, broad
> readable north-south avenue and east-west crossroads, government office at
> upper-left, market at upper-right, companion residence at lower-right, and a
> clear bottom-center road back to camp. Preserve the top, right, and bottom
> fixed-HUD regions as dark low-detail safe zones. Rich painterly realistic
> materials and strong landmarks. No people, animals, readable text, labels,
> UI, logo, watermark, modern object, copied architecture, or copyrighted game
> screen.
The generated masters were converted to opaque 1920×1080 WebP runtime assets
with the project background builder or an equivalent loss-controlled FFmpeg
conversion; only the optimized runtime assets are tracked.
@@ -116,6 +134,14 @@ The generated turnaround was chroma-cleaned and assembled by
`scripts/build-exploration-character-sheet.py`; only the optimized transparent
runtime sheet is shipped.
The Xuzhou, Xinye, and Chengdu stays add dedicated SD turnarounds for Mi Zhu,
Zhuge Liang, and Huang Quan. Their project portraits were used only as identity
and palette references. Each final request retained the common three-view,
flat-magenta-background contract while specifying the character's own robes,
headwear, age, and silhouette. The same chroma-cleaning and sprite-sheet
assembly workflow was used, so tactical unit sheets are no longer shown in
city exploration.
## Optimization and verification
- Backgrounds are limited to 2 MiB each and 6 MiB combined.

View File

@@ -10,8 +10,8 @@ Generated by `scripts/audit-visual-asset-quality.mjs`.
- Flagged battle map rows with repaint reports: 3
- Battle map source pixel density range: 60.0-96.0 px/tile
- Story source backgrounds: 136
- Story page background references: 466
- Flagged story background review rows: 17
- Story page background references: 469
- Flagged story background review rows: 16
## Main Findings
@@ -53,10 +53,10 @@ Generated by `scripts/audit-visual-asset-quality.mjs`.
| 2 | `src/assets/images/story/40-nanzhong-captures-river-ford.png` | 10 | 1672x941 | 1.8187 | repeat story background | `fortySeventhBattleIntroPages/forty-seventh-zhao-yun-vanguard`<br>`fortyEighthBattleIntroPages/forty-eighth-zhuge-amnesty`<br>`fortyNinthBattleVictoryPages/forty-ninth-victory-second-capture` |
| 2 | `src/assets/images/story/25-yizhou-luo-road.png` | 10 | 1672x941 | 2.4004 | repeat story background | `twentySeventhBattleIntroPages/twenty-seventh-yizhou-request`<br>`twentySeventhBattleIntroPages/twenty-seventh-gate-warning`<br>`twentySeventhBattleVictoryPages/twenty-seventh-victory-road-open` |
| 2 | `src/assets/images/story/37-yizhou-luo-road-ambush.png` | 9 | 1672x941 | 1.7313 | repeat story background | `twentyThirdBattleIntroPages/twenty-third-zhuge-plan`<br>`twentyFourthBattleIntroPages/twenty-fourth-yi-ji-rumor`<br>`twentySeventhBattleVictoryPages/twenty-seventh-next-fu-pass` |
| 2 | `src/assets/images/story/72-northern-mountain-war-council.png` | 8 | 1672x941 | 1.3639 | repeat story background | `thirtyFifthBattleIntroPages/thirty-fifth-hanzhong-front`<br>`thirtySixthBattleIntroPages/thirty-sixth-dingjun-mountain`<br>`thirtySixthBattleIntroPages/thirty-sixth-western-cavalry` |
| 2 | `src/assets/images/story/12-yizhou-mountain-pass.png` | 8 | 1672x941 | 1.6969 | repeat story background | `twentyThirdBattleIntroPages/twenty-third-ma-liang-rumor`<br>`twentyThirdBattleVictoryPages/twenty-third-victory-southern-road`<br>`twentyThirdBattleVictoryPages/twenty-third-next-commandery` |
| 2 | `src/assets/images/story/28-nanzhong-seven-captures.png` | 8 | 1672x941 | 2.4106 | repeat story background | `fortySeventhBattleIntroPages/forty-seventh-zhuge-policy`<br>`fortySeventhBattleVictoryPages/forty-seventh-next-nanman`<br>`fortyEighthBattleVictoryPages/forty-eighth-next-capture` |
| 2 | `src/assets/images/story/30-maicheng-isolation.png` | 2 | 1672x941 | 1.1976 | low PNG byte density | `fortyFourthBattleIntroPages/forty-fourth-lu-meng-seals-roads`<br>`fortyFourthBattleVictoryPages/forty-fourth-lu-meng-tightens` |
| 1 | `src/assets/images/story/02-liu-bei-resolve.png` | 0 | 1672x941 | 1.3671 | unused source background | none |
## Battle Map Inventory
@@ -148,7 +148,7 @@ Generated by `scripts/audit-visual-asset-quality.mjs`.
| `src/assets/images/story/102-yiling-baidi-lantern-vigil.png` | 2 | 1672x941 | 2.26 | none |
| `src/assets/images/story/103-weishui-northbank-frozen-ferry.png` | 3 | 1672x941 | 2.75 | none |
| `src/assets/images/story/104-lucheng-pursuit-dust-road.png` | 1 | 1672x941 | 3.01 | none |
| `src/assets/images/story/105-qishan-renewed-snow-relay.png` | 2 | 1672x941 | 2.81 | none |
| `src/assets/images/story/105-qishan-renewed-snow-relay.png` | 5 | 1672x941 | 2.81 | none |
| `src/assets/images/story/106-hanzhong-rain-supply-trench.png` | 3 | 1672x941 | 2.49 | none |
| `src/assets/images/story/107-maicheng-isolation-abandoned-gate.png` | 1 | 1672x941 | 2.45 | none |
| `src/assets/images/story/108-yiling-fire-forest-corridor.png` | 2 | 1672x941 | 2.44 | none |
@@ -163,7 +163,7 @@ Generated by `scripts/audit-visual-asset-quality.mjs`.
| `src/assets/images/story/116-yiling-fire-attack-river-ashes.png` | 2 | 1672x941 | 2.26 | none |
| `src/assets/images/story/117-baidi-entrustment-river-watch.png` | 1 | 1672x941 | 2.10 | none |
| `src/assets/images/story/118-tianshui-front-hidden-letter.png` | 2 | 1672x941 | 2.35 | none |
| `src/assets/images/story/119-hanzhong-rain-mountain-shrine.png` | 1 | 1672x941 | 2.67 | none |
| `src/assets/images/story/119-hanzhong-rain-mountain-shrine.png` | 2 | 1672x941 | 2.67 | none |
| `src/assets/images/story/12-yizhou-mountain-pass.png` | 8 | 1672x941 | 2.55 | repeat story background |
| `src/assets/images/story/120-maicheng-isolation-snow-bridge.png` | 3 | 1672x941 | 2.29 | none |
| `src/assets/images/story/121-wudu-yinping-cloud-signal.png` | 3 | 1672x941 | 2.68 | none |
@@ -177,7 +177,7 @@ Generated by `scripts/audit-visual-asset-quality.mjs`.
| `src/assets/images/story/129-three-heroes-rain-shelter.png` | 1 | 1672x941 | 2.31 | none |
| `src/assets/images/story/13-northern-expedition.png` | 11 | 1672x941 | 2.35 | repeat story background |
| `src/assets/images/story/130-lucheng-pursuit-ravine-signal.png` | 1 | 1672x941 | 2.72 | none |
| `src/assets/images/story/131-weishui-camps-frozen-watch.png` | 2 | 1672x941 | 2.22 | none |
| `src/assets/images/story/131-weishui-camps-frozen-watch.png` | 5 | 1672x941 | 2.22 | none |
| `src/assets/images/story/132-weishui-northbank-siege-line.png` | 1 | 1672x941 | 2.55 | none |
| `src/assets/images/story/133-yiling-fire-attack-smoke-crossing.png` | 2 | 1672x941 | 2.37 | none |
| `src/assets/images/story/134-chengdu-surrender-sealed-gate.png` | 1 | 1672x941 | 2.50 | none |
@@ -192,7 +192,7 @@ Generated by `scripts/audit-visual-asset-quality.mjs`.
| `src/assets/images/story/21-hanzhong-rain-defense.png` | 2 | 1672x941 | 2.25 | none |
| `src/assets/images/story/22-lucheng-pursuit.png` | 2 | 1672x941 | 2.03 | none |
| `src/assets/images/story/23-weishui-camps.png` | 1 | 1672x941 | 2.31 | none |
| `src/assets/images/story/24-weishui-northbank.png` | 2 | 1672x941 | 2.22 | none |
| `src/assets/images/story/24-weishui-northbank.png` | 1 | 1672x941 | 2.22 | none |
| `src/assets/images/story/25-yizhou-luo-road.png` | 10 | 1672x941 | 3.60 | repeat story background |
| `src/assets/images/story/26-chengdu-surrender.png` | 2 | 1672x941 | 3.64 | none |
| `src/assets/images/story/27-jingzhou-crisis.png` | 5 | 1672x941 | 3.23 | none |
@@ -211,7 +211,7 @@ Generated by `scripts/audit-visual-asset-quality.mjs`.
| `src/assets/images/story/40-nanzhong-captures-river-ford.png` | 10 | 1672x941 | 2.73 | repeat story background |
| `src/assets/images/story/41-wandering-night-camp.png` | 5 | 1672x941 | 2.55 | none |
| `src/assets/images/story/42-wandering-river-crossing.png` | 6 | 1672x941 | 2.60 | none |
| `src/assets/images/story/43-northern-qishan-snow-march.png` | 5 | 1672x941 | 3.03 | none |
| `src/assets/images/story/43-northern-qishan-snow-march.png` | 4 | 1672x941 | 3.03 | none |
| `src/assets/images/story/44-northern-wei-fortress.png` | 5 | 1672x941 | 2.93 | none |
| `src/assets/images/story/45-yizhou-council-at-river.png` | 2 | 1672x941 | 2.89 | none |
| `src/assets/images/story/46-yizhou-mountain-gate.png` | 2 | 1672x941 | 3.01 | none |
@@ -230,8 +230,8 @@ Generated by `scripts/audit-visual-asset-quality.mjs`.
| `src/assets/images/story/59-yiling-baidi-mountain-retreat.png` | 3 | 1672x941 | 2.84 | none |
| `src/assets/images/story/60-maicheng-isolation-snow-road.png` | 1 | 1672x941 | 2.74 | none |
| `src/assets/images/story/61-yiling-fire-attack-riverbank.png` | 1 | 1672x941 | 2.60 | none |
| `src/assets/images/story/62-hanzhong-rain-night-watch.png` | 3 | 1672x941 | 2.55 | none |
| `src/assets/images/story/63-weishui-northbank-cavalry-screen.png` | 2 | 1672x941 | 2.74 | none |
| `src/assets/images/story/62-hanzhong-rain-night-watch.png` | 2 | 1672x941 | 2.55 | none |
| `src/assets/images/story/63-weishui-northbank-cavalry-screen.png` | 1 | 1672x941 | 2.74 | none |
| `src/assets/images/story/64-nanzhong-forest-council.png` | 1 | 1672x941 | 2.73 | none |
| `src/assets/images/story/65-yizhou-luo-road-cliff-fortress.png` | 5 | 1672x941 | 2.36 | none |
| `src/assets/images/story/66-yizhou-luo-road-mountain-scouts.png` | 11 | 1672x941 | 2.59 | repeat story background |
@@ -240,7 +240,7 @@ Generated by `scripts/audit-visual-asset-quality.mjs`.
| `src/assets/images/story/69-wandering-market-shelter.png` | 6 | 1672x941 | 2.31 | none |
| `src/assets/images/story/70-wandering-cold-mountain-pass.png` | 7 | 1672x941 | 2.10 | none |
| `src/assets/images/story/71-northern-supply-valley.png` | 3 | 1672x941 | 2.65 | none |
| `src/assets/images/story/72-northern-mountain-war-council.png` | 8 | 1672x941 | 2.05 | repeat story background |
| `src/assets/images/story/72-northern-mountain-war-council.png` | 7 | 1672x941 | 2.05 | none |
| `src/assets/images/story/73-red-cliffs-chain-smoke.png` | 3 | 1672x941 | 2.20 | none |
| `src/assets/images/story/74-wolong-river-strategy.png` | 2 | 1672x941 | 2.29 | none |
| `src/assets/images/story/75-jingzhou-crisis-river-watchtowers.png` | 2 | 1672x941 | 2.38 | none |
@@ -263,7 +263,7 @@ Generated by `scripts/audit-visual-asset-quality.mjs`.
| `src/assets/images/story/92-northern-supply-depot.png` | 4 | 1672x941 | 2.73 | none |
| `src/assets/images/story/93-yizhou-mountain-pass-command-post.png` | 4 | 1672x941 | 2.70 | none |
| `src/assets/images/story/94-red-cliffs-dawn-aftermath.png` | 3 | 1672x941 | 2.43 | none |
| `src/assets/images/story/95-yellow-pursuit-rural-crossroads.png` | 2 | 1672x941 | 2.95 | none |
| `src/assets/images/story/95-yellow-pursuit-rural-crossroads.png` | 3 | 1672x941 | 2.95 | none |
| `src/assets/images/story/96-wolong-autumn-study.png` | 6 | 1672x941 | 2.56 | none |
| `src/assets/images/story/97-fan-castle-flood-prison-camp.png` | 4 | 1672x941 | 2.15 | none |
| `src/assets/images/story/98-jingzhou-crisis-secret-letter.png` | 4 | 1672x941 | 2.22 | none |