387 lines
16 KiB
Markdown
387 lines
16 KiB
Markdown
# Master of Vega — art spec
|
||
|
||
Every sheet below is **optional**. Each one starts with `"path": null` in
|
||
`data/mastervega-artwork.json`, and `VegaArt.js` paints a procedural stand-in
|
||
with the identical frame layout — the game is fully playable with zero art
|
||
files. To use real art: drop the PNG in `assets/images/vega/` and set its
|
||
`path` in the artwork JSON. **No code changes are needed.**
|
||
|
||
Frame indexes are **APPEND-ONLY**. Never renumber an existing frame — the
|
||
indexes are baked into `data/mastervega-rules.json` and shifting them silently
|
||
mismaps every piece of artwork already drawn.
|
||
|
||
Status: ⬜ = not painted yet (procedural fallback in use).
|
||
|
||
Two different pictures of a planet are used and they are **not** interchangeable:
|
||
the `planets` sheet (§2) is a transparent 192 px disc for the orrery, and the
|
||
world backdrops (§2b) are opaque 1920 × 1080 scenes for the colony screen.
|
||
|
||
---
|
||
|
||
## 1. `ships` — ✅ `assets/images/vega/ships.png`
|
||
|
||
| | |
|
||
|---|---|
|
||
| Sheet size | **1536 × 1920** |
|
||
| Frame | **192 × 192** |
|
||
| Grid | 8 cols × 10 rows = 80 frames |
|
||
|
||
**One row per species, one column per hull.** Frame = `species.shipFrame × 8 + hull.frame`.
|
||
|
||
Columns (hull):
|
||
|
||
| Col | Hull | Notes |
|
||
|---|---|---|
|
||
| 0 | Scout | Small, fast, unarmed |
|
||
| 1 | Colony Ship | Bulbous, carries a habitat pod |
|
||
| 2 | Troop Transport | Boxy, no guns |
|
||
| 3 | Frigate | Smallest warship |
|
||
| 4 | Destroyer | Mid warship |
|
||
| 5 | Cruiser | Heavy warship |
|
||
| 6 | Battleship | The big one — should read as huge even at 24px |
|
||
| 7 | Star Base | Immobile orbital fortress; a ring/station, not a ship |
|
||
|
||
Rows (species): 0 Human, 1 Kestrelli, 2 Ursaal, 3 Umbrix, 4 Kkrix, 5 Mekhan,
|
||
6 Rrashaa, 7 Cerebrai, 8 Ssakar, 9 Lithox.
|
||
|
||
**Ships face UP.** The battle screen rotates them ±90° so the two sides face each
|
||
other. Each species has a colour in the rules file — art can ignore it (the
|
||
sprite is used as-is) or lean into it.
|
||
|
||
Only the human row is painted so far; the other nine fall back to the procedural
|
||
stand-in, which is cut at the same 192px geometry.
|
||
|
||
> The **thumbnails and the detail window turn the hull a full 180°** — a
|
||
> deliberate look, not a correction. `makeShipIcon` in `VegaShipMedia.js` is the
|
||
> one place that does it, with `setAngle(180)` rather than `setFlipY`: a flip
|
||
> would mirror the hull's asymmetries, a rotation does not.
|
||
|
||
---
|
||
|
||
### 1b. Ship commander videos — 🟨 `assets/videos/vega/ship-<species>-<hull>.mp4`
|
||
|
||
**Not part of the sheet.** One looping **256 × 256** muted clip per species *per
|
||
hull* — the officer who flies that class — shown beside the hull on every ship
|
||
row and at full size in the detail window.
|
||
|
||
Declared in `shipVideos` in `data/mastervega-artwork.json`, nested
|
||
`species → hull id → { key, path }`. A species with none recorded is a single
|
||
`null`. Same drop-in contract as everything else: drop the files, add the lines,
|
||
no code changes.
|
||
|
||
The fallback ladder is one tier deeper than the species portraits:
|
||
|
||
1. this species' clip for this hull — `shipVideos[species][hull]`
|
||
2. the species' own portrait video — `portraitVideos[species]` (§ below)
|
||
3. its 1024px still — `portraitStills[species]`
|
||
4. a frame on the procedural `portraits` sheet
|
||
|
||
So a gap is never a hole: every row shows a moving face from day one, and each
|
||
new race lights up one clip at a time. `starbase` has no clip for anyone and is
|
||
expected to keep falling through.
|
||
|
||
| Hull id | File suffix | Human |
|
||
|---|---|---|
|
||
| `scout` | `ship-human-scout.mp4` | ✅ |
|
||
| `colonyship` | ⚠️ `ship-human-**colony**.mp4` | ✅ |
|
||
| `transport` | `ship-human-transport.mp4` | ✅ |
|
||
| `frigate` | `ship-human-frigate.mp4` | ✅ |
|
||
| `destroyer` | `ship-human-destroyer.mp4` | ✅ |
|
||
| `cruiser` | `ship-human-cruiser.mp4` | ✅ |
|
||
| `battleship` | `ship-human-battleship.mp4` | ✅ |
|
||
| `starbase` | — | ⬜ falls back |
|
||
|
||
> ⚠️ The colony ship's file is `ship-human-colony.mp4` while its hull id is
|
||
> `colonyship`. Same class of mismatch as `char-cerebai.mp4`: the manifest points
|
||
> at the real filename and the verifier confirms both the file and the derived
|
||
> texture key, so wiring it the wrong way round fails immediately rather than
|
||
> 404ing in the browser.
|
||
|
||
Rows: kestrelli, ursaal, umbrix, kkrix, mekhan, rrashaa, cerebrai, ssakar and
|
||
lithox are all ⬜ — nine species × seven hulls outstanding.
|
||
|
||
---
|
||
|
||
## 2. `planets` — ⬜ `assets/images/vega/planets.png`
|
||
|
||
| | |
|
||
|---|---|
|
||
| Sheet size | **960 × 576** |
|
||
| Frame | **192 × 192** |
|
||
| Grid | 5 cols × 3 rows = 15 frames |
|
||
|
||
One frame per planet type, in rules order. Draw the planet as a **centred disc**
|
||
filling ~84% of the frame, transparent outside it — the orrery and system view
|
||
both place these on a black background and scale them.
|
||
|
||
| Frame | Type | Look |
|
||
|---|---|---|
|
||
| 0 | Terran | Blue oceans, green continents, white cloud |
|
||
| 1 | Ocean | Almost entirely water, scattered islands |
|
||
| 2 | Jungle | Deep green, permanent cloud banding |
|
||
| 3 | Steppe | Olive grassland, thin atmosphere |
|
||
| 4 | Arid | Tan, dry riverbeds |
|
||
| 5 | Desert | Orange sand seas, no water |
|
||
| 6 | Tundra | Pale blue-grey, heavy ice caps |
|
||
| 7 | Minimal | Grey-green, very thin air |
|
||
| 8 | Barren | Airless grey rock, craters |
|
||
| 9 | Dead | Darker, cracked, lifeless |
|
||
| 10 | Inferno | Molten orange, volcanic |
|
||
| 11 | Toxic | Sickly yellow-green fog |
|
||
| 12 | Radiated | Livid yellow-green, glowing |
|
||
| 13 | Gas Giant | Banded, a storm spot — **not colonisable** |
|
||
| 14 | Asteroid Belt | Scattered rocks, no disc — **not colonisable** |
|
||
|
||
---
|
||
|
||
### 2b. World backdrops — ✅ mostly painted, `assets/images/vega/world-<type>-01.png`
|
||
|
||
**Not part of the `planets` sheet.** These are full-screen **1920 × 1080 opaque**
|
||
backdrops for the colony screen (`VegaColonyView.js`) — the same worlds seen from
|
||
the ground rather than from orbit. The sheet above stays what it is: transparent
|
||
192 px discs for the orrery.
|
||
|
||
Declared per planet type in `worldBackgrounds` in `data/mastervega-artwork.json`,
|
||
exactly like the species stills. A `null` path is a legitimate "not painted yet"
|
||
and falls back to a gradient built from that type's `color` in the rules file, so
|
||
the set can be finished one world at a time with no code change.
|
||
|
||
The `-01` suffix is a **variant slot** — nothing reads a variant index yet, but
|
||
the naming leaves room for `world-terran-02.png` and a roll.
|
||
|
||
| Type | File | |
|
||
|---|---|---|
|
||
| Terran | `world-terran-01.png` | ✅ |
|
||
| Ocean | `world-ocean-01.png` | ✅ |
|
||
| **Jungle** | — | ⬜ **outstanding** |
|
||
| Steppe | `world-steppe-01.png` | ✅ |
|
||
| Arid | `world-arid-01.png` | ✅ |
|
||
| Desert | `world-desert-01.png` | ✅ |
|
||
| Tundra | `world-tundra-01.png` | ✅ |
|
||
| Minimal | `world-minimal-01.png` | ✅ |
|
||
| Barren | `world-barren-01.png` | ✅ |
|
||
| Dead | `world-dead-01.png` | ✅ |
|
||
| Inferno | `world-inferno-01.png` | ✅ |
|
||
| Toxic | `world-toxic-01.png` | ✅ |
|
||
| Radiated | `world-radiated-01.png` | ✅ |
|
||
| Gas Giant | ⚠️ `world-gas-**giant**-01.png` | ✅ |
|
||
| Asteroid Belt | — | ⬜ not needed — neither type is colonisable, so the colony screen never opens on one |
|
||
|
||
> ⚠️ The gas giant's filename is `world-gas-giant-01.png` **with a hyphen** while
|
||
> its rules id is `gasgiant`. Same class of mismatch as `char-kestralli.png`: the
|
||
> manifest points at the real filename, and the verifier fails immediately if a
|
||
> declared path stops resolving.
|
||
|
||
Text is drawn over the top-left of these (name, owner, world details) with a drop
|
||
shadow, and the right ~500 px sits under a semi-transparent panel — so keep the
|
||
top-left readable and do not put the subject of the picture on the far right.
|
||
|
||
---
|
||
|
||
## 3. `stars` — ⬜ `assets/images/vega/stars.png`
|
||
|
||
| | |
|
||
|---|---|
|
||
| Sheet size | **576 × 576** |
|
||
| Frame | **192 × 192** |
|
||
| Grid | 3 cols × 3 rows = 9 frames |
|
||
|
||
One frame per star class, in rules order: 0 Blue, 1 White, 2 Yellow, 3 Orange,
|
||
4 Red, 5 Brown Dwarf, 6 Binary, 7 Pulsar, 8 Black Hole.
|
||
|
||
Drawn with **ADD blending** on the star map (except the black hole, which is
|
||
drawn normally) — so paint them **glowing on transparent black**, with the
|
||
corona fading to fully transparent at the frame edge. The star map rotates the
|
||
pulsar frame continuously and orbits a scaled copy of the binary frame, so keep
|
||
the pulsar's beam axis vertical and the binary's companion at the frame centre.
|
||
|
||
---
|
||
|
||
## 4. Species portraits — **video**, with a sheet fallback
|
||
|
||
Portraits are **looping, muted 256 × 256 videos**, one per species, at
|
||
`assets/videos/vega/char-<speciesId>.mp4`. They play silently on a loop wherever
|
||
a species portrait appears — the setup screen's species cards (84 px), the
|
||
species detail pop-over (**full 256 px**), and the diplomacy screen (96 px).
|
||
|
||
Clicking a card grows it into a centred pop-over showing the portrait at native
|
||
resolution. The card's portrait is *reparented* into the pop-over rather than a
|
||
second one being created, so there is only ever one video object per species.
|
||
|
||
**To add one:** drop the file in, then change that species' `path` from `null`
|
||
to it in `portraitVideos` in `data/mastervega-artwork.json`. Nothing else. The
|
||
verifier checks every species has an entry, that the key matches, and that every
|
||
non-null path points at a file that exists.
|
||
|
||
**All ten species have both a video and a still.** ✅
|
||
|
||
| Species | Video (256 × 256) | Still (1024 × 1024) |
|
||
|---|---|---|
|
||
| Human | `char-human.mp4` | `char-human.png` |
|
||
| Kestrelli | `char-kestrelli.mp4` | ⚠️ `char-kestr**a**lli.png` |
|
||
| Ursaal | `char-ursaal.mp4` | `char-ursaal.png` |
|
||
| Umbrix | `char-umbrix.mp4` | `char-umbrix.png` |
|
||
| Kkrix | `char-kkrix.mp4` | `char-kkrix.png` |
|
||
| Mekhan | `char-mekhan.mp4` | `char-mekhan.png` |
|
||
| Rrashaa | `char-rrashaa.mp4` | `char-rrashaa.png` |
|
||
| Cerebrai | ⚠️ `char-cereb**a**i.mp4` | `char-cerebrai.png` |
|
||
| Ssakar | `char-ssakar.mp4` | `char-ssakar.png` |
|
||
| Lithox | `char-lithox.mp4` | `char-lithox.png` |
|
||
|
||
### Fallback order
|
||
|
||
Three tiers, best first — no caller knows which it got, so the roster can be
|
||
finished a species at a time with no code changes:
|
||
|
||
1. **Video** — `assets/videos/vega/char-<id>.mp4`, listed in `portraitVideos`.
|
||
2. **Still** — `assets/images/vega/char-<id>.png` (1024 × 1024), listed in
|
||
`portraitStills`. Used when there is no video, and as the recovery path if a
|
||
video is present but the browser refuses to decode it.
|
||
3. **Painted sheet** — the optional ⬜ `assets/images/vega/portraits.png`
|
||
(1280 × 512, 256 × 256 frames, 5 × 2, one per `species.portraitFrame` in the
|
||
ship-row order), which itself falls back to a procedural painting.
|
||
|
||
> ⚠️ **Two filenames do not match their species id**, each with a correctly
|
||
> spelled counterpart: the kestrelli *still* is `char-kestralli.png`, and the
|
||
> cerebrai *video* is `char-cerebai.mp4` (no `r`). The manifest points at the
|
||
> real filenames so both work as-is — rename a file and its one path together
|
||
> if you want the spelling fixed. The verifier fails immediately if a declared
|
||
> path stops resolving, so a rename cannot go unnoticed.
|
||
|
||
These are **species portraits, not characters** — this game deliberately does
|
||
not use the `data/opponents.json` roster or its videos.
|
||
|
||
| Frame | Species | Identity |
|
||
|---|---|---|
|
||
| 0 | Human | Traders and diplomats |
|
||
| 1 | Kestrelli | Avian aristocrats, superb pilots |
|
||
| 2 | Ursaal | Ursine heavy-worlders |
|
||
| 3 | Umbrix | Shapeshifters, spies, universally distrusted |
|
||
| 4 | Kkrix | Insect hive, tireless industry |
|
||
| 5 | Mekhan | Cyborgs, factories everywhere, filthy |
|
||
| 6 | Rrashaa | Feline gunners |
|
||
| 7 | Cerebrai | Vast fragile intellects |
|
||
| 8 | Ssakar | Reptilian broodmothers |
|
||
| 9 | Lithox | Crystalline, breathe nothing, colonise anywhere |
|
||
|
||
---
|
||
|
||
## 5. `leaders` — ⬜ `assets/images/vega/leaders.png`
|
||
|
||
| | |
|
||
|---|---|
|
||
| Sheet size | **640 × 640** |
|
||
| Frame | **160 × 160** |
|
||
| Grid | 4 cols × 4 rows = 16 frames |
|
||
|
||
One frame per leader (`leader.portraitFrame`), rules order. Frames 0–7 are
|
||
colony administrators, 8–15 are ship captains. Shown at 40–60 px.
|
||
|
||
---
|
||
|
||
## 6. `buildings` — ⬜ `assets/images/vega/buildings.png`
|
||
|
||
| | |
|
||
|---|---|
|
||
| Sheet size | **512 × 128** |
|
||
| Frame | **64 × 64** |
|
||
| Grid | 8 cols × 2 rows = 16 frames |
|
||
|
||
One frame per building (`building.frame`), rules order: Automated Factory,
|
||
Research Laboratory, Missile Base, Pollution Processor, Space Port, Cloning
|
||
Center, Ground Battery, Spy Center, Planetary Shield, Terraforming Plant, Stock
|
||
Exchange, Holo Simulator, Robotic Miners, Super Computer, Artemis System Net,
|
||
Enrichment Facility.
|
||
|
||
---
|
||
|
||
## 7a. `techfields` — ⬜ `assets/images/vega/techfields.png`
|
||
|
||
| | |
|
||
|---|---|
|
||
| Sheet size | **144 × 96** |
|
||
| Frame | **48 × 48** |
|
||
| Grid | 3 cols × 2 rows = 6 frames |
|
||
|
||
One frame per tech *field* (`techFields[].iconFrame`), rules order: Computers,
|
||
Construction, Force Fields, Planetology, Propulsion, Weapons. Exact fit, no
|
||
spares.
|
||
|
||
Split out of the old combined `techicons` sheet (§7b) so the six field icons
|
||
— larger, simpler glyphs meant to read at a glance on the research screen —
|
||
can be painted and sized independently of the ~90 individual tech icons.
|
||
Nothing in the game draws a field icon yet; this sheet exists for whenever
|
||
that lands.
|
||
|
||
---
|
||
|
||
## 7b. `techicons` — ⬜ `assets/images/vega/techicons.png`
|
||
|
||
| | |
|
||
|---|---|
|
||
| Sheet size | **480 × 480** |
|
||
| Frame | **48 × 48** |
|
||
| Grid | 10 cols × 10 rows = 100 frames |
|
||
|
||
One frame per individual tech (`techs[].iconFrame`), 0–90, in the order techs
|
||
appear in `data/mastervega-rules.json` — the original 60 plus two later
|
||
MOO1-branching passes. 91–99 spare (the tech list has grown once already;
|
||
expect it to again). Drawn today by `VegaGnnScreen.js`'s tech-breakthrough
|
||
story page.
|
||
|
||
---
|
||
|
||
## 8. Menu icon — ✅ `assets/images/game-icons.png` frame **92**
|
||
|
||
The shared 660 × 660 sheet, 44 × 44 cells, 15 per row. Frame 92 is row 6,
|
||
column 2 → pixel origin **(88, 264)**. **Painted.**
|
||
|
||
---
|
||
|
||
## Already supplied
|
||
|
||
| File | Size | Used for |
|
||
|---|---|---|
|
||
| `assets/images/vega/background-menu.png` | 1920 × 1080 | Backdrop for both menus — dimmed 34% on the landing screen, 62% on the setup screen so the species cards stay legible |
|
||
| `assets/images/vega/menu-title.png` | 1368 × 768 | Title logo. Large on the **left** of the landing screen (contained in 900 × 560 → 900 × 505), and small as the setup screen's header (contained in 760 × 132). Always contained, never stretched. |
|
||
| `assets/images/vega/world-*-01.png` | 1920 × 1080 | Colony-screen backdrops, one per planet type — see §2b. |
|
||
|
||
## Speech — ✅ `assets/speech/vega/`
|
||
|
||
| Clip | When it plays |
|
||
|---|---|
|
||
| `ui-choose-start.mp3` | On arriving at the choose-a-species screen |
|
||
| `char-<speciesId>.mp3` | Once, when that species' detail pop-over opens |
|
||
|
||
All ten species lines are present and correctly named.
|
||
|
||
Unlike the portraits, speech is **not** declared in the artwork manifest:
|
||
`ui/SpeechQueue.js` streams it straight from `assets/speech/<clip>.mp3` without
|
||
going through Phaser's loader, so the filename convention *is* the wiring. Drop
|
||
in a replacement and it plays — the verifier checks every species resolves.
|
||
|
||
Each new line cuts off whatever was playing rather than letting two voices
|
||
overlap — so opening a species interrupts the greeting, opening a second species
|
||
interrupts the first, and closing the window stops playback.
|
||
|
||
---
|
||
|
||
## Sound
|
||
|
||
Menu clicks use the shared `8bit-activate` cue (already preloaded globally as
|
||
`sfx-8bit-activate`) — every button on the landing and species screens, the
|
||
species cards, and the detail pop-over.
|
||
|
||
Combat effects already wired, no new audio needed: `laser-zap.mp3`, `scifi-explode.mp3`,
|
||
`ta-rocket-1.mp3`, `ta-rocket-2.mp3`.
|
||
|
||
**Soundtrack** is the game's own set, `data/masterofvega-music.json` →
|
||
`assets/music/vega/`, at volume 0.6. Four tracks are declared: *Power Down*
|
||
(DV-8-2303), *High Orbit* (Klaxon), *Master of Vega Main Theme* (Aiko), *Defend
|
||
the Colony* (Cy-Bro).
|
||
|
||
> ⚠️ `assets/music/vega/track-05.mp3` is on disk but **not listed** in
|
||
> `masterofvega-music.json`, so it never plays. Add an entry for it if that was
|
||
> not deliberate. The verifier checks every declared track exists, but cannot
|
||
> know about files you meant to declare.
|