← all games

action-roguelite-gpt-5-unknown-2 — FRICTION.md

# Friction log

## 1. Required addon versions do not match the scaffold version

- **Trying to do:** Install the three addons required by the game brief beside the `create-yage@0.9.0` scaffold.
- **What happened:** npm rejected `@yagejs-addons/abilities@^0.9.0` because that version does not exist.
- **Evidence:** `npm install` returned `ETARGET` for `@yagejs-addons/abilities@^0.9.0`. The scaffold installed the core packages at `^0.9.0`.
- **Workaround or open question:** The project now uses `file:` references into the sibling YAGE WIP checkout, including each addon's actual package directory. Published version numbering is no longer used to choose the implementation surface.
- **Category:** API friction

## 2. No matching door or gate in the selected sprite set

- **Trying to do:** Find door or portal art that matches Foozle's Void ship, fleet, and environment packs.
- **What happened:** Searches for `door space station`, `gate sci-fi`, and `portal space` returned station modules from Wenrexa, generic UI icons from FlexUnit, and unrelated fantasy doors. None matched the selected Foozle pixel-art fleet.
- **Evidence:** The local catalog searches returned no Foozle door, gate, portal, or corridor connector.
- **Workaround or open question:** Draw energy gates at runtime with the same cyan, teal, and amber combat palette. Keep the gate shapes functional and record the missing sprite category in `ASSET-PLAN.md`.
- **Category:** asset gap

## 3. Automated browser checks cannot judge audio level balance

- **Trying to do:** Verify that weapon, impact, explosion, interface, and music assets play at balanced perceived levels.
- **What happened:** Browser checks proved that each cue path executed without a runtime error, but they did not reveal that call sites used hand-tuned gains without accounting for the source files' different loudness and true-peak measurements.
- **Evidence:** The asset manifests include `loudnessLufs` and `peakDb`. The first implementation passed unrelated numeric volumes at each `AudioManager.play` call. A listening review found the mismatch after the game and harness builds had passed.
- **Workaround or open question:** Calculate one per-asset gain table from the library measurements, then apply the music, sound-effect, and interface channel gains separately. A human listening pass remains necessary for the final mix.
- **Category:** infra / test gap

## 4. Renderer has no tiled animated-background primitive

- **Trying to do:** Fill the 1280×720 viewport with two animated 360×360 space-background layers without distorting their artwork.
- **What happened:** `AnimatedSpriteComponent` renders one frame-sized sprite, and the renderer has no tiled animated-sprite component. The first implementation stretched one square frame with a non-uniform `3.6 × 2.05` transform, which widened every star and cloud shape.
- **Evidence:** Searches of the WIP renderer source and LLM documentation found no `TilingSprite`, `TiledSprite`, or equivalent component. The replacement needs a 4×2 grid for each layer, for 16 animated entities in total, plus manual rotation and frame offsets to hide repetition.
- **Workaround or open question:** Keep each frame at its native 360×360 size and repeat it across the viewport. Consider a renderer primitive that tiles a texture while advancing spritesheet frames.
- **Category:** missing primitive

## 5. Particle emitters cannot declare a blend mode

- **Trying to do:** Render explosion smoke, sparks, and reward glows without dark source pixels covering the arena.
- **What happened:** Renderer visual components accept `blendMode`, but `ParticleEmitterComponent` does not. Normal blending exposed dark rectangles around the particle textures.
- **Evidence:** `EmitterOptions` includes alpha, tint, scale, rotation, and layer but no blend mode. The working implementation must set `emitter.container.blendMode = "add"` through the raw Pixi container.
- **Workaround or open question:** Set the container blend mode after creating every affected emitter. `ParticleEmitterComponent` should accept and serialize the same `blendMode` option as renderer visual components.
- **Category:** API friction

## 6. Steering heading cannot account for sprite orientation or target-facing enemies

- **Trying to do:** Rotate up-facing enemy ship sprites so they point toward the player while moving with steering behaviors.
- **What happened:** `SteeringAgent({ faceHeading: true })` points the entity along its travel velocity, not toward its combat target. Ranged enemies arrive, orbit, or flee while their projectiles aim at the player through a separate vector, so movement and aim often differ. The addon also writes `velocity.angle()` directly: zero radians points right, while every selected Nairan ship asset is authored nose-up.
- **Evidence:** The steering source sets `Transform.rotation` to `velocity.angle()` when `faceHeading` is active. The asset manifests report `orientation: "up"`. Projectile visuals in the same game add `Math.PI / 2` for this orientation, but the enemy steering setup has no corresponding offset.
- **Workaround or open question:** For target-facing enemies, disable `faceHeading` and set rotation from `playerPosition.sub(enemyPosition).angle() + Math.PI / 2` after steering updates. For travel-facing enemies, rotate a child visual or add a heading offset. A `faceHeadingOffset` option would remove the raw workaround; a target-facing shooter recipe should also distinguish movement direction from aim direction.
- **Category:** API friction