How the game looks, sounds and feels. docs/plan.md
covers what the game is; this covers how it should read on screen. “Now”
is what exists in the code today; Proposal is a
direction for Foster to approve or change.
Mockups and palettes are recolours of a real gate frame (Lantern
Town, two players), so they show the existing art under each direction,
not new art. They live in docs/design/; the guide is
published at https://design.delve.fdhproperty.com.
Pillars
Readable at a glance: a player, a monster and a
platform are never confused.
A place you return to: each zone has its own light,
palette and sound.
Warm, not grim: cosy town and danger that is
pretty, not gory.
Feel first: movement and hits are tuned to numbers
and kept by bots.
Setting and tone
The names so far, Lantern Town, Mossy Field and the Cinder Eye,
already lean toward light against the dark.
A. Lantern Dusk (recommended). A world at permanent
dusk where towns are lit by lanterns and the wilds by embers, spirits
and moss glow. The light is the theme: zones get darker and stranger
with level, and the boss is a fire that wants the lanterns. It suits the
light map we already have and makes zones easy to tell apart.
B. Bright Meadow. MapleStory’s sunny daytime:
saturated, cheerful, closest to today’s look. Lowest risk, least
distinctive.
C. Mossy Ruins. Muted, overgrown ruins of an older
civilisation. Moody and coherent, but it fights pillar 3 and reads
poorly on small phone screens.
Pixel scale (locked)
Now: 16 px tiles, a 12×22 player, camera zoom 2, a
960×540 viewport with canvas_items stretch and nearest
filtering. So one art pixel is two screen pixels and the view is 480×270
art pixels, 30×17 tiles.
Rule: every sprite, tile and icon is drawn at that
one density. No scaled-up or scaled-down art, no mixed resolutions, no
rotation of pixel art except swinging held items (already done in
player_view.gd).
Positions snap to whole art pixels when drawn.
Proposal: turn on
rendering/2d/snap/snap_2d_transforms_to_pixel so
interpolated players never sit on half pixels.
Palette
Now: colours live in code
(player_art.gd, art.gd, hud.gd),
about 60 hand picked hex values, a flat sky #6ea6db, no
background.
Proposal: one shared palette file
(game/render/palette.gd) that every drawn colour comes
from, 32 colours at most, with per-zone ramps picked from it.
Option A’s core twelve (the full 32 extend each with a light and a
dark step):
Name
Hex
Use
Ink
#1c1a2e
outlines, text shadow, deepest shade
Dusk
#2b2f5a
upper sky, far hills, UI panels
Mauve
#7a5a8c
mid sky, distant layers
Ember
#f2a65a
horizon, warm rim light
Lantern
#ffd27a
light sources, highlights, hint text
Cinder
#e0532f
danger, the boss, damage taken
Moss
#5f9e4a
grass, field foliage
Leaf
#9ccf5a
foliage highlight, healing
Soil
#7a5236
dirt, wood
Stone
#6d6f78
brick, rock
Parchment
#f3e6c8
UI text, paper, bone
Spirit
#8a70ff
portals, magic, rare items (portals already use it)
palette A
Light
Now: a per-tile flood-fill light map
(lighting.gd): sky light and torches, decaying 0.9 per open
tile and 0.78 per solid tile.
Proposal: keep it and add a per-zone ambient colour
and level (town 0.85 warm, fields 0.75, deeper fields lower, boss map
0.4 lit by the boss). Light sources (lanterns, torches, portals, the
Cinder Eye) carry their own tint. Players carry a small light so a dark
zone is never unplayable.
Characters and monsters
Outlines: a 1 px outline in a darkened version of
the sprite’s own colour, not pure black. Tiles have no outline. This is
how sprites pop off busy backgrounds.
Silhouettes: every monster must be identifiable as
a black shape. Size bands in art pixels, from today’s sprites:
Band
Size
Now
Small
~12–16 px
slime 15×14, cave bat 24×12 (wide but thin)
Player-sized
~12×22
the player, skeleton 15×22
Elite (proposal)
24–32 px
none yet
Boss
40+ px
Cinder Eye 39×40
Animation frames (proposal; the player has 4 today: idle,
stride, step, jump): idle 2–4, walk 4–6, jump 1 up + 1 down,
climb 2, attack 3–4, hurt 1, death 4. Monsters: move 2–4, attack 2–3,
hurt 1. At 60 Hz, 6–8 ticks per frame.
Players: the same body for everyone; identity comes
from equipment layers (hat, top, bottom, shoes, weapon), as in
MapleStory. That needs the body split into layers before gear lands in
M6d.
Environment
Tiles: 16 px, top edge always lighter than the
body, grass caps on exposed dirt (already done), one-way platforms
visibly thinner than solid ground, climbables (ladders, ropes) a
distinct warm colour that stands out from the background.
Backgrounds (proposal; none today): a sky gradient
plus 2–3 parallax layers at 0.2, 0.4 and 0.6 of camera speed, drawn in
the zone’s far colours with no outlines and lower contrast than gameplay
tiles. Gameplay layers stay the highest contrast.
Per-zone shift: each zone picks sky stops, two hill
colours, an ambient light and an accent from the palette. Town: warm
lanterns. Mossy Field: green and lantern-gold. Higher fields: cooler,
dimmer, more Spirit. Boss map: Ink and Cinder.
UI and HUD
Now: Godot’s fallback font at 8–12 px, navy slots
(0.16, 0.2, 0.42, 0.85), gold selection
(0.85, 0.68, 0.2), hearts for life, a boss bar
(0.95, 0.42, 0.12), damage popups
DAMAGE_COLOR #ffd94d and HURT_COLOR #ff5959
(main.gd) rising 18 px over 1.2 s.
Proposal:
A pixel font at one size (8 px art, 16 px on screen) plus a bold
variant for names and numbers. Candidates must be OFL: m5x7/m6x11 (free,
permissive) or Silver. Text gets a 1 px Ink outline, never a drop
blur.
Panels: Dusk at 90% with a 1 px Parchment border at 30%, 2 px corner
cut. No gradients, no rounded vector corners.
HP and MP as bars (MapleStory), replacing hearts: HP Cinder, MP a
blue from the palette, XP Lantern along the bottom edge.
Damage numbers: dealt in Lantern, taken in Cinder, crits bigger and
Ember, heals in Leaf; rise 18 px and fade over 0.8 s.
Every HUD element must be readable at a 375 px wide phone screen
(P3).
Game feel (now, then targets)
Thing
Now (zone.gd, combat.gd)
Target
Walk
90 px/s, 900 px/s² ground, 450 air
keep
Jump
280 px/s up, gravity 900: 44 px high (2.7 tiles), 0.62 s
airborne
keep; add 6-tick coyote time and a 6-tick jump buffer
Fall
max 420 px/s
keep
Climb
70 px/s, 0.6 sideways
keep
Knockback
enemies (130, −140), player (160, −160)
keep
Invulnerable after a hit
0.67 s, blinking
keep
Hit-stop
none
50 ms on a hit, 100 ms on a kill or crit, both sides freeze
Screen shake
none
2 px for 120 ms on player hurt, 4 px on boss hits
Hit flash
hurt timer tints enemies
1 frame white, then the tint
Hit-stop and shake are client-only presentation online, so they never
touch the sim’s determinism. Bots check the movement numbers stay
put.
Audio (proposal; the
game is silent today)
Music: one loop per zone, calm in town, a pulse in
fields, full drums at the boss. Acoustic with soft synths to suit dusk:
guitar, marimba, pads.
SFX: short and dry: swing whoosh, hit thud, kill
pop, pickup chime, level-up fanfare, portal hum, footsteps per surface.
Every hit has a sound.
Sources: CC0 or bought packs first (Kenney, Sonniss
GDC bundles), then commissioned music once the zones are settled.
Nothing AI-generated in shipped audio until rights are clear.
Asset pipeline
Code-drawn (now): tiles, item icons and the player
are pixel masks in GDScript (art.gd,
player_art.gd). Fast, diffable, consistent; fine for tiles
and icons.
Local mflux (now): monster sprites came from local
mflux generation, cut out and downsized to the pixel grid. It works with
no API key; the lanternfall proof showed the same. Every generated
sprite is cleaned up by hand or script to the palette and outline rules
before it ships.
Rules: everything lands on the pixel grid and the
palette; sources and prompts for generated art are committed next to the
PNG; third-party assets only under CC0, CC-BY (credited in
CREDITS.md) or a bought licence that allows redistribution
in a game; no assets traced from MapleStory or Terraria.
Proposal: a tools/art/ check in the
gate that fails a sprite with colours off the palette or a size off its
band.
Open choices for Foster
Setting and tone: A Lantern Dusk, B Bright Meadow or C Mossy
Ruins.
Palette: lock option A’s 32 colours, or a stock palette
(e.g. Resurrect 64).
HP and MP bars instead of hearts.
Pixel font: m5x7/m6x11, or commission one.
Art source for M6d–M6g: keep mflux plus cleanup, buy a pack, or
commission a pixel artist for the player and gear layers.
Audio: packs now and commission later, or commission a composer
early.