Files
jpmschweitzerandClaude Opus 4.8 ae7606ed83 docs(governance): address PR #169 review — reconcile sprite-era decisions + doc fixes
Tyre: D-244 now references its precedent (D-148 3D camera / D-149 live 3D characters
— D-244 completes that pivot for objects + assets) and reconciles the 5 sprite-era
decisions it touched, all amended 2026-06-17:
- D-043: 'not 3D' / Light2D scoped to overlay layers; in-world is 3D.
- D-044: sprite footprint retired (sim occupancy + visual hierarchy survive).
- D-049: z-stack logical model survives; sprite/CanvasLayer implementation language retired.
- D-066: dual-scale coordinate model + 2x2 geometry minimum survive; sprite-footprint language legacy.

Hoshe (doc QA):
- D-244 broken cross-file anchors fixed ([D-159]->scope.md, [D-241]->process.md).
- renderer/README: bare [D-244] linked; D-019->D-148 camera note; legacy banner over the
  object-sprite workflow sections; resolution-chain output path qualified.
- docs/assets/_templates/sprite.md + README: marked the template legacy object-sprite schema
  (model/texture/artwork template TBD).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-17 09:40:41 +02:00

7.4 KiB
Raw Permalink Blame History

Settled Reach — 2D Artwork Render Pipeline

Repurposed (D-244). This offline Godot renderer is not the in-world object format. Per D-244 the in-world view renders 3D objects directly (props via Trellis .glb / /glb-gen; characters via the Quaternius pipeline + CharacterVisualDescriptor); the only flattened 2D content is textures and flat 2D artwork (paintings, flags, billboards, signage). This pipeline began as the #541 3D-to-2D sprite spike and now serves that flat artwork. The "render every entity/object/wall to sprites" framing below is legacy (the retired object-sprite use); the camera / lighting / resolution mechanics remain usable for flat-artwork rendering.

Offline Godot 4 renderer. Produces flat 2D artwork (and, in its legacy mode, 3D-to-2D sprites) at three resolutions from a fixed camera angle, with outlines applied at working resolution.

Camera Specification (D-019)

  • Angle: -72.5° from horizontal (= 17.5° from vertical, the midpoint of the 15-20° from vertical range)
  • Projection: Orthographic (size = 1.4)
  • Position: (0, 3, 1) — above and slightly in front of the model origin
  • Godot Transform3D: Transform3D(1, 0, 0, 0, 0.30071, 0.95372, 0, -0.95372, 0.30071, 0, 3, 1)

Note (D-244): D-019 is superseded by D-148 (30° low-angle Camera3D) for the gameplay camera. The 72.5° angle here is the offline render camera used for 2D-artwork generation (and the retired object-sprite mode) — not the in-world gameplay camera.

This is "the angle" per the D-019 amendment (2026-02-12); v0.1 object-sprite rendering used it, now retired. The offline renderer keeps this fixed camera for flat-artwork output.

Lighting Rig

Three-point studio rig. All lights have shadow_enabled = false — sprites are shape templates, no baked shadows or directional lighting. The Godot runtime PointLight2D pipeline provides all scene lighting at runtime (D-043).

Light Energy Direction Purpose
KeyLight 1.0 Matches camera angle (-72.5° from horizontal) Main illumination; ensures front face is lit as the camera sees it
FillLight 0.4 45° from right side (-45° pitch, +90° yaw) Fills shadow opposite the key; no deep-black patches on right face
RimLight 0.3 45° from behind (-45° pitch, +180° yaw) Back-edge accent; defines silhouette boundary for outline processing

Rationale: Even 3-light coverage ensures no black patches on a convex mesh, keeping surface colors flat and readable for the outline processing step.

Resolution Chain (D-043, D-044)

1024×1024  — source PNG, full fidelity for outline processing
    ↓ bilinear resize
256×256    — working PNG, outline applied at 4-8px, color #333340
    ↓ bilinear resize
64×64      — runtime PNG (legacy object-sprite output → client/assets/sprites/; for flat artwork, promote to client/assets/textures or .../artwork)

Outline implementation: alpha-mask dilation + flat color fill. Outline width in render_export.gd: outline_width_px = 4 (at 256px = 1px effective at 64px).

