Skip to content
Agentmart
Submit a tool

authoring-a-level-pack

How to author, check and hand over a level pack — the PACK.json contract, slug rules, the ops vocabulary and layer order, the palette split, the rim and…

Skill by briant92

IndexedApache-2.0
Write a review

Install

Works with Claude Code, Claude apps, Codex, Cursor, Gemini CLI, GitHub Copilot, VS Code, OpenCode, Goose, Windsurf. Read the repository before you give any tool access to your data.

npx agentmarket install skill/briant92-authoring-a-level-pack

Asks which of your tools to add it to (Claude Code, Codex, Cursor, VS Code, Windsurf, Gemini CLI, Claude Desktop) and shows the change first. See https://agentmart.dev/cli.

Get the weekly diff

The weekly diff: one email a week with new agent tools, notable updates and grade changes, plus security alerts for tools you follow. Double opt-in, one-click unsubscribe.

We use your email only for this newsletter. Privacy

About

How to author, check and hand over a level pack — the PACK.json contract, slug rules, the ops vocabulary and layer order, the palette split, the rim and scrim, and the render-check loop. Use when writing a new world for a level, or reviewing one somebody else wrote.

Use cases: documents, writing

No reviews yet. Installed it? Reviews come from verified installers only. How reviews work

Permissions

What this skill can do and what it asks for, from its SKILL.md. Checked Oct 25, 2026.

Tools
No tools found
Secrets
None asked for
Install scripts
None found

Network hosts it talks to 1

  • codeload.github.com · found in install command

Files it touches

  • ~/.claude/skills/authoring-a-level-pack

What's inside

Skill name
authoring-a-level-pack
Description
How to author, check and hand over a level pack — the PACK.json contract, slug rules, the ops vocabulary and layer order, the palette split, the rim and scrim, and the render-check loop. Use when writing a new world for a level, or reviewing one somebody else wrote.
License
Apache-2.0
Instructions
354 lines in SKILL.md · view on GitHub

Files (1)

  • SKILL.md

SKILL.md (first lines)

# Authoring a level pack

A level pack is **a whole world a level can be set in**: the palette, the terrain,
the backdrop behind it. Where an art pack is the crew, a level pack is the place.

It is data, not code. A pack **is** a `Scene` plus a palette plus provenance —
it extends the renderer's own scene type rather than restating it, so a pack
cannot describe something the renderer would refuse to draw. Anything the format
can express, a pack can use; anything it cannot, no pack can smuggle in.

Install is a folder drop: put the directory in `web/public/packs/` and reload.
No build step, no restart — the server reads the folder on every request.

---

## 1. The contract

One `pack.json` per folder. Everything the checker demands, in order:

```jsonc
{
  "name": "The Pequod",             // required — shown on the level card and palette picker
  "provenance": "…",                // required — where it came from, under what terms
  "viewH": 450,                     // required — how tall the world is
  "groundY": 388,                   // required — where the crew stand
  "rim": "rockEdge",                // optional but do it — see §5
  "theme": { "void": 2236468, … },  // required — all 16 slots, as numbers
  "backdrop": {                     // optional
    "scrim": { "color": "void", "alpha": 0.38, "from": 300, "steps": 12 },
    "ops": [ … ]
  },
  "ops": [ … ],                     // required, non-empty — the foreground
  "ambient": [ … ]                  // optional idle life
}
```

**What the checker enforces**

| Field | Rule |
| --- | --- |
| `name`, `provenance` | non-empty strings, both |
| `theme` | all 16 slots present, each an integer `0x000000`–`0xffffff` |
| extra theme slots | warning — "nothing draws with" them |
| `viewH`, `groundY` | positive finite numbers; `groundY < viewH` |
| `groundY` | **≥ 58**, refused outright below it — the doorway alone needs that headroom |
| `viewH - groundY` | warning under 10px — the floor reads as a hairline |
| `ops` | present and non-empty; a pack with no foreground draws nothing |
| every colour name | must resolve to a slot this pack's theme defines — anywhere, at any nesting depth |
| every coordinate | a finite number, or a string the renderer's own parser accepts |
| `rim` | if set, must name a slot the theme defines |

The colour/coordinate walk is the half worth having. An unknown colour name
otherwise reaches the renderer as a **throw at draw time** — a level that will
not open, with a stack trace behind it. The checker turns that into a line
naming the op and the slot, before anything is installed.

The walk is driven by key names, not by the op union, so it reaches a colour
nested inside a `repeat` inside a `band`:

- **paint keys**: `color`, `light`, `dark`, `alt`, `fill`, `edge`, `tip`, `rim`
- **coord keys**: `x`, `y`, `w`, `h`, `at`, `from`, `to`, `minY`, `maxY`,
  `below`, `topLeft`, `topRight`, `topY`, `botLeft`, `botRight`, `botY`, and
  each half of every `points` pair

If you add an op with a new colour- or coordinate-typed field, add its key to
those sets or it goes unchecked.

### The 16 slots

`void`, `rock`, `rockLight`, `rockDark`, `rockEdge`, `accent`, `accentLight`,
`accentDark`, `grass`, `grassDark`, `wood`, `woodDark`, `stoneDark`, `flame`,
`flameCore`, `hover`.

**Every slot, or none.** A pack that defines only the slots it happens to use
will throw the first time the renderer reaches for one it forgot, mid-level.

**Slots are yours to repurpose.** They are named after the cave they came from,
not after what they must be. The Pequod spends `grass` on the sea and
`grassDark` on its swell; The Drained Pool spends `flameCore` on white noon
light; Arrakis could spend `void` on sky. The checker cares that a colour
resolves, not what it is called.

### Coordinates

Numbers, or anchor strings: `worldWidth`, `viewH`, `groundY`, `spawnX`, `exitX`,
with an optional integer offset — `"groundY-40"`, `"exitX+34"`.

One regex parses them. It is **not an expression evaluator**: `"groundY*2"` is
refused, and so is anything else arithmetic.

### Provenance

Required, and the checker refuses a pack without it. Not ceremony: a pack lands
in this repository, so its licence becomes this project's problem, and "free"
routinely still means attribution-required or redistribution-forbidden — which
committing it here is. Record where it came from and under what terms, **in the
file**, before installing.

Worlds drawn from books and films need the same care. Public-domain source text
is one question; a studio's designs, marks and names are another, and the answer
is not the same for a private tool as for anything shared.

A pack drawn from nothing still says so. The Drained Pool's line is the model:
it names the spec it was drawn against, states that no external image, font or
reference pack was used, names the palette, and concludes that no third-party
rights attach.

---

## 2. The slug

The **folder name is what a level stores**, so it is the pack's identity — not
`name`, which is only a label.

- lower-case words joined by hyphens: `^[a-z0-9]+(?:-[a-z0-9]+)*$`, e.g. `orlop-deck`
- 40 characters maximum
- **not** a built-in theme name — `cave`, `chalkboard`, `household`, `marble`
  are refused rather than merged, because which one won would otherwise depend
  on directory order

From briant92/Agentlings, Apache-2.0.

More from briant92/Agentlings

Signals

Stars
0
Forks
0
Open issues
6
Last commit (this folder)
Aug 8, 2026 (2 months ago)

From GitHub (fetched Oct 24, 2026).

Details

License
Apache-2.0
First seen
Oct 24, 2026
Last checked
Oct 24, 2026

More from briant92

Cite this page

authoring-a-level-pack skill. Agent Mart. https://agentmart.dev/skills/briant92-authoring-a-level-pack (last updated 2026-10-24)