Files
mazegame/projects/kissaten_yugure/docs/ART.md
T
jurjen.ladeniusandClaude Opus 5 60c9e13fa8 Art brief: give each asset type its own palette block
The palette constraint is not uniform across assets, so a single generic
line was not enough:

- Portraits list only the 11 non-sky colours, since a face never shows sky;
  omitting the sky slots is safer than asking a generator to avoid them.
  Adds the flat #492424 backdrop requirement (HMMM blits have no
  transparency, so whatever surrounds the head gets copied literally).
- The background block is split by region: four sky colours inside the
  window opening, eleven interior colours everywhere else, with the frame
  and mullions counted as interior wood. Also reserves the top 16 and
  bottom 64 rows the game draws over.
- Sprites take no palette at all — they are hardware sprites coloured at
  runtime, so the art only defines shape.

Notes that the available clothing colours are few enough that characters
need distinct ones or they blur together in the dialogue box.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-07-28 10:23:34 +02:00

230 lines
9.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Kissaten Yūgure — Art brief
Pipeline: **you generate in PixelLab from the prompts below, drop the PNGs in
`art/`, and I convert them to SCREEN 5 data.** I'll write the converter
(`tools/convert_art.py`) once the first real images land — there's working
precedent in `projects/mazegame/convert_screens.py`.
---
## 1. The palette — read this before generating anything
Everything in the game shares **one 16-colour palette**. It is already in
`kissaten.c` as `g_Palette` and is what the current build renders with.
- `art/palette.png` — 16×1 px, one pixel per entry. Machine-readable; use it
wherever PixelLab accepts a palette image.
- `art/palette_ref.png` — 512×64 swatch strip, same order, for eyeballing.
| # | Hex | Role | Notes |
|---|---|---|---|
| 0 | `#000000` | transparent | **Never paint with this.** It is the transparent index. |
| 1 | `#242424` | outline | near-black; outlines, dark hair |
| 2 | `#492424` | dark wood | deep shadow, dark brown hair |
| 3 | `#924924` | mid wood | wall panels, doors, deep skin shadow |
| 4 | `#B66D49` | light wood | counter top, **skin shadow** |
| 5 | `#FFB649` | lamp glow | warm light |
| 6 | `#FFDB92` | cream | glassware, **skin highlight** |
| 7 | `#6D4949` | muted wall | upper wall, muted cloth |
| 8 | `#492492` | dusk deep | **sky only** |
| 9 | `#9249B6` | dusk violet | **sky only** |
| 10 | `#DB6D6D` | dusk rose | **sky only** |
| 11 | `#FF9249` | horizon amber | **sky only** |
| 12 | `#6D2400` | coffee | coffee, dark red-brown cloth |
| 13 | `#496DB6` | coat blue | uniforms, coats |
| 14 | `#FFB692` | skin | **skin base** |
| 15 | `#FFFFDB` | warm white | highlights, cup rims, eye whites |
### The one non-negotiable rule
**Slots 811 are sky. Slots 47 are wood and warm interior.** Nothing else may
use 811.
This is what makes seasons and time-of-day free: the background bitmap is
authored once, and each season/hour is a 32-byte palette swap. If a character's
jacket is painted in slot 9, that jacket changes colour every time the sun
moves. Getting this wrong is not a cosmetic issue — it silently destroys the
whole seasonal system, and you don't find out until M7.
### Skin, specifically
There is only one literal "skin" entry, which is too thin for a face. Use
these three as a ramp — they're hue-compatible:
- highlight `#FFDB92` (6) → base `#FFB692` (14) → shadow `#B66D49` (4)
- deepest shadow / hair: `#924924` (3), `#492424` (2), `#242424` (1)
---
## 2. What I need back
| Asset | Size | Count |
|---|---|---|
| Character portrait | **48×48** | 3 per character (neutral / happy / troubled) |
| Shop background | **256×212** | 1 |
| Customer sprite | **16×16** | 2 layers per character (fill + outline) |
**PNG, generated natively at the target size — do not downscale a larger
image.** Downscaling pixel art produces half-pixels and anti-aliased edges
that cannot be quantised cleanly.
No anti-aliasing, no gradients, no dithering unless it's deliberate hard
checkerboard. If PixelLab can be constrained to the 16 colours, do that; if
not, generate close and I'll quantise — but the sky/wood slot rule above
still has to hold visually or the quantiser can't fix it.
**48×48 is very small** — roughly 6 pixels of eye. Faces need a strong
silhouette and simplified features. Detail that reads at 200×200 will turn to
mud. If a generation looks great zoomed out and illegible at 1:1, it's wrong.
---
## 3. Prompts — Aki (needed now, for M3)
Hoshino Aki, 17, studying for Tokyo entrance exams, cream soda drinker.
Character notes in `SCRIPT.md` §1. Written as a girl there; that's one word to
change if you'd rather — the dialogue beats themselves use no gendered
pronouns.
### Portrait palette block — paste into every portrait prompt
Portraits never show sky, so the four sky slots are simply absent from the
list. That is safer than asking the generator to avoid them.
```
Use only these 11 colours and no others:
#242424 #492424 #924924 #B66D49 #FFB649 #FFDB92 #6D4949 #6D2400
#496DB6 #FFB692 #FFFFDB
Skin: #FFDB92 highlight, #FFB692 base, #B66D49 shadow, #924924 deep shadow.
Hair and outlines: #242424 or #492424.
Eye whites and highlights: #FFFFDB.
Fill the entire background behind the head with flat #492424.
Do not use pure black #000000 anywhere.
```
**Common style stem** — prepend to all three, then append the palette block:
> 48x48 pixel art portrait, 1987 Japanese anime style as drawn for MSX2 or
> PC-88 games, head and shoulders, three-quarter view, hard-edged pixels, no
> anti-aliasing, flat cel shading, simple readable silhouette, flat single
> colour background
**Aki — neutral**
> ...17 year old Japanese high school student, straight dark bob-length hair,
> tired but polite expression, calm eyes, slight shadows under the eyes,
> looking slightly off to one side
**Aki — happy**
> ...17 year old Japanese high school student, straight dark bob-length hair,
> small genuine smile, eyes softened and slightly narrowed, faint blush,
> looking toward the viewer
**Aki — troubled**
> ...17 year old Japanese high school student, straight dark bob-length hair,
> eyes cast downward, faint frown, tense mouth, weary
---
## 4. Prompts — the rest of the cast (M8, not urgent)
Same style stem and the **same portrait palette block from §3**, swapping the
clothing line. Note the clothing colours available are only `#496DB6` (blue),
`#6D4949` (muted brown-grey), `#6D2400` (dark red-brown), `#492424` and
`#242424` — so give each character a distinct one or they'll blur together in
the dialogue box.
**Ōta-san** — retired stationmaster, ~70, black coffee, punctual.
> elderly Japanese man in his seventies, close-cropped grey hair, deeply
> lined face, upright bearing, plain dark jacket buttoned to the collar
- *neutral:* composed, formal · *happy:* faint dignified smile, eyes crinkled
- *troubled:* jaw set, looking past the viewer
**Fujimoto** — manga artist, ~30, exhausted, funny about it.
> Japanese manga artist in their thirties, messy shoulder-length hair, heavy
> shadows under the eyes, round glasses, rumpled shirt with sleeves pushed up
- *neutral:* wired, sleepless · *happy:* crooked grin, animated
- *troubled:* hollow stare, hand near face
**Nakajima-san** — widow, ~65, orders two coffees.
> Japanese woman in her mid-sixties, silver hair pinned back neatly, soft
> composed face, high-collared blouse under a plain cardigan, small pearl
> earrings
- *neutral:* serene, self-possessed · *happy:* warm gentle smile
- *troubled:* distant, looking at something not in the room
---
## 5. Prompt — the shop background (M6, longest lead time)
256×212. This one carries the game's whole look and is the hardest to redo,
so it's worth several attempts.
Composition is fixed by the code — see `DESIGN.md` §4 and `DrawScene()`:
- Top **16px** is the status bar (drawn over) — keep it empty/dark.
- **y=16148** is the shop scene.
- Bottom **64px** is the dialogue window (drawn over) — keep it empty/dark.
- Window on the **left** (~x1688), showing dusk sky in slots 811 only.
- Door on the **right** (~x208244).
- Counter running horizontally at **y≈98**, its top edge level.
- Hanging lamp above the counter, centre.
- Siphon coffee rig sits on the counter left of centre — I can keep drawing
this procedurally if it's easier to leave out.
> 256x212 pixel art interior of a small 1987 Japanese kissaten coffee shop at
> dusk, viewed straight on, static single-screen game background, wooden
> counter running across the lower third, tall window on the left showing a
> violet and amber dusk sky, wooden door on the right, hanging lamp with warm
> glow above the counter, wood panelling, shelves with glassware, cosy and
> quiet, 1987 MSX2 game art, hard-edged pixels, no anti-aliasing, flat cel
> shading
### Background palette block — this one is split by region
Unlike the portraits, the background needs all 15 colours — but **which
colours may appear is decided by where you are in the image**. This is the
constraint that makes seasons free, and it is the easiest one to get wrong.
```
Use only these 15 colours and no others.
For the sky visible through the window, use ONLY these four:
#492492 #9249B6 #DB6D6D #FF9249
For everything else — walls, floor, counter, door, window frame, lamp,
shelves, glassware, every object in the room — use ONLY these eleven:
#242424 #492424 #924924 #B66D49 #FFB649 #FFDB92 #6D4949 #6D2400
#496DB6 #FFB692 #FFFFDB
The four sky colours must appear nowhere except inside the window opening.
The window frame, mullions and sill are wood and use the interior colours.
Do not use pure black #000000 anywhere.
Leave the top 16 rows and the bottom 64 rows flat #242424 — the game draws
its own status bar and dialogue box over them.
```
**Why this one rule matters more than the rest of this document:** each season
and hour of day is a 32-byte palette swap on the same bitmap. Repaint slots
811 and the sky goes from dusk to noon to rain for free. But if a chair leg
or a coffee cup is painted in `#9249B6`, that chair leg changes colour every
time the sun moves — and you won't find out until M7, long after the art is
finished.
---
## 6. Sprites (M6)
16×16, two layers per customer: a **fill** layer and an **outline** layer that
is the same silhouette dilated by one pixel, drawn behind. Sprite mode 2, so
each layer is a single colour — these are shapes, not shaded art. Current
placeholders are in `kissaten.c` as `g_SprCustFill` / `g_SprCustLine`.
**Palette does not apply here in the usual sense.** These are hardware
sprites, not bitmap art: each layer is one flat colour chosen at runtime by
the code, so the image only needs to define *shape*. Draw them as pure
black-on-white silhouettes and I'll assign colours — currently `#496DB6` for
the fill layer and `#242424` for the outline, per customer.
Worth doing by hand rather than generating; a 16×16 single-colour silhouette
is faster to draw than to prompt for.