Repository navigation
EN Studio Assets
Français · Type: how-to · Audience: author · Context: local Studio · Status: ready · Applies from: 4.2.1
The local Studio · contract: stable · verified by CI (support matrix of 4.4.0, 2026-10-23): Chromium end to end (the Studio's checks); Windows: the unit suite only · automated checks: jobs
e2e,windows; CI plane2e,windows; 2 test files · people's passes:studio-hero-matrixnot run (#238) · known limits:demo-read-only
The Assets tab lists every image and sound of the game against what the game uses, gives each sheet its art prompt, and takes the generated images and sounds that replace or add to them, cutting sheets into cells, without ever deleting a file.
A generated sprite sheet cut into the cells the game names, a picture or a sound replaced with the old one kept beside it, and the game showing the new art once prepared.
The local Studio, in the engine repository or a created project. True from 4.2.1 (every upload is one operation of the game's journal). The demo Studio shows the listing read-only; a hosted Studio has the same tab with its own limits (below).
- The Studio running (overview).
- Python 3 with Pillow for cutting and keying (
tools/cut-sheet.py), ffmpeg for sounds, the image and audio toolchains: Image toolchain, Audio toolchain. - The art prompts and the sheet ids come from the game: Images: prompts, cutting sheets, transparency, scale.
In the browser, on the Assets tab. Prepare assets runs npm run assets for you, in the folder the Studio serves.
The tab lists everything under games/<id>/art/ and audio/ against what the game references
(tools/refs.ts), with the prompts of npm run prompts (tools/prompts.ts).
- Tree (left): Characters (one entry per sprite sheet, named after the character whose poses it holds), Objects, Backgrounds, Furniture, Talk kits, Sounds (music, sound effects). Badges: red = cells the game references without a file; orange = used but not prepared, or older than their source; grey = cut but unused.
-
Sheet (centre): the cells as thumbnails with their id and what uses them (
walk,portrait,items.key,house.props.pantry…); filters All / Used / Unused / Missing. On top, the Prompt panel: the sheet's section of the prompts with Copy prompt (the fenced block for the image model), Copy prompt for missing cells only when some are missing, and the shared Style block (folded) with its own Copy. - Cell (right): large preview, file, size, image ids, prepared or not, where it is used (with "Open room"), Replace…, and the backups.
- Backgrounds: the decor with the room's hotspots, props (foot and height), actors and walk area drawn over it, and the dashed floor band the prompt asks to keep empty; Replace… and "+ background".
-
Sounds: a player per file, where it is used, Replace… (same extension) and Add sound…. The music and sound ids
the game declares are listed whether or not a file exists;
npm run assetsships what is there and reports what is missing (Music).
- Pick the sheet in the tree, Copy prompt (or Copy prompt for missing cells only) and generate the image with your image model.
-
Upload generated sheet… sends the image with the sheet's id and grid (6 × 4 by default). It is saved under
private/sheets/<sheetId>-<time>.<ext>and cut bytools/cut-sheet.pyintoart/<sheetId>/. If cells of that sheet exist already, a dialog lists them, each with a recut box: unticked, the cell is kept and only the new cells are cut. The cut result is shown. For a sheet that has no folder yet, use Upload sheet into a new sheet id… in the toolbar.
- To change one picture, select the cell and Replace…. Keying: a flat background is keyed by default; choose "always" or "never" to force it. A decor (PNG or JPEG) is replaced the same way from Backgrounds, a sound from Sounds (any format ffmpeg reads, same extension).
- Prepare assets (npm run assets) in the toolbar runs the pipeline with its output live in a drawer; the count next to it is what it would process. Afterwards the Rooms view reloads. A replaced cell shows in the game once prepared.
Guarantee ·
no-silent-recut· referenced · scope self-checked by the author (AI), not reviewed An upload that would recut existing cells without naming them is refused with 409 and the list of those cells. An upload that names a cell recuts only that cell, and the old file is kept as<name>_v<N>first.
Nothing is deleted: a replaced sound or decor is kept as <name>_v<N> too.
Backups are not cells: the listing and the prompts ignore them.
Limit ·
demo-read-onlyIn the demo Studio the listing comes from the snapshot (assetsinsnapshot.json), the thumbnails and sounds from the prepared files ofpublic/assets(unused cells have no preview); uploads and Prepare are hidden.
Applies from 4.2.3
The same tab, served by the Studio Server under /api/assets. Uploads are bounded (10 MiB; PNG, JPEG or WebP images,
Ogg, MP3 or WAV sounds, recognised from their bytes); the cutting, the keying and Prepare assets (on the server)
are jobs of the processing worker, under the project's exclusive lease, shown in a small panel with a Cancel
button (a job cancelled before its write leaves nothing). The uploaded sheet itself is not kept there. See
Hosted assets.
The cell's badge leaves red; after Prepare it leaves orange; the cell shows in the game. git status shows the new
files under art/<sheetId>/ and the _v<N> backups beside them.
| Symptom | Cause | Fix |
|---|---|---|
409 with conflicts on an upload |
Cells of that sheet exist and were not named | Tick recut for the cells to replace, or leave them kept |
`sheetId` must be letters, digits, _ and - (not "decor") |
A bad sheet id | Use the game's sheet id |
| A replaced cell does not show in the game | Not prepared yet (orange badge) | Prepare assets |
| The cut fails | Python 3 or Pillow is missing | Image toolchain |
games/<id>/art/<sheetId>/<cell>.png and their _v<N> backups; art/decor/<name>.<ext>; audio/<music|sfx>/<file>;
the uploaded sheet under games/<id>/private/sheets/; the prepared files under public/assets/ after Prepare.
A replaced file is kept as <name>_v<N>: copy it back over the cell, or use git. Prepare can be run again at any
time.
- Server side:
tools/studio/assets.ts(mounted at/__studio/api/assets), the cutting intools/studio/cut.ts. The tab:src/studio/assets.tswith its model, IO and views beside it (assets-model.ts,assets-io.ts,assets-view.ts,assets-sheets.ts,assets-decors.ts,assets-sounds.ts); the Storyboard and Rooms tabs are laid out the same way since 4.1.8, every file under 800 lines. - The routes: Studio API.
Generated publication · publication générée — current documentation · documentation courante: quest'n'click 4.4.0 r1, documentation revision · révision de la documentation 8dc717c69acb62c4742b69c54a7e7dfb620f75d8.
Earlier versions and permalinks · versions précédentes et liens permanents: https://wanoo.github.io/quest-n-click/docs/
An edit made in this wiki is overwritten at the next publication · une modification faite dans ce wiki est écrasée à la publication suivante.
Edit the source · Modifier la source · Report an error · Signaler une erreur
Index (6)
Start (6)
Play (9)
Install (17)
- Requirements
- Install from the release archive
- Install from npm, once published
- Install from the repository to work on the engine
- doctor: checking your machine
- Image toolchain
- Audio toolchain: ffmpeg, fluidsynth, Furnace, uv
- Upgrade
- Upgrade notes: 4.4
- Upgrade notes: 4.3
- Upgrade notes: 4.2
- Upgrade notes: 4.1
- Upgrade notes: v3
- Upgrade notes: v2 to v3
- Coming from web-scumm
- Package reference
- Install troubleshooting
Create a game (55)
- Your first game
- Layout of a created project and of the engine repository
- The working loop
- Content principles and the identity contract
- Rooms
- Geometry: placement, walk zones, masks, layers, camera
- Something is visible but unreachable
- Reactions
- Game commands
- Conditions
- Flags, variables and events: which to use
- Custom code
- Characters
- Items and inventory
- World map
- Dialogues
- Scripts and events
- Moving characters: patrols and walks
- Exits
- Chapters and objectives
- State and saves: persistent or temporary, renaming an id, migrations
- Staging: wide rooms and animations
- The stage: lights, particles, floors
- Skin and fonts
- Title and credits
- Heroes: several characters and hero choice
- Built-in minigames
- A custom minigame
- Translations
- Music in stems
- Sound effects
- Voices: per language and per hero
- Images: prompts, cutting sheets, transparency, scale
- Asset provenance
- The storyboard, source of truth
- Puzzle design
- Classic mechanics
- Review pages
- DSL reference
- Checking your game
- What the solver proves
- Solver options
- Playtests
- Remix
- Speedrun for authors
- The sealed ending
- Production template
- Example games
- Working with an AI
- Build and release a game
- Publish on GitHub Pages
- The static game on Clever Cloud
- Other static hosts
- Sub-path, cache and service worker, incomplete deploys, going back
- Testing on a phone over the LAN
Local Studio (24)
- The local Studio: overview and launch
- Edit a room
- Placement and stage
- Preview, apply, undo
- Storyboard
- Assets and cutting
- Check: validator, solver, critical path, heat, health, coverage
- Before and after captures
- Semantic diff
- Play and replay a session
- Rule explainer
- Language and objectives
- Voices and the heroes × languages matrix
- Map
- Notes
- Remix in the Studio
- Music
- The Assistant: bring your own key
- Demo mode and studio-apply
- Local and LAN security
- Studio API
- Local MCP: setting up each client
- MCP tools
- Studio troubleshooting
Team Studio (21)
- What runs where
- Concepts: revision, transaction, span, lease, preview, build
- Starting as an invited dev
- Working together day to day
- Roles and actions: the full matrix
- Invitations
- Managing members
- Write refused on the hosted Studio: stale base revision (409)
- Write refused on the hosted Studio: span locked (423)
- Recovering after a lost lease, a disconnection or a stale preview
- Comments
- Map and semantic diff
- Publishing builds
- Remote MCP
- The game in Git
- Upgrading the engine of a hosted game
- Hosted assets
- The server's command line
- Health and metrics routes
- Trying it locally with compose.yml
- Known limits
Clever Cloud (23)
- Clever Cloud: overview, cost and prerequisites
- Apps and add-ons
- Domains and TLS
- Keycloak
- Generic OIDC and GitLab
- Configuration
- First deployment
- Backups
- RPO and RTO
- Restore the Studio on a fresh installation
- Redeploys
- Upgrading the server and checking state after a migration
- Limits of going back
- Monitoring
- Security
- Rotating keys
- Recovering admin access
- Changing domain or OIDC provider
- Worker, PostgreSQL or Cellar down
- Exporting the game and leaving the installation
- Retention
- Clever Cloud troubleshooting
- Costs and teardown
Reality Bridge and connectors (16)
- The Reality Bridge: what it is
- Quick start
- Guarantees
- Install and run the Bridge
- Backup and restore
- Several tenants
- Signals and the manifest
- The Bridge's command line
- Connectors overview
- Email connector
- Telnet connector
- SSH connector
- Open Badges connector
- The connector SDK
- Security: Biscuit and signatures
- Bridge and connector troubleshooting
Contribute (25)
- Welcome
- Developer setup
- The dev loop
- Before a pull request
- Conventions
- Writing documentation
- Architecture
- Code tour
- Import boundaries
- Which tests run when
- Mutation testing
- The coverage ratchet
- The quality baseline
- CI explained
- Field passes
- Benchmarks
- Releasing
- npm packages
- Decisions and ADRs
- Governance
- Bot pull requests
- Contributing with AI agents
- Security policy
- Code of conduct
- Licences and credits