⚠️ Legacy: object-sprite workflow (retired per D-244)

Everything from here down describes the retired object-sprite pipeline (#541 spike) — entity/object/wall sprites are no longer the in-world format (objects are 3D .glb; characters are 3D meshes). It is kept for reference, and because the camera / lighting / resolution mechanics above are reused for 2D-artwork rendering. When generating flat artwork, promote outputs to client/assets/textures or client/assets/artwork (not client/assets/sprites/) and ignore the entity-sprite footprint / material / deployment specifics below.

Entity Footprint Spec (D-044, D-066)

  • Entity sprites occupy a 24×32px footprint within the 64×64 visual tile
  • Entities render across a 2×2 sim tile sprite footprint (D-066)
  • Visual tile = 64×64px at runtime; sim tile = 32×32px (0.5m)
  • NPC model scale: CapsuleMesh(radius=0.25, height=0.62) at camera size 1.4 produces ~24×32px apparent size in the 64px output tile

Usage

Command Line

# From the repository root
godot --path renderer/ --headless --quit-after 1200 res://render_scene.tscn -- <model_name>

The /sprite-gen skill wraps this command and handles output placement.

Adding a New Model

  1. Create renderer/models/<model_name>.tscn — root node is a MeshInstance3D (or Node3D with children)
  2. Center the mesh at the origin
  3. Use a flat StandardMaterial3D (no baked shadows — just albedo color + roughness)
  4. Run: godot --path renderer/ --headless --quit-after 1200 res://render_scene.tscn -- <model_name>
  5. Output: 12 PNGs in renderer/output/ (4 directions × 3 resolutions)
  6. Runtime sprites: copy 64px variants to client/assets/sprites/

Material Guidelines

  • Entity sprites: neutral flat material (albedo Color(0.5, 0.5, 0.5)). D-033 relationship color tinting applied at runtime by the client's entity renderer. Outline color (#333340 per D-043) is compatible with all D-033 tint colors — the dark blue-grey outline remains visible against teal, green, amber, and red entity tints.
  • Structural sprites: use zone-appropriate texture (textures/wall_institutional_era1.png, etc.)
  • No specularity: metallic = 0.0, roughness = 0.9
  • No emission, no normal maps — shape is the signal

Models

Model File Type Notes
wall_structural models/wall_structural.tscn Structure 1.0×0.8×0.2 box, institutional era-1 texture
wall_bar_green models/wall_bar_green.tscn Structure 1.0×0.8×0.2 box, green panel texture (model only — no sprites rendered yet)
npc_generic models/npc_generic.tscn Entity Capsule silhouette, neutral grey, 24×32px footprint. Rotationally symmetric — north/south and east/west pairs are near-identical by design (asymmetric silhouettes come from named NPC models with identifying features per D-044).

Output Naming Convention

<model_name>_<direction>_<resolution>.png

wall_structural_north_64.png
npc_generic_south_256.png

Directions: north, east, south, west (model rotated 0°, 90°, 180°, 270° around Y axis).

Runtime Sprite Path

64px sprites are deployed to: client/assets/sprites/

Naming convention at the client side matches the pipeline output: <model_name>_<direction>_64.png. The 1024 and 256 variants stay in renderer/output/ as pipeline intermediates (gitignored).

Design Constraints

  • No baked lighting: sprites are shape templates. Lighting is applied at runtime by Godot's PointLight2D per D-046.
  • No baked shadows: shadow direction would conflict with runtime point lights at arbitrary positions.
  • No baked mood: flat materials, three-point neutral rig. Zone atmosphere comes from runtime CanvasModulate.
  • Outline applied at 256px, not 64px: ensures outline is crisp after bilinear downscale.
  • Transparent background: SubViewport.transparent_bg = true — sprites are PNG with alpha, composited at runtime.

Cross-References

  • D-019: Camera angle spec and amendment
  • D-043: Art direction — "functional warmth," resolution chain, outline color
  • D-044: Visual hierarchy, entity footprint spec
  • D-049: Z-level rendering stack (sprites land on layers 2-3)
  • D-066: Dual-scale grid, 2×2 sim tile entity footprint