Official project name: TBD.
An RPG built as a Perchance generator. The game is a
normal web app (TypeScript + Vite + Preact + three.js); the Perchance platform
provides the hosting shell and the two AI plugins used at runtime
(generateImage, generateText).
This branch (perchance) is the minimal upload set for the Perchance
workspace. It contains the app code plus this README — nothing else (no
configs, no CI, no specs, no dev tooling).
Onboarding flow: a title screen ("CHRONICLES" + New Game / Load /
Settings / Credits / Help; Load is disabled until a save exists) leads to
the New Game identity wizard (name → appearance archetype, which
generates your sprite → background story template or custom → review →
creates a save slot and enters the game). The identity is locked to the
save. Load Game shows the 3 manual slots + autosave. Settings has
a working Language tab (en / zh / hi / es / ar — the AI responds in the
selected language; other tabs are stubs). Saves persist in IndexedDB
(save table).
Scene (type C — open variant): a 3D scene built with three.js — a
floor plane and a landscape backdrop, each textured by an
AI-generated image (see prompts in src/rpg/src/scene/manifest/openPlains.ts).
Two character sprites (the player from identity creation + a picked
NPC from the seed pool) stand on the floor. A subtle fog effect drifts
over the scene frame (declarative in the manifest). Each sprite is
generated by the image plugin on a solid-white background with its
ground shadow baked into the image (so it reads grounded wherever the
generator placed the feet), removed client-side by RMBG-1.4
(@huggingface/transformers + ONNX Runtime Web), cleaned, and rendered
with a black outline plane behind it.
⚠️ On first boot the browser downloads the ~45 MB removal model from
huggingface.co (cached afterwards) — an animated loading screen reports
the live stages, including a "Downloading AI model…" stage with a
percentage, and a corner chip shows removal progress ("Removing background
1/2…"). The inference runs off the main thread (ONNX Runtime proxy
worker) so the UI stays responsive, and the ORT WASM engine is fetched
from the jsdelivr CDN at runtime (wasmPaths — the local
build/assets/*.wasm is intentionally not uploaded; a 404 for it is NOT
expected). A sprite generated before the model is ready waits for it; if
the model CDN is unreachable, the app falls back to the platform's
removeBackground (console warning — the fallback is never cached, so the
next boot re-attempts the model).
Processed cut-outs are cached: after the first removal each sprite's
cut-out is stored in IndexedDB (cutouts table). Reloads serve them with
no re-inference — expect a fast reload (seconds) and the console line
[rpg] cutout-cache: hit <id> (skip inference).
Narrator opening: after the scene loads, the world narrator speaks once (2-3 sentences describing the scene and who is present — it knows the scene and the characters from the art prompts; it never sees the player's background).
Dialogue (multi-turn): a Preact overlay. Talk to <NPC name> (in the
top-left HUD) asks the text AI for a line with the full context payload
(who the NPC is, their background, the player's appearance, the scene, the
bounded conversation log, the language). If the AI includes a [choices]
block (see below), the options become clickable buttons; choosing one
appends it to the conversation and asks the AI for the follow-up, which
may carry new choices — the loop continues until Leave (always-escape,
fixed button, always available, even while the AI is thinking).
Sprite re-roll: a Re-roll sprite HUD button regenerates the current
NPC's sprite with a new seed (cache bust → fresh image → fresh
cut-out). The player's sprite is part of their identity and is never
re-rolled.
| Perchance | This branch |
|---|---|
Lists panel (main.pjs) | imports the AI plugins (generateImage, generateText) |
HTML panel (index.html) | loads the app bundle |
src/rpg/build/ | the compiled production bundle (rpg.js, rpg.css, chunks/) |
src/rpg/src/ | readable TypeScript source (for agent navigation) |
src/README.md | this file |
src/test-prompt.txt | the handoff prompt for each test round |
src/rpg/src/content/npcPool.ts); one is picked per new game.[choices] format: dialogue text, blank line, a line with exactly
[choices], then 1. <option> lines (max 4). The parser also degrades
gracefully when the AI omits the block.The game code boots against window.root:
root.generateImage(opts) → AI image generation (floor/backdrop textures
and RAW character sprites on a solid-white background with a baked ground
shadow)root.generateText(opts) → AI text generation (dialogue)Read src/test-prompt.txt first — it lists exactly what to check, click,
measure, and report for this round. The AI plugins only execute inside the
platform; the generator runs in a cross-origin iframe, so runtime validation
is your job.
Local development, tooling, CI, and specs live on the main branch of
https://github.com/Fahell/chronicles. This branch is generated by
./scripts/ship-perchance.sh — do not edit it by hand.
122 commits
TypeScript
82.8%
CSS
7.0%
JavaScript
5.3%
HTML
3.1%
Shell
1.8%
Official project name: TBD.
An RPG built as a Perchance generator. The game is a
normal web app (TypeScript + Vite + Preact + three.js); the Perchance platform
provides the hosting shell and the two AI plugins used at runtime
(generateImage, generateText).
This branch (perchance) is the minimal upload set for the Perchance
workspace. It contains the app code plus this README — nothing else (no
configs, no CI, no specs, no dev tooling).
Onboarding flow: a title screen ("CHRONICLES" + New Game / Load /
Settings / Credits / Help; Load is disabled until a save exists) leads to
the New Game identity wizard (name → appearance archetype, which
generates your sprite → background story template or custom → review →
creates a save slot and enters the game). The identity is locked to the
save. Load Game shows the 3 manual slots + autosave. Settings has
a working Language tab (en / zh / hi / es / ar — the AI responds in the
selected language; other tabs are stubs). Saves persist in IndexedDB
(save table).
Scene (type C — open variant): a 3D scene built with three.js — a
floor plane and a landscape backdrop, each textured by an
AI-generated image (see prompts in src/rpg/src/scene/manifest/openPlains.ts).
Two character sprites (the player from identity creation + a picked
NPC from the seed pool) stand on the floor. A subtle fog effect drifts
over the scene frame (declarative in the manifest). Each sprite is
generated by the image plugin on a solid-white background with its
ground shadow baked into the image (so it reads grounded wherever the
generator placed the feet), removed client-side by RMBG-1.4
(@huggingface/transformers + ONNX Runtime Web), cleaned, and rendered
with a black outline plane behind it.
⚠️ On first boot the browser downloads the ~45 MB removal model from
huggingface.co (cached afterwards) — an animated loading screen reports
the live stages, including a "Downloading AI model…" stage with a
percentage, and a corner chip shows removal progress ("Removing background
1/2…"). The inference runs off the main thread (ONNX Runtime proxy
worker) so the UI stays responsive, and the ORT WASM engine is fetched
from the jsdelivr CDN at runtime (wasmPaths — the local
build/assets/*.wasm is intentionally not uploaded; a 404 for it is NOT
expected). A sprite generated before the model is ready waits for it; if
the model CDN is unreachable, the app falls back to the platform's
removeBackground (console warning — the fallback is never cached, so the
next boot re-attempts the model).
Processed cut-outs are cached: after the first removal each sprite's
cut-out is stored in IndexedDB (cutouts table). Reloads serve them with
no re-inference — expect a fast reload (seconds) and the console line
[rpg] cutout-cache: hit <id> (skip inference).
Narrator opening: after the scene loads, the world narrator speaks once (2-3 sentences describing the scene and who is present — it knows the scene and the characters from the art prompts; it never sees the player's background).
Dialogue (multi-turn): a Preact overlay. Talk to <NPC name> (in the
top-left HUD) asks the text AI for a line with the full context payload
(who the NPC is, their background, the player's appearance, the scene, the
bounded conversation log, the language). If the AI includes a [choices]
block (see below), the options become clickable buttons; choosing one
appends it to the conversation and asks the AI for the follow-up, which
may carry new choices — the loop continues until Leave (always-escape,
fixed button, always available, even while the AI is thinking).
Sprite re-roll: a Re-roll sprite HUD button regenerates the current
NPC's sprite with a new seed (cache bust → fresh image → fresh
cut-out). The player's sprite is part of their identity and is never
re-rolled.
| Perchance | This branch |
|---|---|
Lists panel (main.pjs) | imports the AI plugins (generateImage, generateText) |
HTML panel (index.html) | loads the app bundle |
src/rpg/build/ | the compiled production bundle (rpg.js, rpg.css, chunks/) |
src/rpg/src/ | readable TypeScript source (for agent navigation) |
src/README.md | this file |
src/test-prompt.txt | the handoff prompt for each test round |
src/rpg/src/content/npcPool.ts); one is picked per new game.[choices] format: dialogue text, blank line, a line with exactly
[choices], then 1. <option> lines (max 4). The parser also degrades
gracefully when the AI omits the block.The game code boots against window.root:
root.generateImage(opts) → AI image generation (floor/backdrop textures
and RAW character sprites on a solid-white background with a baked ground
shadow)root.generateText(opts) → AI text generation (dialogue)Read src/test-prompt.txt first — it lists exactly what to check, click,
measure, and report for this round. The AI plugins only execute inside the
platform; the generator runs in a cross-origin iframe, so runtime validation
is your job.
Local development, tooling, CI, and specs live on the main branch of
https://github.com/Fahell/chronicles. This branch is generated by
./scripts/ship-perchance.sh — do not edit it by hand.
122 commits
TypeScript
82.8%
CSS
7.0%
JavaScript
5.3%
HTML
3.1%
Shell
1.8%