Skip to content
quest'n'click

InstallHow-toFor authorsApplies from 4.3.0

Image toolchain

Cette page en françaisThis page on the GitHub wiki

The tools that turn generated or drawn sheets into a game's images are Python scripts the engine ships under tools/: they cut a sheet into sprites, choose its background, and prepare every image a game names for the browser. This page installs them and runs each once, in the engine repository and in a created project. What the art should look like, and how the prompts are written, is on Images.

What you get

Python and its pinned modules installed, a sheet cut into keyed sprites under your game's art/, and those sprites prepared into public/assets/ by npm run assets.

Context and versions

  • The engine repository (a game under games/<id>/) or a created project (the game under game/, the tools under node_modules/quest-n-click/tools/). The commands differ only by the path of the tool and its output.
  • From 4.3.0 the modules are Pillow 13.0.0, NumPy 2.4.6 and SciPy 1.18.1 (requirements.txt); with that upgrade the sample game's images came out byte for byte the same (4.3 notes).

Prerequisites

  • Python 3 (Requirements); CI uses 3.12.
  • A game, with its site.json (the template has one).
  • For sounds and videos in npm run assets: ffmpeg (Requirements).

Where to run the commands

At the root of the engine repository, or at the root of the created project. Each block says which.

Steps

  1. Install the pinned modules:

    # in the engine repository
    python3 -m pip install -r requirements.txt
    # in a created project
    python3 -m pip install -r node_modules/quest-n-click/requirements.txt
  1. Get one ready-to-paste prompt per sheet the game names, with the cut command of each (--missing for the sheets not cut yet). It writes prompts.md in the game's folder:

    # in the engine repository: games/<id>/prompts.md
    npm run prompts
    # in a created project: game/prompts.md
    npx quest-n-click prompts
  1. Cut a generated sheet into keyed sprites, <out>/<sheet-id>/r<row>c<col>.png (a 6 × 4 grid by default, --grid to change it, --auto for figures not on a grid):

    # in the engine repository: writes games/<GAME>/art/hero/
    python3 tools/cut-sheet.py hero_sheet.png hero
    # in a created project: name the output folder, the tool's default is the repository's games/<GAME>/art
    python3 node_modules/quest-n-click/tools/cut-sheet.py hero_sheet.png hero --out game/art

    With "artStyle": "pixel" in site.json (or --pixel), the cutter also scales each cell down 4× (--scale), limits it to 32 exact colours (--colors) and writes indexed PNGs; npm run assets then writes lossless WebP. A sheet on a transparent background ("sheetBackground": "transparent") is cut on its alpha, nothing keyed by colour.

  1. Choose the sheets' background, once per image tool:

    # in the engine repository (in a created project, prefix the tool with node_modules/quest-n-click/)
    python3 tools/check-alpha.py test_image.png
    python3 tools/pick-bg.py games/<id>/art/hero/

    check-alpha.py says whether an image tool writes real alpha: TRANSPARENT, FAKE CHECKERBOARD or OPAQUE. pick-bg.py takes sheets, sprite folders or reference images and ranks the flat colours by their distance to the drawing; its first line, BEST #RRGGBB, is the sheetBackground to use.

  1. Prepare every image and sound the content names:

    # in the engine repository, for the current game
    npm run assets
    # in a created project
    npm run assets

    tools/refs.ts lists what the content cites (rooms, characters, items, the map, minigame parameters, skin, the title and credits screens, ending.scratch, and index.ts's extraImages), then tools/assets.py prepares it into public/assets/. Only what changed is processed again. Where each image is read from, and sources.json to read it from elsewhere, are on Images.

Expected result, and how to check it

After step 3, the sheet's folder under art/ holds one PNG per cell. After step 5, public/assets/img/<sheet>/<cell>.webp exists for each image the content names, and assets prints a warning for each one it could not find: warning: missing images: … (and warning: missing sounds: …). No warning means every image the content names was prepared.

Common errors

SymptomCauseFix
ModuleNotFoundError: No module named 'PIL' (or numpy, scipy)Step 1 not done, or done for another PythonStep 1 with the python3 that runs the tools; in a created project, PYTHON=<path> makes assets use another interpreter
ModuleNotFoundError: No module named 'cv2'A talking-mouth tool needs OpenCV, not in requirements.txtInstall OpenCV's Python module yourself
The sprites land in games/<id>/art of a folder that does not existcut-sheet.py run in a created project without --outAdd --out game/art
warning: missing images: …The content names an image with no fileCut or add it, or fix the name in the content

Files or data changed

  • prompts.md in the game's folder (step 2).
  • art/<sheet-id>/ in the game's folder (step 3); --cells r1c2,r3c1 cuts only those cells again.
  • public/assets/ (not committed), the game's assets.gen.json (the pixel sizes of the prepared images) and .cache/refs.json (step 5).

Recovery or going back

Commit the game's art/ before cutting a sheet again: the cutter overwrites the cells it writes. public/assets/ is rebuilt from the sources by npm run assets at any time.

The talking-mouth tools

tools/talk-kit.py prepares a "talking kit" per character and pose (the validated sprite's head copied into a 3 × 2 grid), tools/talk-apply.py pastes the generated mouths back onto the sprite, and tools/talk-normalize.py makes one row of a talking sheet match the validated sprite. The last two import OpenCV (cv2).

References