Guardian Paper Doll Sprite Editor Design Document

A contract-first specification for a “Guardian” Paper Doll sprite editor that consumes Ink outputs and provides layer-based composition, selection tools, and pose-aware editing.

Core Principles

Ink is authoritative. The editor must consume Ink outputs and must not re-implement Ink’s conversion rules in JavaScript or PHP.

This spec intentionally draws hard lines around common implementation foot-guns: re-implementing Ink conversions, confusing pose frames with palette animation frames, and auto-deduplicating semantically distinct slots.

Sprite Sources & Formats

Guardian assets are sourced from MEM/MOM tables and associated sprite files. The editor must treat MOM/MEM as authoritative metadata and treat Ink as the authoritative transformer/renderer for supported formats.

Supported Sprite Formats

Important Naming/Parsing Rules

Pose Frames vs Palette Frames Critical Distinction

Pose Frames (Character Animation)

Pose frames are the logical character/creature pose slots. Pose indices range from 0..3.

Example: pose 1 and pose 3 may resolve to the same underlying sprite data. This is intentional and must round-trip correctly.

Playback Semantics

Playback rules are example behavior, not an enforced limitation. A typical Guardian playback may be: 0 → 1 → 2 → 1. Pose 3 remains a valid addressable slot regardless of whether it is used in the default playback.

Palette Frames (Color Animation)

Palette animation is controlled by Ink’s &frame=. Palette frames range from 0..3 and represent animated color states. Palette frames are visual-only and independent of pose frames.

Do not conflate pose frames with palette frames. Pose is “which pose slot is active.” Palette frame is “which palette-cycle frame is being previewed.”

Naming Contract (Mandatory)

Identifier Range Meaning
poseIndex 0..3 Character pose slot / animation frame index
palFrame 0..3 Palette animation frame (Ink &frame=)

BSV JSON Contract Editable Canonical Form

When Ink emits BSV as JSON, it must be interpreted as the canonical editable representation for pixel tools, selection masks, and composition operations.

{
  "rows": [
	[64, 64],
	[ -1, -1,  12,  12, ... ],
	[ -1,  34,  34,  12, ... ],
	...
  ]
}

Transparency is represented by -1. This value is authoritative for masking, selection, and composition rules.

Palette Model

Palettes are treated as 256-entry tables with 4 animated frames per entry. Each palette entry contains multiple representations (RGB + hex string).

Expected Palette JSON Shape

{
  "pal": [
	[
	  [  0,  0,  0, "#000000" ],
	  [  0,  0,  0, "#000000" ],
	  [  0,  0,  0, "#000000" ],
	  [  0,  0,  0, "#000000" ]
	],
	...
  ]
}

Palette animation (palFrame) is purely visual and must not modify underlying pixel indices. Pixel indices remain 0..255 and reference palette entries; only the displayed RGB changes across palette frames.

Layer Masks & Composition

Paper-doll composition is defined by an explicit ordered stack of layers. Layers can include “mask semantics” conveyed by filename suffixes _ and -.

Layer Operations

Composition Rules

This document intentionally separates “how Ink renders a single sprite” from “how the editor composes multiple sprites.” Ink renders inputs; the editor applies stacking, offsets, and mask semantics.

Selection Tools

The editor must include selection tooling suitable for sprite editing and paper-doll layer authoring.

Required Tools

Default Matching Rules

Scope Rules (Important)

Composition Definition Schema Round-trip Safe

Even if server persistence is optional, the editor must have a stable internal JSON definition for a paper-doll composition. This supports undo/redo, exporting/sharing later, and prevents redesign.

{
  "base": {
	"file": "Guardian/char/hero.08v",
	"poseIndex": 0
  },
  "layers": [
	{
	  "file": "Guardian/gear/helmet.bsv",
	  "op": "_",
	  "offset": { "x": 0, "y": 0 },
	  "visible": true,
	  "lock": false,
	  "name": "Helmet"
	},
	{
	  "file": "Guardian/gear/visor-mask-.bsv",
	  "op": "-",
	  "offset": { "x": 0, "y": 0 },
	  "visible": true,
	  "lock": false,
	  "name": "Visor Mask"
	}
  ],
  "palette": {
	"set": "Guardian",
	"palFrame": 0
  },
  "view": {
	"zoom": 8,
	"grid": true,
	"checker": true
  }
}

Pose Duplication Requirement

The schema must preserve poseIndex as a semantic slot. If poses are duplicated in the underlying asset, the editor must still allow editing and addressing any pose 0..3 without deduplication.

Rendering & Performance Expectations

When to Request PNG vs JSON

Caching Guidance

The editor should remain “sprite-editor responsive” even when Ink is remote. This implies prefetching/caching, minimizing conversions during interaction, and rendering locally once JSON is loaded.

Backend Expectations (Optional)

Server persistence is optional. However, if implemented, the backend should accept and return the composition schema as compact JSON, potentially with additional metadata for authoring, sharing, and versioning.

Optional Endpoints

Even with persistence, the backend should not “reinterpret” layering semantics. It should store and return the editor’s schema as authored. Ink remains the transformer; the editor remains the compositor.