# Airship One Dev

> Airship One implementation playbook for runtime architecture, npm-first tooling, release/PWA flow, and debugging checks. Use when this capability is needed.

- Skill: `tomevault-io/airship-one-dev` (Agent Skill, multi-file: 2 files)
- Install (CLI): `npx skillmds@latest add tomevault-io/airship-one-dev`
- Raw SKILL.md: https://api.skillmd.com/api/skills/tomevault-io/airship-one-dev/raw
- Safety review: pending (external: skill-scanner PASS, skillspector PASS)
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: tomevault-io (https://skillmd.com/u/tomevault-io)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/tomevault-io/airship-one-dev

---


# Airship One Dev Skill

Use this skill for day-to-day implementation in this repository.

## Purpose

Keep contributors aligned on:
- runtime architecture direction,
- npm-first developer tooling,
- release/PWA versioning flow,
- practical debugging checks before and after changes.

## Current Stack and Source of Truth

- Runtime: TypeScript + Vite + Three.js.
- Deployment target: GitHub Pages.
- Architecture target: modular ECS + typed event queue + multi-rate update domains.
- Version source of truth: `package.json` `version`.
- Theme model: runtime light/dark mode with tokenized Victorian wood/paper/velvet palette.
- Menu model: data-driven stack-based DOM overlay menus with submenu/back/close behaviors and custom menu item renderers (e.g., `letter`).
- Save model (current scaffold): browser `localStorage` envelope including settings + local simulation, with JSON export/import roundtrip and persisted player pose (`position`, `yaw`, `pitch`).
- Ship-state model (current scaffold): authoritative geo-time fields in simulation (`shipLatitudeDeg`, `shipLongitudeDeg`, `shipAltitudeAslM`, `shipLocalSolarTimeHours`) updated from real UTC.
- Controls model (current scaffold): dual bindings (keyboard + gamepad button/axis) with HID-safe rebind capture baseline.
- Input helper model (current scaffold): shared action-edge, pressed-state, gamepad lookup, and binding-label helpers are centralized in `src/core/input.ts`.
- Module generation model: parameterized generator profiles for generic module types and exact module variants (`--interior-profile auto|none|captains-cabin`).
- Module runtime registry model: one handler file per module template under `src/modules/handlers/*.ts`, with `src/modules/registry.ts` as the single wiring point for fixed modules, insertable modules, and capability metadata (e.g., battery supply).
- Lighting model (current scaffold): UTC-driven global sun + ambient derived from authoritative ship geo-time state (lat/lon/ASL + UTC) and planet parameters.
- Lighting helper model (current scaffold): solar-state and solar-charge-effectiveness calculations are centralized in `src/render/lighting.ts`.
- Electrical model (current scaffold): effective battery capacity and percent drain/charge rates scale with installed battery-supply module count across all active ladder floors.
- Battery control menu model (current scaffold): queue-driven in-place live bindings are visibility/throttle gated, and runtime display uses staged tail labeling (`A+B ... then B +tail`).
- Menu module model (current scaffold): menu definition factory and row renderers are extracted to `src/ui/menu-definitions.ts` and `src/ui/menu-render.ts`, with `src/main.ts` retaining menu orchestration and event wiring.
- Sky model (current scaffold): parameterized procedural sky dome (day/sunset/night gradients, sun-centered tinting, contiguous evolving cloud coverage).
- Generated version artifacts:
  - `public/version.js` (local/dev fallback and build-time overwrite),
  - `dist/version.js` (must match deployed build version).

## Required Workflow

### 1) Local Development
- `./dev-prepare.sh` for baseline setup/checks.
- `./dev-run.sh` to run dev server.
- `./dev-test.sh` for lint/typecheck/test.
- `./dev-build.sh` for production build.
- `./dev-build-bump-ver.sh` to bump patch version then build.

### 2) Release Build
- Prefer `./prod-release.sh` (delegates to npm release flow).
- Build must produce:
  - `dist/version.js` with current package version,
  - `dist/sw.js` with versioned cache name,
  - deployable `dist/` artifact.

### 3) CI/CD (Pages)
- Use `.github/workflows/build-and-deploy.yml`.
- Keep build artifact path as `dist`.
- Post-deploy verification remains required on live Pages URL.

## Runtime Architecture Rules

- Keep simulation deterministic and decoupled from render FPS.
- Preserve planned timing domain separation:
  - `simTick`, `renderTick`, `terrainHarvestTick`, `audioTick`.
- Keep state transitions event/command driven.
- Keep UI as state consumer/dispatcher, not direct simulator mutator.
- Keep spherical math correctness constraints explicit in all nav work.
- Early-development fail-fast policy is strict: do not add save/data migrations, do not add fallback execution paths, and do not hide exceptions.

## Floor/Module Ownership Rules

- Use explicit per-floor ownership for interior modules via level-keyed arrays (`floorModuleIdsByLevel`).
- Never resolve missing floor module arrays by inheriting from another floor; missing level state is a defect and should throw.
- Keep ladder shaft alignment stable across levels by preserving a shared ladder center Z when floor layouts are rebuilt.
- Compute movement/collision bounds from actual rendered placement extents, not assumptions tied to only one active floor.
- When selecting active level fallback, compare player eye Y against level standing-eye heights, not deck base Y.
- Ladder climb min-Y clamps must be level-relative for lowest/negative levels to avoid descend snap-back.

## Module Type Extension Rules

- Add new module templates by creating a dedicated handler file in `src/modules/handlers/` and exporting it via `src/modules/handlers/index.ts`.
- Keep module capability flags (e.g., battery supply) in handler metadata, not hardcoded ID-prefix checks in runtime logic.
- Route chain construction and insertable-choice generation through `src/modules/registry.ts` only.
- Keep fixed module rules (`cockpit` front, `cargo` rear) enforced by registry-level logic.

## Rendering and UI Guardrails

- Preserve 320x320 logical rendering concept.
- Keep menu/dialog UI as accessible DOM overlays.
- Use pixel-style scale tokens; avoid random per-component hardcoded styling.
- Interaction-triggered menu close may request pointer recapture, but explicit user `Escape` to free cursor must always cancel pending recapture.

### Known Early Pitfall: Growing Canvas/Square in Dev

If visual surface appears to grow continuously:
- Check for `ResizeObserver` feedback loops where observed size is immediately rewritten.
- Avoid style updates that change the observed container dimensions each callback.
- Prefer stable wrapper sizing and only update renderer/canvas dimensions from external layout changes.
- Add temporary logging around resize callback dimensions to verify convergence.

### Known Early Pitfall: Texture Update Warning on First Frames

If you see `THREE.WebGLRenderer: Texture marked for update but no image data found`:
- Ensure tile textures are preloaded before creating module meshes/materials.
- Avoid cloning repeat-variant textures before the source image is loaded.
- Centralize texture configuration (wrap, color space, anisotropy) for both preload and fallback load paths.

### Known Early Pitfall: Ladder Floor Teleport/Snap Bugs

If floor add/remove or descend behavior causes apparent teleports:
- Verify level-anchor fallback uses standing-eye height (`level * deckHeight + eyeHeight`).
- Verify climb volume floor clamp uses level-relative eye-height when no lower floor exists.
- Avoid index-based remapping assumptions across multi-floor rebuilds unless index domain is level-scoped and stable.

### Known Early Pitfall: Pointer Lock Races During Menu Close

If console logs `SecurityError` after click/close transitions:
- Expect pointer-lock request races during unlock and handle `requestPointerLock()` promise rejection for known unlock races.
- Keep a single helper for pointer-lock requests so `SecurityError` handling is consistent.
- Ensure `Escape` intent cancels pending recapture semantics.

### Known Early Pitfall: Procedural Clouds Look “Vector-Like”

If sky clouds look like hard cutout shapes:
- Add domain warping before primary cloud density sampling.
- Use edge erosion/detail noise instead of a single hard threshold.
- Keep sky dome tessellation high enough for smooth directional interpolation with high-frequency cloud fields.

## Pre-Commit / Pre-Handoff Checklist

- Run `./dev-test.sh` and `./dev-build.sh`.
- Confirm `dist/version.js` matches `package.json` version.
- Confirm `dist/sw.js` regenerated in build.
- Update `ROADMAP.md` status and any parity notes touched by the change.
- Keep `.github/copilot-instructions.md` current if project reality changed.

## Post-Deploy Checklist (GitHub Pages)

- Validate first-load app shell and no critical console errors.
- Validate manifest installability.
- Validate offline refresh after first online visit.
- Validate update path by version bump + redeploy (service worker update lifecycle).
- Validate repo-subpath asset/deep-link behavior on Pages.

---
> Converted and distributed by [TomeVault](https://tomevault.io/claim/timelessp) — claim your Tome and manage your conversions.
<!-- tomevault:4.0:skill_md:2026-04-13 -->

