Game Design Document and Technical Specification
Document status: Proposed implementation baseline Version: 1.0 Date: 2026-07-24 Audience: PixelBullet engine, gameplay, rendering, UI, audio, tools, and test contributors Working title: Boundless Vector Arena Source reference: The uploaded Godot project is treated as an executable visual and gameplay sketch, not as an architectural dependency.
Repository import revision — 2026-07-25. This is a complete import of PixelBullet_Boundless_Vector_Arena_GDD_Technical_Spec.md version 1.0 from the operator-provided source directory. Repository alignment changed obsolete lab/example names, established Arena as a product rather than an executable- only surface, separated its future interactive and headless adapters from the generic authored-scene runner, and made product-local asset ownership explicit. Illustrative type names, target names, and layouts remain recommended implementation direction until Phase 0 approves them. Gameplay requirements, acceptance identifiers, rationale, and phased intent were retained.
Document purpose
This document decides whether the geometric arena-shooter concept should remain a fixed-screen arena or become an effectively boundless, character-centered game. It then specifies the recommended design as a from-scratch PixelBullet implementation.
The specification is intended to be actionable. It defines:
- what the player should experience;
- how the 31-wave campaign and four-boss framework should behave;
- how a boundless local world should be represented and simulated;
- how enemies, projectiles, perks, camera, UI, audio, and effects should interact;
- which responsibilities belong to ECS, Vulkan/DXC rendering, RmlUi, miniaudio, and optional engine services;
- what performance and correctness constraints must be enforced;
- how each major subsystem will be accepted.
The document intentionally excludes replication of the Godot project's menu, profile, boot-terminal, localization, save-slot, music-browser, and portrait experiments. Only the combat loop, progression shape, boss concepts, geometric presentation, and relevant effects are used as references.
Normative language
- MUST and MUST NOT identify release-blocking requirements.
- SHOULD and SHOULD NOT identify the recommended default; deviation requires an explicit measured or design rationale.
- MAY identifies optional or later work.
- Numerical values labeled initial target are starting points for implementation and tuning, not immutable balance law.
- Reference resolution means a 1600×900, 16:9 view, matching the uploaded project's intended viewport.
- WU means gameplay world unit. The initial conversion is 1 WU = 64 reference pixels.
Contents
- Executive recommendation
- Feasibility and best-practice analysis
- Product definition
- Core design pillars
- Complete gameplay loop
- Spatial scale and reference conversion
- Player controls, movement, inertia, and weapons
- Camera behavior
- Effectively boundless world and coordinate strategy
- Enemy roster and behavior specification
- Enemy spawning, activation, distribution, and retirement
- Projectile lifetime, range, cleanup, and collision
- Wave progression and encounter pacing
- Perk and modifier system
- Boss encounter framework
- Difficulty scaling and balance principles
- Visual design and presentation language
- User interface and feedback requirements
- Audio and effects requirements
- Technical architecture and system responsibilities
- Data structures, configuration, and content authoring
- Performance, scalability, and object management
- Edge cases, failure states, and implementation risks
- Testing and validation plan
- Phased implementation plan
- Consolidated definition of done
Appendices: Godot interpretation · Initial constants · Traceability · Research
1. Executive recommendation
1.1 Decision
Adopt the boundless, player-centered structure as the primary design.
The recommended game is not a persistent open world and not a literal infinite map. It is an effectively boundless combat substrate:
- the player can move indefinitely during standard waves;
- the camera remains centered on the player;
- the visible grid and sparse ambient markers are generated from logical coordinates;
- only a bounded local population around the player is simulated;
- enemies are introduced through an off-screen spawn annulus and retired or recycled through explicit lifecycle rules;
- projectiles have finite lifetime, range, and active-region constraints;
- world coordinates are kept precise through camera-relative simulation and origin rebasing;
- boss waves temporarily establish an explicit combat lockfield so authored projectile patterns cannot be escaped or invalidated by endless retreat.
This structure is a meaningful improvement over the fixed-screen prototype because it turns movement and dash into persistent spatial decisions, removes wall-clamping and corner-camping, gives the encounter director much more compositional freedom, and exercises more of PixelBullet's engine architecture. It also creates a stronger base for later endless, challenge, mutator, and alternate-arena modes without requiring a new movement model.
The recommendation is conditional on implementing the constraints in this document. A naïve “infinite empty grid plus enemies spawned somewhere around the camera” version would be worse than the fixed arena. It would encourage indefinite kiting, create invisible stragglers, make spawn fairness difficult, and cause the world to feel like a treadmill. The boundless version succeeds only when spawn placement, activation, recycling, pacing, visual navigation, and boss containment are treated as first-class systems.
1.2 Why the boundless design wins
| Criterion | Fixed screen | Boundless, centered | Decision |
| Immediate clarity | Excellent | Very good with strict telegraphs | Fixed advantage, manageable |
| Movement expression | Limited by walls | Strong, continuous | Boundless advantage |
| Dash usefulness | Often constrained by edges | Consistently useful | Boundless advantage |
| Spawn variety | Four borders and corners | Full annulus and directional sectors | Boundless advantage |
| Anti-kiting complexity | Low | Medium-high | Fixed advantage |
| Boss authoring | Straightforward | Requires temporary encounter field | Fixed advantage, solved explicitly |
| Long-run sustainability | Density tends to fill the screen | Population can flow with the player | Boundless advantage |
| Engine-demonstration value | Moderate | High: rebasing, active regions, culling, instancing, director | Boundless advantage |
| Future modes | Requires arena variants | Reuses the same substrate | Boundless advantage |
| Implementation risk | Low | Medium | Acceptable for the added value |
The table is directional rather than mathematically weighted. The deciding factors are that the boundless structure substantially improves movement, spawn composition, and engine coverage, while its principal weaknesses have concrete engineering and design mitigations.
1.3 Required compromise: boss lockfields
Standard waves MUST permit unrestricted travel. Boss waves MUST be allowed to create a temporary, visible, diegetic lockfield centered on the encounter origin.
This is not an accidental fallback to a fixed-screen game. It is an authored encounter rule serving four purposes:
- keeping the boss and player within a known readable relationship;
- preserving radial, fan, gravity, and mirror-duel patterns;
- preventing endless retreat from resetting or trivializing the encounter;
- allowing the entire boss boundary to be framed by a controlled camera zoom.
The lockfield dissolves immediately after the boss is resolved, and boundless travel resumes at the same logical world position.
1.4 Scope recommendation
The target product shape is:
- single-player;
- top-down 2.5D presentation through PixelBullet's Vulkan renderer;
- fixed 60 Hz gameplay simulation with interpolated rendering;
- 29 standard waves and four boss encounters at waves 10, 20, 30, and 31;
- perk drafts at waves 5, 10, 15, 20, and 25;
- approximately 30–45 minutes for a complete successful run after tuning;
- wave-boundary checkpoints, not arbitrary mid-wave saves;
- no permanent authored map geometry in the first implementation;
- no network multiplayer;
- no meta-progression requirement;
- no reproduction of the Godot front-end shell.
2. Feasibility and best-practice analysis
2.1 Design feasibility
The uploaded game already demonstrates that its core combat does not depend on Godot-specific scene, physics, or animation systems. The active combat scene is effectively one Node2D with procedural drawing and manually integrated arrays of enemies, bullets, pickups, and effects. The concept therefore transfers cleanly into a purpose-built ECS simulation.
A centered boundless version is feasible because the game has:
- no authored level topology that must be streamed;
- no navigation mesh requirement;
- simple steering toward or around the player;
- small circular collision shapes;
- procedural geometric visuals;
- finite wave membership;
- natural opportunities to recycle entities outside the camera;
- no requirement that projectiles persist across long distances.
The largest design risk is not coordinate precision or rendering. It is encounter integrity: keeping enemies fair, relevant, and completable when the player can move forever.
2.2 Relevant research conclusions
The implementation should borrow principles, not copy architectures.
Procedural population should be structured, not arbitrary
Valve's Left 4 Dead AI work identifies replayability and dramatic pacing as explicit goals, uses procedural population to make sessions skill challenges rather than memorization exercises, and describes an active area surrounding the players in which population is created and destroyed as the group moves. It also separates common pressure, periodic mobs, special threats, and bosses into different frequency classes. [R1]
For PixelBullet, the corresponding lesson is:
- author the macro progression;
- procedurally vary micro-composition and arrival geometry;
- keep a bounded active population around the player;
- distinguish ambient pressure, surge packs, elite threats, and bosses;
- modulate spawn cadence to create peaks and releases without secretly changing the wave's promised total difficulty.
The encounter director in this specification therefore controls when and where committed threat enters, not whether the game quietly removes threat because the player is struggling.
Camera lag is a design choice, not a default
Cinemachine's official documentation distinguishes dead zones, soft zones, and damping, and explicitly characterizes damping as introducing camera lag. It also warns that predictive look-ahead can amplify noisy motion and cause jitter. [R2]
That toolset is useful for many genres, but it is the wrong default here. When the entire world scrolls around a small character and aiming is cursor-relative, camera lag makes movement feel slippery and changes the apparent aim vector. The camera therefore MUST use:
- no positional dead zone;
- no follow damping;
- no motion look-ahead;
- no gameplay-space displacement from screen shake;
- only fixed-tick interpolation and a separate presentation impulse layer.
Simulation should not depend on render frame time
A fixed or tightly bounded timestep prevents movement and collision behavior from changing with display refresh rate and avoids the instability and tunneling risks associated with arbitrary variable timesteps. [R3]
PixelBullet MUST run the canonical combat simulation at 60 Hz. Rendering MAY occur at any supported rate using interpolated snapshots. Large frame gaps MUST be clamped and limited to a bounded number of catch-up steps.
“Boundless” does not require engine-wide double precision
Godot's current large-world documentation notes that precision decreases as values move away from the origin, that large-world doubles carry performance and memory costs, that origin shifting is an alternative, and that large coordinates are rarely required for 2D projects. [R4]
PixelBullet should not widen every hot transform to double precision for this product. Instead:
- persistent logical location uses integer chunks plus a normalized local offset;
- active simulation uses small camera-relative float2 values;
- the local origin is rebased at deterministic tick boundaries;
- render instances are always camera-relative floats.
This retains precision, bounds data size, and exposes a reusable large-world seam without imposing double precision on ECS, shaders, collision, or particles.
Fast bullets require swept tests
Box2D's documentation describes continuous collision detection by sweeping a shape from its old position to its new position and computing time of impact to prevent tunneling. [R5]
The geometric shooter does not need a general rigid-body CCD solver, but it does need the same principle. Every gameplay projectile MUST perform at least a swept segment-versus-expanded-circle query over the current tick, rather than checking only its final point.
Rendering should exploit repeated geometry
Khronos' Vulkan samples describe instancing as a way to render many copies of the same mesh using variable per-instance parameters. [R6] That directly matches repeated triangles, squares, circles, bullets, rings, and fragments.
The baseline renderer should use:
- a small set of shared unit meshes;
- compact per-instance buffers;
- batches by pipeline/material/shape;
- camera-relative transforms;
- ordinary instanced draws first;
- indirect draw generation only after profiling shows a CPU submission bottleneck.
UI and audio already fit the proposed responsibility split
RmlUi's data binding model is explicitly MVC-like: application data is bound to views and updated by marking values dirty. [R7] The HUD and perk draft should therefore consume a small presentation model rather than query ECS storage or mutate the document element-by-element.
miniaudio's resource manager supports shared loading, in-memory decoded sounds, streaming, and asynchronous decoding. [R8] High-frequency combat cues should be cached or generated once and played through bounded voices; music should stream. The Godot prototype's per-event PCM construction must not be reproduced.
2.3 Likely gameplay effects
Clarity
The centered camera improves self-location: the player is always at the same screen position. It worsens world-reference clarity because the grid and all enemies move around the player. The mitigation is to keep the background restrained and add sparse, stable coordinate markers.
Pacing
Continuous motion allows pressure to arrive from more varied angles, but can turn a wave into a long chase. The wave director therefore needs a total threat budget, maximum active population, angular scheduling, catch-up/recycle logic, and a hard rule that off-screen enemies cannot attack.
Difficulty
Boundless movement gives the player more defensive space. Difficulty must shift away from “the walls eventually trap you” and toward:
- role combinations;
- cross-angle pressure;
- deliberate surges;
- chargers and kamikazes with visible commitment;
- ranged enemies that establish lanes after entering view;
- boss lockfields;
- modest predictive spawn weighting with strict fairness limits.
Navigation
There is no exploration objective in the first version. The world exists to support motion, not destination finding. Navigation therefore means maintaining orientation and perceiving travel, not following a map. A minimap is unnecessary; a compass-like edge indicator and coordinate-stable ambient markers are sufficient.
Performance
The boundless world is cheaper than a persistent open world because only a local active bubble exists. Performance becomes bounded when:
- projectiles have finite life/range;
- enemies outside the active region are recycled;
- VFX have strict budgets;
- rendering is instanced;
- collision uses a uniform spatial grid;
- transient events use preallocated frame arenas or bounded buffers.
Bosses
The first three bosses rely on known screen-relative positions and radial patterns; the Shadow boss relies on screen clamps and teleports. They cannot simply be released into infinite space. The lockfield and boss-relative coordinate system are therefore mandatory, not optional polish.
2.4 Fallback threshold
The project should revert to the prior fixed-arena design only if implementation proves one of the following after the production systems are in place:
- origin shifting produces unresolved render or collision discontinuities;
- spawn fairness cannot meet the zero-visible-spawn and minimum-reaction-time criteria;
- standard-wave completion regularly stalls because enemies cannot be kept relevant;
- controlled playtests show that unrestricted movement reduces rather than increases weapon/dash decision-making;
- the world lacks readable motion even after stable markers and grid tuning;
- the boss lockfield feels inconsistent or substantially less readable than a permanent arena.
These are validation thresholds, not expected outcomes. The current analysis does not indicate that fallback is necessary.
3. Product definition
3.1 Player-facing pitch
A cyan vector pilot moves continuously through a dark, effectively endless grid while geometric hostile programs assemble outside the camera and converge in escalating waves. The pilot fights with a rapid blaster, a cooldown-limited scatter weapon, and an invulnerable dash. Milestone drafts add systemic modifiers. Three escalating machine bosses interrupt the campaign, followed by a final mirror entity that uses player-like movement and weapons.
3.2 Engine-showcase purpose
The product should visibly exercise:
- deterministic fixed-step ECS combat;
- high entity churn;
- projectile-heavy collision and event processing;
- a moving local simulation region;
- world-origin rebasing;
- data-driven wave composition;
- typed perk effects and reactive procs;
- boss state machines;
- Vulkan instancing and dynamic effect buffers;
- DXC-authored shaders targeting SPIR-V;
- RmlUi HUD and card selection;
- miniaudio cue prioritization and streamed music;
- editor/debug controls and headless simulation tests.
It should complement, rather than duplicate, the current authored labs—Level Slice, World Sandbox, Behavior Lab, and Combat Lab—and the executable Material, Physics, and Sprite Galleries. The representative-scene matrix remains the authority for those existing surfaces and their automated proof.
3.3 Non-goals
The first complete implementation MUST NOT require:
- authored terrain, rooms, doors, or navigation meshes;
- a persistent open-world database;
- procedural level generation beyond the background marker field;
- Jolt rigid bodies for enemies or bullets;
- arbitrary mid-wave serialization;
- online or local multiplayer;
- a universal visual ability scripting language;
- campaign narrative, dialogue, captions for story, profile creation, or menu theatrics;
- reuse of unverified music, fonts, text, or imagery from the Godot archive;
- exact parity with every prototype bug, value, or UI decision.
3.4 Session targets
| Metric | Initial target |
| Full successful run | 30–45 minutes |
| Standard wave | 35–75 seconds |
| Act boss | 75–150 seconds |
| Final Shadow encounter | 150–240 seconds including interludes |
| Intermission | 3.0 seconds, skippable |
| Draft duration | Player-controlled; simulation paused |
| Reference viewport | 1600×900 |
| Regular camera view | 25.0 × 14.0625 WU at 16:9 |
| Boss camera view | 32.0 × 18.0 WU at 16:9 |
| Simulation tick | 60 Hz |
4. Core design pillars
Pillar 1 — Continuous motion without camera friction
The player should feel free to commit to any direction without colliding with an arbitrary screen edge. Movement must be crisp enough that the centered camera does not make the world feel delayed or seasick.
Pillar 2 — Shape, motion, and attack communicate role
Color is reinforcement, not the sole code. A triangle that rushes, a square that establishes range, a diamond that commits to a charge, a pentagon that splits, and a hexagon that absorbs damage should be identifiable at a glance and in color-vision accessibility modes.
Pillar 3 — Authored progression, structured variation
Waves, unlocks, perk milestones, and bosses are authored. Exact pack order, angular arrival, surge side, drop positions, and some elite modifiers vary by seed. The player learns systems rather than memorizing spawns.
Pillar 4 — Upgrades must alter play, not only arithmetic
The perk system should visibly change projectiles, dash behavior, sustain, defense, or death reactions. Pure numerical gains are allowed but should not dominate the run.
Pillar 5 — Every combat consequence has one canonical path
All damage enters DamageEvent; all deaths enter DeathEvent. Dash kills, explosions, bullets, contact, bosses, drones, and status effects must produce consistent score, drops, procs, VFX, and cleanup.
Pillar 6 — Infinite presentation, bounded computation
Nothing in the player's normal movement suggests a world edge, but every simulation resource has a defined cap, lifetime, active radius, or recycle rule.
Pillar 7 — Readability outranks spectacle
Effects may be bright and energetic, but hitboxes, hostile projectiles, telegraphs, and the player silhouette must remain readable under maximum intended load.
5. Complete gameplay loop
5.1 Run lifecycle
- Create a run from a seed and difficulty profile.
- Initialize base player stats, weapons, dash, health, armor, score, and deterministic random streams.
- Start wave 1 at the player's current logical coordinate.
- Resolve standard waves through the encounter director.
- Between waves, clear or gracefully retire transient hazards, vacuum eligible pickups, show a three-second intermission, and save a wave-boundary checkpoint.
- At perk milestones, pause the simulation and resolve the specified draft.
- At waves 10, 20, 30, and 31, create a boss lockfield and enter the authored boss state machine.
- On player death, present restart-from-checkpoint, restart-run, and exit actions.
- On Shadow defeat, resolve the run, show build/score/seed statistics, and permit immediate restart.
5.2 Standard-wave loop
- WaveDefinition commits a total threat budget and roster.
- The director divides that budget into packs.
- Packs are scheduled against a target intensity curve.
- Spawn placement selects off-screen positions in the annulus around the camera.
- Enemies remain non-attacking until their arming and visibility conditions are met.
- The player kills enemies and collects health/armor drops.
- Enemies that become irrelevant outside the hard leash are safely recycled without kill credit.
- The wave completes only when all committed threat tokens have been defeated and no required child-spawn debt remains.
- Remaining hostile projectiles dissolve over a short cleanup window.
- Drops are magnetized or converted according to the intermission rules.
5.3 Moment-to-moment loop
- Move to manage approach angles.
- Aim independently of movement.
- Hold primary fire for sustained damage.
- Use scatter fire for burst, crowd control, or a dangerous close target.
- Dash to avoid a committed attack, cross a projectile lane, reposition, or trigger dash perks.
- Read incoming shape/motion telegraphs.
- Convert kills into space, score, sustain, and perk reactions.
- Decide whether to continue in the current travel direction or rotate into a safer angular sector.
5.4 Failure and checkpoint model
The save system is explicitly a wave checkpoint.
A checkpoint contains:
- version and content schema hash;
- run seed and deterministic stream states at the checkpoint;
- next wave number;
- score and run time;
- player health and armor;
- player base stats and perk ranks;
- weapon and dash configuration;
- one-shot states such as Phoenix used/not used;
- difficulty profile;
- optional statistics.
It does not contain live enemies, projectiles, pickups, particles, or a boss halfway through a phase. Loading recreates the start of the saved wave. Checkpoints MUST be written only after a draft has committed and before the next wave begins, or at an equivalent explicit safe boundary.
6. Spatial scale and reference conversion
The Godot sketch uses a 1600×900 viewport and pixel-space movement. PixelBullet should use world units while preserving its approximate proportions.
6.1 Reference scale
1 WU = 64 reference pixels
At the regular camera zoom:
- visible width: 25.0 WU;
- visible height: 14.0625 WU;
- visible circumradius: approximately 14.34 WU;
- player radius: 0.25 WU.
This scale keeps values human-readable and makes the existing prototype a useful tuning baseline.
6.2 Reference gameplay values
| Element | Godot sketch | PixelBullet initial target |
| Player radius | 16 px | 0.25 WU |
| Move speed | 280 px/s | 4.375 WU/s |
| Dash speed multiplier | 2.8× | 2.8× |
| Dash active time | 0.15 s | 0.15 s |
| Dash distance | 117.6 px | 1.84 WU |
| Primary cadence | 0.11 s | 0.11 s |
| Primary projectile speed | 950 px/s | 14.84 WU/s |
| Primary projectile radius | 4 px | 0.0625 WU |
| Scatter pellet count | 6 | 6 |
| Scatter speed range | 850–1050 px/s | 13.28–16.41 WU/s |
| Scatter half-spread | 0.35 rad | 0.35 rad |
| Scatter cooldown | 1.0 s | 1.0 s |
| Magnet radius | 260 px | 4.06 WU |
| Slow field radius | 160 px | 2.5 WU |
| Chain explosion radius | 110 px | 1.72 WU |
These values are starting references. Boundless spawning, camera motion, and the absence of walls may require modest changes, but the rewrite should begin close enough that the original feel is recognizable.
7. Player controls, movement, inertia, and weapons
7.1 Input actions
The gameplay layer MUST consume named actions rather than raw keys.
| Action | Keyboard/mouse default | Controller default |
| Move | WASD / arrow keys | Left stick |
| Aim | Mouse position relative to view center | Right stick |
| Primary fire | Left mouse, hold | Right trigger |
| Scatter fire | Right mouse | Left trigger |
| Dash | Space | South face button / bumper |
| Pause | Escape | Menu |
| Skip intermission | Enter or Space | Confirm |
| Select perk | Pointer or 1/2/3 | Stick/D-pad and Confirm |
The first release MAY omit controller support, but the action model, dead-zone handling, and UI navigation interfaces MUST not assume mouse-only input.
Input sampling happens once per rendered frame and is converted to a deterministic PlayerCommand consumed by fixed simulation ticks. Edge-triggered actions such as dash and card confirmation MUST be latched until consumed by a simulation tick, so they cannot be lost between render and fixed updates.
7.2 Aiming
Mouse
The logical player is always at the camera center during standard combat. Mouse aim is therefore:
aim_vector = cursor_position_in_view_pixels - viewport_center_pixels
The vector is normalized only after applying a minimum magnitude.
Requirements:
- Aim MUST have no inertia, smoothing, acceleration, or camera-look-ahead contribution.
- If the cursor is within an 8-reference-pixel center dead radius, retain the last valid aim direction.
- Screen shake MUST NOT change the logical aim vector.
- UI scaling and letterboxing MUST be accounted for before deriving the vector.
- Cursor-to-world ray projection MAY be used by the engine, but the resulting aim direction must be mathematically equivalent on the flat gameplay plane.
Controller
- Use a circular dead zone, initial target 0.18.
- Remap the remaining magnitude to [0,1].
- Retain the last valid aim direction when the stick returns to center.
- Aim assist is out of scope for the baseline.
- Controller reticle distance SHOULD be fixed in screen space or proportional to stick magnitude without affecting the direction used for projectiles.
7.3 Movement model
The prototype moves immediately at full speed. In a centered-camera game, both excessive inertia and perfectly discontinuous keyboard velocity can look harsh. The recommended compromise is short, asymmetric velocity convergence:
- fast enough to preserve arcade precision;
- enough acceleration to prevent one-frame velocity snapping;
- even faster deceleration so release does not feel like sliding;
- very fast reversal so directional dodging remains viable.
Initial targets:
| Parameter | Target |
| Maximum base speed | 4.375 WU/s |
| Time from rest to 95% speed | 0.08 s |
| Time from full speed to 5% after release | 0.06 s |
| Time to reverse from full forward to 95% backward | 0.10 s or less |
| Keyboard diagonal policy | Normalize to unit circle |
| Analog response | Linear after dead-zone remap |
| Maximum speed perk cap | 6.0 WU/s before temporary effects |
A frame-rate-independent exponential convergence is preferred:
velocity = lerp_exp(velocity, desired_velocity, response_hz, fixed_dt)
or an equivalent move_toward implementation with separately configured acceleration and braking. The exact formula is less important than matching the measured response times.
The movement system MUST NOT:
- simulate mass for normal movement;
- retain drift after input release;
- rotate or tilt the camera based on velocity;
- change maximum speed with render frame rate;
- let keyboard and controller diagonals exceed cardinal speed.
7.4 Dash
The dash is an explicit ability state, not a temporary change to generic movement acceleration.
Activation
- Edge-triggered.
- Requires cooldown ready.
- Requires the player to be alive and not in a paused/draft/transition state.
- Dash direction is sampled once at activation.
- Direction priority:
- current non-zero movement input;
- last valid movement direction;
- current aim direction;
- default +X only as a final safety fallback.
Motion
Initial targets:
- active time: 0.15 s;
- speed: 12.25 WU/s;
- distance: approximately 1.84 WU;
- cooldown: 1.8 s;
- invulnerability: active dash interval plus no more than one simulation tick of exit grace;
- steering: none by default;
- collision: dash may pass through ordinary enemies but must still generate dash-contact events for perks;
- boss lockfield: analytic sweep against the circular boundary, ending in a tangent slide rather than tunneling outside.
The dash MUST be resolved through a swept movement path. Dash-damage perks query the swept capsule/segment, not only the final player position.
Feedback
- Player fill changes from cyan to white or near-white.
- A cyan afterimage trail is emitted at a bounded rate.
- A short synth cue plays with priority above primary-fire cues.
- Camera shake is small and presentation-only.
- Cooldown is visible in the HUD and through a subtle player-ring state.
- Invulnerability is never communicated only through color.
7.5 Primary weapon
Initial behavior:
- automatic while held;
- cadence: 0.11 s before modifiers;
- projectile speed: 14.84 WU/s;
- radius: 0.0625 WU;
- base damage: 1.0;
- random angular deviation: up to ±0.06 rad;
- muzzle offset: 0.31 WU;
- range and lifetime: defined in Section 12;
- no physical recoil to player movement;
- a very small presentation recoil MAY offset the barrel/shape for less than 0.08 s.
The weapon MUST use an accumulator or scheduled next-fire time that behaves consistently at 60 Hz. It MUST NOT fire more than one unplanned catch-up shot after a long frame; clamped fixed stepping and a bounded fire accumulator prevent bursts caused by stalls.
7.6 Scatter weapon
Initial behavior:
- six pellets;
- evenly distributed base spread between -0.35 and +0.35 rad;
- per-pellet random deviation up to ±0.05 rad;
- speed randomized between 13.28 and 16.41 WU/s;
- one-second cooldown;
- base pellet damage 1.0, subject to later balance;
- short range and lifetime;
- visible muzzle ring and stronger audio cue.
The Godot sketch applies a 10-pixel backward displacement. In the centered-camera version, moving the player also moves every world reference on screen, so a large instantaneous recoil would be visually disruptive. The baseline SHOULD use:
- presentation recoil on the player/barrel;
- optional physical impulse no greater than 0.12 WU;
- exponential recovery completed within 0.12 s;
- no recoil that can cross a boss lockfield or cancel a dash.
7.7 Health, armor, damage, and invulnerability
Initial baseline:
- maximum health: 100;
- base armor: 0;
- armor absorbs incoming damage before health;
- ordinary hostile projectile: approximately 10;
- kamikaze contact/explosion: approximately 12;
- ordinary contact: approximately 18;
- Shadow slash: approximately 25.
All incoming damage MUST carry:
- source entity or source archetype;
- team;
- damage type;
- amount;
- hit position and normal where applicable;
- flags such as bypass armor, boss, contact, projectile, explosion;
- proc generation/depth;
- simulation tick.
Player invulnerability windows MUST be represented explicitly. Damage events received during invulnerability are rejected before armor/health mutation but MAY still create a low-intensity deflection effect if desired.
Repeated contact damage requires a per-source or global contact cooldown. The player MUST NOT lose multiple full contact hits from the same overlapping enemy on adjacent ticks unless the enemy is explicitly designed as a damage-over-time hazard.
7.8 Pickups
Two baseline pickup types are retained:
Rules:
- pickups exist in world space and move relative to the centered camera;
- default lifetime: 12 s, with 15 s for rare or boss-interlude drops;
- pickup radius: approximately 0.19 WU;
- collection uses a circle overlap with the player;
- health and armor cannot exceed their maxima unless a perk explicitly permits overcharge;
- during intermission, all eligible pickups within the active region are magnetized toward the player at high speed;
- any uncollected pickup still active when the next wave starts remains for no more than a short grace period;
- pickup count is capped;
- when the cap is reached, the system SHOULD merge value into an existing nearby pickup or replace the oldest low-value pickup rather than silently losing reward.
A boundless world makes abandoned drops more common. The wave-end vacuum is therefore a core rule, not merely a magnet-perk substitute. The Magnet perk improves collection during combat and expands the intermission collection guarantee.
7.9 Player-system acceptance criteria
MOV-AC-01 — At 60, 120, 144, and uncapped render rates, maximum speed and dash distance differ by less than 1% over a ten-second automated measurement.
MOV-AC-02 — The player reaches 95% of base speed in 0.06–0.10 s and falls below 5% in 0.04–0.08 s.
MOV-AC-03 — Releasing movement produces no perceptible drift after the braking interval.
MOV-AC-04 — Mouse aim remains stable while moving, rebasing, resizing the window, and applying maximum camera shake.
MOV-AC-05 — A dash cannot be lost because it was pressed between fixed ticks.
MOV-AC-06 — Dash collision and dash-damage tests cover the full swept path.
MOV-AC-07 — The player cannot leave a boss lockfield through dash, recoil, knockback, or numerical error.
MOV-AC-08 — Holding primary fire for five minutes does not create fire-rate drift, unbounded event accumulation, or allocation growth.
MOV-AC-09 — Pickup collection, clamping to maxima, expiry, and wave-end vacuum are deterministic for a fixed seed and command stream.
8. Camera behavior
8.1 Standard-wave camera
The camera MUST be character-centered:
camera_logical_position = player_logical_position
player_screen_position = viewport_center
This relationship holds during ordinary gameplay except for presentation effects that do not alter simulation.
There is:
- no dead zone;
- no soft zone;
- no follow damping;
- no velocity look-ahead;
- no aim look-ahead;
- no camera spring.
The camera may use render interpolation between the previous and current fixed-tick player poses. This interpolation MUST be visually smooth and MUST NOT feed back into collision, aiming, spawning, or gameplay-space queries.
8.2 Camera layers
Use separate conceptual layers:
- Logical camera — exact player position; used for visibility, spawn tests, audio relative positions, and world-to-view transforms.
- Interpolated render camera — interpolated between fixed snapshots.
- Presentation impulse — shake, brief boss impact, or transition offset.
- UI camera — unaffected by world shake.
Spawn placement and off-screen tests MUST use the logical camera without shake. Aim mapping MUST use the unshaken view center.
8.3 Camera shake
Recommended trauma model:
- events add normalized trauma;
- visual translation and optional rotation derive from decaying noise;
- maximum regular translation: approximately 0.10 WU;
- heavy boss-death translation MAY reach 0.25 WU;
- rotation should remain below 0.5° by default;
- shake scale is user-configurable from 0–100%;
- gameplay collision, world origin, reticle direction, UI, and spawn frustum are unaffected.
High-frequency primary shots should use barrel recoil and tiny local impulses rather than repeatedly shaking the entire screen.
8.4 Zoom
Regular waves
The default view at 16:9 is 25.0 × 14.0625 WU.
Zoom SHOULD remain fixed during standard combat. Dynamic zoom based on speed or enemy count would alter spawn visibility and aiming scale and is not justified for the baseline.
Boss waves
Boss intro transitions to a 32.0 × 18.0 WU view over 0.75–1.0 s with an ease-in/out curve. The lockfield radius is selected to fit vertically with a safety margin.
During the transition:
- gameplay is paused or the boss is invulnerable and non-attacking;
- hostile projectiles are absent;
- the player remains centered;
- all view-dependent systems receive the current interpolated extents;
- the spawn director is disabled except for boss-authored interludes.
After victory, the camera returns to the regular view before standard-wave control resumes.
8.5 Aspect ratio and resize policy
Vertical gameplay span is authoritative:
- regular orthographic height: 14.0625 WU;
- boss orthographic height: 18.0 WU.
Wider displays see more horizontal world. Narrower displays see less. The director uses the actual frustum for spawn rejection and activation, so no enemy appears inside the visible area.
To avoid severe aspect-ratio balance divergence:
- supported baseline range: 4:3 through 21:9;
- boss lockfield must remain fully visible in the vertical dimension;
- horizontal extra visibility does not reduce total threat budget;
- edge telegraphs use the actual safe frame;
- score leaderboards, if added later, MAY separate aspect-ratio classes; no such leaderboard is required now.
On resize:
- recompute view geometry immediately;
- suppress new spawns for 0.5 s;
- do not delete enemies that become visible due to enlargement;
- hostile enemies newly revealed by resize remain attack-gated for at least 0.35 s;
- update RmlUi scaling and safe zones;
- do not change player movement scale or weapon speed.
8.6 Camera acceptance criteria
CAM-AC-01 — Excluding presentation shake, the player center deviates by no more than 0.5 display pixel from the logical viewport center.
CAM-AC-02 — No camera damping or look-ahead is observable during rapid direction reversals.
CAM-AC-03 — Maximum shake does not alter aim direction, spawn visibility classification, hit detection, or UI position.
CAM-AC-04 — Boss zoom transitions contain no one-frame projection jump and preserve the player's exact screen center.
CAM-AC-05 — At 4:3, 16:9, 16:10, and 21:9, the boss lockfield and all required telegraphs are visible and correctly clipped.
CAM-AC-06 — Window resize cannot produce an immediate unavoidable off-screen attack.
9. Effectively boundless world and coordinate strategy
9.1 Conceptual model
The world has no gameplay boundary during standard waves, but it also has no fully materialized infinite map.
At any time the implementation maintains:
- a logical global origin;
- a camera-relative active simulation bubble;
- a deterministic procedural background field;
- active enemies, projectiles, pickups, and VFX near the player;
- no persistent ordinary enemies outside the active bubble;
- no terrain streaming in the baseline.
“Travel” is real in logical coordinates and visible through the grid and markers, but it does not require retaining every location visited.
9.2 Coordinate types
Persistent logical position
struct WorldPosition2D {
int64_t chunk_x;
int64_t chunk_y;
float2 local;
};
Initial chunk size: 256 WU.
Operations MUST normalize overflow or underflow in local into the integer chunk coordinates.
Active local position
Hot ECS components use camera-relative or current-origin-relative float2:
struct LocalPosition2D {
float2 value;
};
All active values should remain within a few dozen WU of zero.
World origin state
struct WorldOrigin2D {
WorldPosition2D logical_origin;
float2 local_player_offset;
uint64_t revision;
};
The exact structure may follow PixelBullet conventions, but the following properties are required:
- integer-backed persistent displacement;
- compact float local transforms;
- monotonic origin revision;
- one authoritative conversion path between logical and local positions.
9.3 Origin rebasing
Initial rebase threshold: 64 WU from the current local origin on either axis.
At the end of a fixed movement stage, before the broadphase is updated:
- Determine a rebase offset aligned to an implementation-friendly quantum, recommended 32 WU.
- Add that offset to the logical world origin.
- Subtract it from every active world-space local position.
- Increment the origin revision.
- Rebuild or translate spatial-grid keys.
- Update cached boss anchors, telegraphs, audio emitters, trail history, procedural marker queries, and interpolation snapshots.
- Publish an OriginShiftEvent for systems with local caches.
- Continue the same fixed tick without changing logical distances.
The player should remain near local (0,0), but it is not necessary to shift every tick. Periodic quantized shifts reduce system churn while retaining high precision.
Systems that MUST respond to rebasing
- player and enemies;
- boss and lockfield anchor;
- projectiles;
- pickups;
- gameplay hazards;
- particles and decals that use world coordinates;
- trails with historical points;
- spatial broadphase;
- spawn candidates and telegraphs;
- audio emitters;
- render interpolation snapshots;
- debug drawing;
- procedural background phase.
Systems that MUST NOT shift
- screen-space UI;
- input cursor position;
- logical run statistics;
- cooldown timers;
- entity identities;
- deterministic random streams;
- score or wave state.
Non-critical cosmetic trails MAY be cleared on origin shift only as an early implementation concession, but release quality SHOULD translate them without a visible break.
9.4 Procedural grid
The Godot reference uses a near-black navy field with very faint 50-pixel grid lines. PixelBullet should preserve this language as an infinite world-space grid.
Requirements:
- minor grid spacing: approximately 0.78125 WU at the reference conversion;
- major line every 4 or 8 minor cells;
- low alpha, with the minor grid substantially dimmer than every hostile projectile;
- stable world phase derived from logical coordinates;
- anti-aliased lines or shader derivatives to prevent shimmer;
- no geometry tessellation across the world;
- generated in a full-screen or camera-plane shader from camera-relative coordinates;
- origin shifts produce no phase jump.
The shader receives a split or modulo representation of logical camera position sufficient to reconstruct grid phase without large floats.
9.5 Ambient travel markers
An empty infinite grid can feel like a treadmill. Add sparse, non-colliding markers generated deterministically from chunk coordinates:
- crosshair nodes;
- broken rings;
- small coordinate ticks;
- faint line clusters;
- rare larger “vector beacons.”
Markers are visual only. They:
- are stable when the player backtracks;
- have no gameplay reward or collision;
- use a hash of logical chunk/cell coordinates;
- are drawn at very low contrast;
- fade before competing with enemies;
- provide parallax-free but stable evidence of travel;
- may subtly shift motif or color tint by campaign act.
The marker field MUST NOT imply destinations the player is expected to reach.
9.6 Active-region radii
All radii derive from the current logical camera view.
Let:
half_extent = (view_width / 2, view_height / 2)
visible_radius = length(half_extent)
Initial regular-view values:
- visible circumradius Rv ≈ 14.34 WU;
- spawn inner radius generally Rv + 1.5–3.0 WU, adjusted by role;
- spawn outer radius Rmin + 4–6 WU;
- full-simulation soft radius approximately Rv + 8 WU;
- hard lifecycle radius approximately Rv + 18 WU.
These are not substitutes for actual frustum tests. The radius is a broad filter; visibility uses the expanded view rectangle or frustum on the gameplay plane.
9.7 Long-run precision
With integer chunks, the run can travel for practical durations without approaching floating-point precision limits. Local floats remain near the origin.
A soak test MUST hold movement in one direction at maximum supported speed for at least 60 minutes and verify:
- no visible entity jitter;
- no grid or marker phase jump;
- no collision divergence;
- no accumulating local coordinate magnitude;
- no entity loss during rebase;
- no audio pan discontinuity;
- no interpolation snap.
9.8 World-system acceptance criteria
WRLD-AC-01 — Sixty minutes of continuous maximum-speed travel produces no visible precision jitter at 1080p or 1440p.
WRLD-AC-02 — Origin shifts are invisible in the player, enemies, projectiles, pickups, grid, markers, and boss field.
WRLD-AC-03 — Pairwise distances before and after a rebase differ by less than 1e-4 WU for active gameplay entities.
WRLD-AC-04 — No hot simulation transform exceeds the configured local safety range during the soak test.
WRLD-AC-05 — Backtracking returns to the same deterministic background marker pattern.
WRLD-AC-06 — A rebase cannot alter RNG outcomes, cooldown order, damage resolution, or wave completion.
10. Enemy roster and behavior specification
10.1 Shared rules
Every standard enemy has:
- an archetype ID;
- shape visual;
- color role;
- circular collider;
- movement and attack parameters;
- threat cost;
- encounter token;
- activation state;
- arming timer;
- leash/recycle state;
- health;
- score value;
- optional child-spawn rule;
- optional elite modifier set.
All ordinary enemies MUST follow these global rules:
- They do not deal damage while unarmed.
- Shooters do not fire while outside the visible frustum.
- Chargers and kamikazes do not begin a committed attack off-screen.
- Spawned enemies receive a visible entry cue before becoming dangerous.
- Enemy movement continues at fixed tick regardless of render rate.
- Enemies do not use Jolt rigid-body dynamics.
- Separation and local avoidance may alter direction but not hide a committed telegraph.
- All damage and death use canonical events.
- Enemy deletion outside the active region does not count as a kill.
10.2 Role table
| Archetype | Shape/color reference | Initial size | Initial speed | Health | Threat cost | Primary role |
| Runner | Magenta triangle | 0.1875 WU | 3.28 WU/s | 2 | 1.0 | Direct pursuit pressure |
| Shooter | Lime square | 0.2344 WU | 2.19 WU/s | 3 | 2.0 | Establishes aimed lanes |
| Charger | Orange diamond/four-sided shape | 0.25 WU | 2.66 WU/s; 6.91 charge | 4 | 2.5 | Telegraph then committed rush |
| Splitter | Turquoise pentagon | 0.2813 WU | 2.03 WU/s | 3 | 3.0 | Creates child pressure on death |
| Bulwark/Tank | Violet hexagon | 0.375 WU | 1.41 WU/s | 8 | 5.0 | Slow space denial and protection |
| Kamikaze | Yellow narrow triangle | 0.1719 WU | 5.0 WU/s | 1 | 1.5 | High urgency contact explosion |
| Mini-splitter | Small cyan triangle | 0.125 WU | 3.44 WU/s | 1 | Child debt | Short-lived child pressure |
Values remain close to the Godot sketch but become data assets.
10.3 Runner
Behavior:
- chooses player position as primary target;
- adds mild separation from nearby allies;
- may use small lateral noise, but must not orbit indefinitely;
- contact damage uses the ordinary contact cooldown;
- rotates continuously to preserve the reference visual language.
Readability:
- fastest common triangle after the kamikaze;
- magenta fill with a thin brighter leading edge;
- no pre-attack telegraph beyond entry arming.
Counterplay:
- primary fire and movement;
- dash through or around packs;
- scatter weapon at close range.
10.4 Shooter
Behavior:
- approaches until within preferred band, initial target 3.5–4.5 WU;
- strafes or drifts laterally within that band;
- fires aimed projectiles at an initial 1.3 s cadence;
- may lead the player only on higher difficulty or elite variants;
- cannot fire until visible and armed;
- aborts a pending shot if recycled or moved off-screen by a sudden resize.
Telegraph:
- square briefly compresses or brightens;
- a thin aim stem or corner pulse appears for at least 0.25 s;
- audio tick precedes projectile release;
- projectile origin is clearly visible.
The shooter should create lanes, not snipe from outside the camera.
10.5 Charger
State machine:
- Approach — moves at 40–60% normal speed.
- Acquire — samples a charge direction toward the player's then-current position.
- Telegraph — orange outline stretches along the charge vector for 0.4–0.6 s.
- Commit — moves at approximately 6.9 WU/s for a bounded duration or distance.
- Recover — slows and cannot immediately reacquire.
Rules:
- no steering or only minimal steering during commit;
- the telegraph must begin while visible;
- collision uses swept movement;
- if the player outruns the active bubble during telegraph, the charge is cancelled and the enemy enters catch-up;
- ordinary chargers die or are staggered on contact according to balance; they must not apply repeated overlap damage.
10.6 Splitter
Behavior:
- pursues at moderate speed;
- on canonical death, creates two child-spawn requests to opposite or contextually clear sides;
- children inherit the parent encounter token as child debt;
- children do not spawn inside another collider or inside the player;
- children have a brief 0.15–0.25 s non-damaging materialization cue.
Capacity rule:
- the director reserves child capacity before spawning a splitter;
- if the child cap is unexpectedly exhausted, excess child debt converts to a bounded radial effect or deferred spawn rather than allocating beyond the hard cap;
- the wave does not complete until required child debt is resolved.
10.7 Bulwark/Tank
Behavior:
- slow pursuit;
- large collider and high health;
- acts as moving cover for smaller enemies through body occupancy, not projectile blocking unless an elite modifier explicitly adds it;
- may create a low-strength separation field that prevents dense overlap;
- no unavoidable contact stun.
The prototype's normal-wave tank branch is unreachable because of condition ordering. The rewrite MUST use weighted data entries, making the role intentionally available from its authored unlock wave.
10.8 Kamikaze
Behavior:
- high-speed pursuit after visible arming;
- pulsing yellow warning increases as distance closes;
- contact creates a damage/explosion event and kills the kamikaze;
- may be intercepted by projectiles;
- never spawns with a predicted time-to-visible below the configured safety floor;
- never starts already committed from off-screen.
The explosion is an ordinary damage source and follows the same event path as every other damage type.
10.9 Mini-splitter
Behavior:
- short direct pursuit;
- lower score and no drop by default;
- no further split;
- lifecycle remains tied to the parent wave token.
10.10 Local avoidance
A simple weighted steering solution is sufficient:
desired =
seek_weight * normalized(target - position)
+ separation_weight * separation_vector
+ lane_weight * role_specific_lateral_vector
Requirements:
- uniform-grid neighbor query;
- no all-pairs scan;
- maximum steering rate per role;
- committed charger movement ignores ordinary avoidance;
- avoidance cannot push an enemy across the player in one tick;
- avoidance has deterministic ordering or order-independent accumulation.
No navmesh is needed because the baseline world has no obstacles.
10.11 Elite modifiers
Elites are data-driven modifiers applied to existing shapes, not new archetypes. Initial candidate set:
- Hardened: health increase, thicker outline;
- Accelerated: modest speed increase, not applied to kamikaze beyond safety cap;
- Shielded: finite armor layer;
- Volatile: death burst with clear icon/outline;
- Suppressor: shooter fires a short burst with longer telegraph;
- Commander: nearby ordinary enemies receive a small speed or cadence buff while it lives.
Rules:
- maximum one modifier in Act II, up to two in Act III only if readability remains clear;
- no modifier removes a role's core counterplay;
- elite outline/icon communicates the modifier independently of hue;
- elite threat cost is multiplied accordingly;
- elite effects are resolved through the same typed modifier/effect system used elsewhere where practical.
10.12 Enemy acceptance criteria
ENMY-AC-01 — Each role is correctly identified by at least 90% of internal playtest participants from shape and motion with colors desaturated.
ENMY-AC-02 — No shooter projectile is created while the shooter is outside the logical visible frustum.
ENMY-AC-03 — No charger or kamikaze begins its dangerous state before entering view and completing its minimum telegraph.
ENMY-AC-04 — Splitter child creation cannot exceed entity caps or allow the wave to complete early.
ENMY-AC-05 — Ordinary movement and local avoidance have no all-pairs complexity.
ENMY-AC-06 — Contact damage cannot repeat every tick from one sustained overlap.
ENMY-AC-07 — A recycled enemy preserves encounter-token accounting and grants no score, drop, lifesteal, or kill proc.
11. Enemy spawning, activation, distribution, and retirement
11.1 System objective
The spawn system MUST make the world feel continuously inhabited without allowing enemies to appear visibly, attack from an unreadable position, accumulate indefinitely, or become irrelevant stragglers. It is responsible for preserving the authored threat of each wave while varying arrival direction and timing.
The system consists of four related services:
- Encounter Director — decides which committed encounter tokens are eligible to enter play and at what cadence.
- Spawn Placement — finds a fair off-screen location for a specific pack.
- Activation Controller — transitions spawned entities from concealed/pre-entry states to visible combat behavior.
- Relevance Manager — catches up, retires, or recycles entities that remain too far from the local action.
The director MUST NOT instantiate enemies directly. It emits a SpawnPackRequest containing a pack definition, token membership, preferred angular sector, timing constraints, and optional formation. The placement system either returns a validated placement or reports a bounded failure so the director can defer or select a different sector.
11.2 Spawn geometry
11.2.1 Visible-region definition
The logical visible frustum is the camera's gameplay-space orthographic rectangle before presentation shake. Spawn fairness MUST be calculated against this logical frustum, not the shaken or interpolated render camera.
An expanded visible region is the logical frustum dilated by a configurable safety margin. No ordinary enemy may be instantiated inside it.
For a reference 25.0 × 14.0625 WU view:
- horizontal half-extent: 12.5 WU;
- vertical half-extent: 7.03125 WU;
- circumradius: approximately 14.34 WU;
- initial static spawn margin: 1.5 WU;
- ordinary spawn band width: 4–6 WU beyond the minimum safe distance.
The implementation SHOULD calculate distance to the actual expanded rectangle rather than approximate all placement with a circle. An annular radius remains useful for broad candidate generation, but final validation MUST use the frustum and predicted entry path.
11.2.2 Dynamic minimum distance
The minimum spawn distance MUST account for how rapidly the enemy could reach the view. For candidate position p, initial movement direction d, enemy speed ve, camera/player velocity vp, and required reaction time tr, the placement system evaluates predicted time to intersect the expanded view.
A practical conservative bound is:
relative_entry_speed = max(0, dot(ve * d - vp, toward_view_normal))
lead_margin = relative_entry_speed * tr
minimum_clearance = static_margin + enemy_radius + lead_margin
The exact implementation MAY use a ray-versus-expanded-rectangle time calculation. It MUST reject placements whose predicted time-to-visible is below:
| Threat | Minimum initial target |
| Runner, splitter, tank | 0.65 s |
| Shooter | 0.80 s |
| Charger | 1.00 s before visible commitment |
| Kamikaze | 1.10 s before visible commitment |
| Elite pack | 1.00 s |
| Announced surge | 0.75 s after border telegraph begins |
Speed perks, run modifiers, camera zoom, aspect ratio, and enemy acceleration MUST participate in the calculation. A static radius is insufficient.
11.2.3 Angular sectors and heat
The area around the player is divided into 16 angular sectors in logical world space. Each sector stores:
- last spawn tick;
- short-term spawn heat;
- active-threat count approaching from that sector;
- recent player heading exposure;
- whether it intersects an active surge reservation;
- whether it was invalidated by camera aspect or boss state.
Heat decays over time. Ordinary packs prefer low-heat sectors, with weighted variation rather than always selecting the mathematically coolest sector. This prevents a visibly mechanical round-robin pattern while reducing repetitive back-spawns.
A sector may be temporarily reserved for:
- a directional surge;
- an elite introduction;
- a scripted pre-boss composition;
- a safety exclusion after a dash toward that side;
- a recent recycle destination.
The director SHOULD avoid spawning more than 45% of a short-window threat budget in one 90-degree quadrant unless the wave explicitly calls for a directional surge.
11.2.4 Pack separation
Within a pack, candidates use Poisson-like minimum separation rather than identical coordinates. Initial target values:
- ordinary body separation: sum of radii + 0.15 WU;
- shooter separation: sum of radii + 0.35 WU;
- elite separation: sum of radii + 0.45 WU;
- surge lane width: 1.5–3.0 WU depending on count and role.
Pack placement MUST avoid:
- overlap with another pending spawn pack;
- overlap with persistent pickups or boss beacons;
- a path that crosses the visible region before the activation telegraph expires;
- a single-file stack that visually hides dangerous enemies;
- a placement that forces all entities through the same exact point.
No general navigation query is required in the first version because the standard world has no obstacles.
11.3 Spawn modes
11.3.1 Ambient pack
The default mode introduces one to several enemies from a low-heat sector. It receives a short concealed travel interval and enters view naturally. No special screen-edge warning is required for ordinary low-threat packs.
11.3.2 Directional surge
A surge commits a pack from one side or a contiguous set of sectors and is a deliberate pacing event. It MUST include:
- a 0.6–0.9 second edge telegraph spanning the relevant approach arc;
- a distinctive but non-alarming audio rise;
- enough formation width to create a lane or front rather than a single clump;
- a per-wave cap on simultaneous surge directions;
- no hostile fire before visible activation.
Surges SHOULD use runners, chargers, splitters, or mixed melee pressure. Shooter-heavy surges require longer preparation and staggered activation so the screen does not instantly fill with synchronized fire.
11.3.3 Cross-angle composition
Later waves may reserve two non-adjacent sectors. One pack establishes pressure; the second arrives after a configured offset. This creates pincer-like pressure without spawning directly on the player's current escape vector.
The secondary pack MUST respect the same visibility and reaction constraints. Cross-angle logic MUST NOT continuously predict and punish the player's preferred direction; it is an authored composition, not adversarial input reading.
11.3.4 Elite or role introduction
The first appearance of a new dangerous role or elite modifier SHOULD use a low-density introduction:
- one highlighted entity or small pack;
- extended telegraph where needed;
- no simultaneous surge unless the wave explicitly tests recognition;
- temporary edge indicator until the threat becomes visible.
11.3.5 Boss transition
Boss waves disable ordinary annular spawning except for explicitly authored minion interludes. The boss is introduced through the lockfield sequence specified in Section 15.
11.4 Activation states
Each spawned enemy uses the following lifecycle:
ReservedToken
-> SpawnedConcealed
-> PreEntry
-> VisibleArming
-> Active
-> Dying / Defeated
-> Destroyed
Active
-> CatchUp
-> RecyclePending
-> SpawnedConcealed
SpawnedConcealed
- Entity exists in simulation and can move toward entry.
- It is not rendered unless a special telegraph is authored.
- It cannot attack, collide with the player, receive ordinary target locks, or grant rewards.
- It may be discarded and replaced if placement becomes invalid before entry.
PreEntry
- Entity is close enough to the expanded view that its arrival will occur soon.
- It may emit a restrained border glow for dangerous roles.
- It remains non-attacking.
VisibleArming
- Begins on first logical-frustum intersection.
- Entity becomes fully rendered and targetable.
- Role-specific minimum arming time elapses before dangerous actions.
- Movement may continue, but charger commitment, kamikaze detonation, and shooter fire are forbidden.
Initial arming targets:
| Role | Arming time |
| Runner | 0.10 s |
| Splitter/tank | 0.15 s |
| Shooter | 0.35 s before first shot |
| Charger | 0.45 s before wind-up may begin |
| Kamikaze | 0.50 s before lethal pulse may begin |
| Elite | base role + 0.10 s on first appearance |
Active
The entity participates in all normal combat systems.
CatchUp
An enemy that falls behind the action may receive a bounded movement multiplier and simplified steering. It MUST NOT attack while outside the expanded visible region. Catch-up is intended to restore relevance, not create an invisible projectile source.
RecyclePending
The entity is removed without death rewards and its encounter token is requeued for a new fair spawn. Health and elite state MAY be preserved; temporary status effects MUST be cleared unless the effect explicitly survives recycling. Recycled entities MUST not count as defeated.
11.5 Relevance radii and recycling
Distances are measured from the camera/player anchor using camera-relative coordinates.
Initial targets at the reference view:
| Region | Distance rule | Behavior |
| Core combat region | visible frustum + 2 WU | Full simulation and presentation |
| Soft relevance radius | view circumradius + 8 WU | Ordinary full simulation; attack still requires visibility |
| Catch-up region | beyond soft radius | Simplified pursuit, no attacks, reduced presentation |
| Hard relevance radius | view circumradius + 18 WU | Recycle eligible |
| Absolute simulation guard | view circumradius + 24 WU | Forced recycle/destruction for non-boss entities |
An active enemy becomes recycle-eligible when all are true:
- it has remained outside the soft radius for 4–6 continuous seconds;
- it is not currently visible or telegraphed;
- it is not a boss, pickup carrier, or authored persistent object;
- it has not dealt or received damage in the last 2 seconds;
- it is not in a committed charge that could re-enter fairly;
- recycling will not exceed the per-token recycle limit.
The per-token initial recycle limit is three. If a token repeatedly fails to engage, the director MUST either:
- choose a substantially different angular sector and pack arrangement;
- convert it to an equivalent lower-mobility role only when the wave definition explicitly permits substitution;
- mark a diagnostic error and resolve the token without reward after a hard timeout, preventing an unfinishable wave.
The last option is a safety valve, not expected gameplay. It MUST increment telemetry and fail automated soak thresholds if frequent.
11.6 Anti-kiting rules
Boundless space must not convert every encounter into moving endlessly in a straight line. Anti-kiting comes from encounter composition and relevance management, not invisible walls or unfair teleportation.
Required rules:
- spawn selection may modestly favor sectors 60–140 degrees ahead of prolonged player travel, but MUST retain at least 35% probability mass outside that forward band;
- no ordinary spawn may materialize in the visible path merely because the player is running quickly;
- ranged enemies establish lateral firing lanes after entering view rather than firing from behind the camera;
- chargers and surges create temporary directional commitments that ask the player to turn or cut across pressure;
- tanks and splitters act as spatial anchors and increase the cost of simply maintaining one heading;
- the director may shorten the next pack interval during long periods of zero nearby threat, but may not exceed the wave's maximum active threat or minimum telegraph floor;
- pickups use attraction, delayed convergence, or bounded auto-collection rules so the player is not forced to reverse across an arbitrarily long trail;
- wave completion is based on committed threat tokens, not distance traveled.
No system may read raw future input, spawn directly on a predicted cursor destination, or cancel the player's earned space without an authored telegraph.
11.7 Threat budget and population caps
Every enemy archetype has a threat cost. A wave has:
- total committed threat budget;
- maximum active threat;
- maximum active entity count;
- pack table and pack weights;
- cadence curve;
- surge reservations;
- elite budget;
- role minimums/maximums;
- hard time and stall diagnostics.
A representative starting cost table:
| Enemy | Threat cost |
| Mini-splitter | 0.5 |
| Runner | 1.0 |
| Shooter | 1.8 |
| Splitter, including child liability | 2.2 |
| Charger | 2.4 |
| Kamikaze | 2.0 |
| Tank | 3.5 |
| Elite modifier | ×1.35 to ×1.80 |
Threat cost is a director abstraction, not a score value. It must include expected descendants and dangerous modifiers so splitting cannot bypass active-threat limits.
The director MUST reserve capacity for child entities and on-death spawns before admitting a splitter or volatile elite. It MUST not fill all entity slots with ordinary enemies and then suppress required gameplay outcomes.
11.8 Encounter-token accounting
Each committed unit of wave content is represented by an EncounterTokenId. One token may own:
- one enemy;
- a pack of linked enemies;
- a splitter and its descendant liability;
- a surge formation;
- an elite escort group.
Token state is separate from entity lifetime:
enum class EncounterTokenState : uint8_t {
Pending,
ReservedForSpawn,
InPlay,
RecycleQueued,
Defeated,
ResolvedBySafetyValve
};
Wave completion requires:
- no pending or reserved tokens;
- no in-play or recycle-queued tokens;
- no boss or authored interlude state;
- all deferred death/proc events committed.
Destroying, culling, recycling, pooling, or losing an entity handle MUST NOT accidentally mark its token defeated.
11.9 Spawn-system acceptance criteria
SPWN-AC-01 — Across a deterministic Monte Carlo test of at least 100,000 ordinary placements over supported aspect ratios and maximum configured movement speeds, no enemy is instantiated inside the expanded logical visible region.
SPWN-AC-02 — Predicted first-visibility time meets the configured role floor in at least 99.99% of accepted placements; all exceptions are rejected before entity creation.
SPWN-AC-03 — No shooter, charger, kamikaze, or elite dangerous action occurs before visible activation and its arming delay.
SPWN-AC-04 — A 30-minute straight-line travel soak completes every standard wave without an invisible straggler stall.
SPWN-AC-05 — Recycling preserves token, health, elite, and wave accounting and produces no kill credit, score, drop, healing, audio stinger, or on-kill proc.
SPWN-AC-06 — Directional surges always have a border telegraph and minimum reaction interval at every supported aspect ratio.
SPWN-AC-07 — Spawn-sector heat prevents more than the configured quadrant concentration except in explicitly authored surge or cross-angle events.
SPWN-AC-08 — Entity and active-threat caps cannot be exceeded by split descendants, volatile effects, or simultaneous pack admission.
SPWN-AC-09 — The safety-valve resolution rate is zero in authored campaign regression seeds and below 0.01% of tokens in randomized 10,000-wave stress runs.
12. Projectile lifetime, range, cleanup, and collision
12.1 Design objective
No projectile may exist indefinitely merely because the world has no wall. Projectile lifecycle must be deterministic, data-driven, legible, and bounded independently of rendering visibility.
Every gameplay projectile MUST have:
- creation tick;
- age or expiration tick;
- previous and current position;
- velocity;
- maximum travel distance;
- accumulated travel distance;
- collision radius;
- team and collision mask;
- owner and source ability identifiers;
- damage payload;
- finite pierce, bounce, or target-transition counters;
- proc generation/depth;
- cleanup policy;
- optional visible-exit policy;
- encounter or boss-field membership where applicable.
A projectile is retired at the earliest applicable condition, not only when it leaves the screen.
12.2 Baseline player projectile rules
Primary projectile
Initial targets:
- speed: 14.84 WU/s;
- radius: 0.0625 WU;
- lifetime: 1.55 s;
- maximum range: 22.5 WU;
- ordinary pierce: 0;
- visible persistence: permitted up to 1.5 WU outside the logical frustum;
- collision: swept segment against candidate circles;
- retirement: impact, range, lifetime, active-region guard, transition cleanup.
At the reference view, this allows a shot to cross most of the screen and continue briefly beyond it, but it cannot circle the active world forever.
Scatter projectile
Initial targets:
- speed: randomized 13.28–16.41 WU/s;
- lifetime: randomized or fixed in the 0.70–0.85 s band;
- maximum range: 10.5–13.0 WU;
- pellet count: six baseline;
- ordinary pierce: 0;
- damage falloff: optional, initially disabled in favor of finite lifetime and spread;
- retirement: impact, range, lifetime, active-region guard, transition cleanup.
Pellets MUST not survive long enough to become an unseen rear hazard after the player has moved away.
12.3 Hostile projectile rules
Ordinary hostile projectiles are encounter-local hazards, not persistent world objects.
Initial rules:
- standard shooter bullet lifetime: 2.5–3.25 s;
- maximum range selected so a visible shot can traverse the view plus a small margin;
- hostile projectile is retired once it has remained outside the expanded visible region for more than 0.15 s;
- an ordinary hostile projectile that exits the expanded visible region MUST NOT later re-enter;
- no ordinary hostile projectile may spawn outside the logical view;
- owner death does not automatically delete an already visible ordinary projectile unless the archetype specifies it;
- all hostile projectiles are cleared on wave transition, perk-draft entry, boss-lockfield creation, checkpoint load, and run termination.
Returning, orbiting, homing, or delayed off-screen projectiles are prohibited in the baseline. A later authored exception MUST provide a persistent edge indicator and a dedicated lifecycle policy.
Boss projectiles may use longer lifetimes because the lockfield bounds the encounter. They MUST still have explicit expiration, boundary behavior, and per-pattern budgets.
12.4 Distance versus lifetime
Both constraints are required:
- lifetime bounds memory and behavior even for slow, stationary, or reflected projectiles;
- range bounds travel even when time scale, velocity modifiers, or pauses alter apparent duration.
Distance accumulation uses actual integrated displacement. It MUST remain deterministic under fixed-step simulation. Teleporting a projectile, rebasing the local origin, or changing coordinate chunks MUST NOT incorrectly add to travel distance.
12.5 Continuous collision rule
For each tick, a projectile traces from its previous to current position. Against a circular target, the query is equivalent to intersecting a segment with a circle expanded by projectile radius. The earliest valid hit time in [0,1] is resolved first.
Processing requirements:
- query broadphase cells overlapped by the swept AABB;
- reject team, mask, owner-immunity, and already-hit identifiers;
- compute time of impact against candidate circles;
- sort or select the earliest hit deterministically;
- emit one DamageEvent;
- decrement pierce or transition count;
- continue the residual segment only if the projectile remains alive;
- bound the number of impacts per projectile per tick.
Initial maximum impacts per projectile per tick: eight. Exceeding it retires the projectile and increments a diagnostic counter; authored definitions must be tuned so this does not occur in normal play.
The collision system MUST NOT directly grant score, destroy enemies, spawn drops, or invoke perk behavior. It only generates damage/contact events.
12.6 Spatial broadphase
Use a uniform 2D grid local to the active camera region.
Initial targets:
- cell size: 1.0–1.5 WU;
- separate or filtered lists for damageable actors, projectiles, pickups, and optional fields;
- rebuilt or incrementally updated each fixed tick;
- deterministic candidate ordering by stable entity ID where outcomes could differ;
- no dynamic allocation per cell in the hot path after capacity warm-up;
- automatic oversized-object fallback for boss bodies and large fields.
The grid's logical origin participates in world rebasing. Cell coordinates are local and small.
12.7 Piercing
A piercing projectile stores:
- remaining pierce count;
- a small recent-hit set or per-target last-hit stamp;
- damage multiplier after each hit if configured;
- maximum impacts per tick and total lifetime.
The initial Piercing Rounds perk grants up to three additional target penetrations. The same target cannot be hit twice by one pass. Damage may begin at 100% and fall to 85%, 70%, and 55% on subsequent hits; exact values are balance parameters.
Piercing MUST remain finite. “Infinite pierce until TTL” is not permitted in the baseline because dense packs can create explosive proc and event counts.
12.8 Ricochet redesign for a boundless world
The Godot reference's wall-bounce premise does not transfer to unrestricted standard waves. The corresponding perk becomes Vector Ricochet:
- after the first valid hit, search for the nearest unhit hostile target within 4.5 WU;
- require a clear gameplay-space line segment if obstacle support is later added;
- redirect once toward the selected target;
- apply a configurable damage multiplier, initial target 70%;
- consume the ricochet count whether or not the new target survives;
- never select an off-screen concealed enemy;
- never chain more than the configured count;
- preserve proc generation so ricochet hits cannot recursively create unbounded ricochets.
During boss lockfields, an authored projectile MAY bounce from the lockfield edge, but that is a boss/weapon rule and not required for the perk.
12.9 Explosion and chain rules
Explosions are transient area queries, not long-lived projectile entities unless a visible expanding wave is specifically authored.
The baseline Chain Burst behavior:
- trigger: eligible enemy death caused by player-aligned damage;
- radius: 1.72 WU initial target;
- primary chain damage: 3.5 initial target;
- generation 0 death creates generation 1 burst;
- generation 1 kills may create generation 2 bursts at 65% radius or damage;
- generation 2 cannot create another chain burst;
- each death can trigger at most one chain burst instance;
- boss and summoned interlude immunity may be configured separately;
- all resulting damage uses ordinary DamageEvent and DeathEvent resolution.
The proc-generation limit MUST be a general typed safeguard, not a one-off boolean.
12.10 Pooling and ownership
Gameplay projectile storage SHOULD use dense ECS/component pools or a dedicated SoA pool with generational entity handles. It MUST NOT allocate one heap object per bullet.
Required behavior:
- reserve normal and stress capacities at run start;
- recycle slots through a free list or ECS archetype reuse;
- clear all mutable state when reusing a slot;
- validate owner handles generationally;
- distinguish owner invalidation from projectile invalidation;
- retain source-team attribution after owner death for score/damage rules;
- separate gameplay projectiles from cosmetic tracers and particles.
A projectile may reference immutable definition data by typed ID, but MUST NOT retain raw pointers that become invalid after hot reload.
12.11 Projectile budgets and degradation
Initial normal-play hard caps:
- player gameplay projectiles: 1,500;
- hostile gameplay projectiles: 1,500;
- combined gameplay projectiles: 2,500 preferred budget, 3,000 absolute campaign guard;
- boss-pattern-specific cap: configured per boss within the absolute guard;
- cosmetic trail segments and sparks: separate VFX budget.
When a gameplay projectile cap would be exceeded:
- reject nonessential duplicate cosmetic fire first;
- coalesce or suppress decorative sub-projectiles explicitly marked scalable;
- defer an enemy shot for a bounded interval if permitted by its weapon definition;
- never silently delete an already visible lethal projectile to recover capacity;
- never reject the player's baseline primary shot without a visible overload fault in development builds;
- increment diagnostics and fail the associated stress acceptance threshold.
Production balance and boss patterns must remain below the cap. Capacity degradation is an emergency guard, not ordinary pacing.
12.12 Cleanup boundaries
All projectiles are cleared or transitioned according to an explicit policy on:
- standard-wave completion;
- perk draft entry;
- boss intro;
- boss phase transition only when the pattern specifies a purge;
- boss defeat;
- player death;
- checkpoint load;
- restart or return to front end;
- hot-reload of incompatible definitions in development.
A purge may produce a cosmetic dissolve or score-neutral shard effect, but MUST not trigger hit, kill, lifesteal, or chain behavior.
12.13 Projectile acceptance criteria
PROJ-AC-01 — Every gameplay projectile definition has nonzero finite lifetime and/or expiration tick plus a finite maximum range; validation rejects unbounded definitions.
PROJ-AC-02 — A projectile fired at maximum supported speed cannot tunnel through the smallest target at 60 Hz in deterministic regression tests.
PROJ-AC-03 — Ordinary hostile projectiles cannot be created off-screen or re-enter after leaving the expanded visible region.
PROJ-AC-04 — Origin rebasing does not change projectile travel distance, remaining lifetime, collision trajectory, or visual interpolation.
PROJ-AC-05 — Perk combinations cannot exceed configured pierce, ricochet, proc-depth, or per-tick impact bounds.
PROJ-AC-06 — A 60-minute firing soak returns projectile counts to zero after cleanup and exhibits no monotonic memory growth.
PROJ-AC-07 — Gameplay projectiles, cosmetic trails, and impact VFX have independently measurable budgets and cannot consume one another's storage implicitly.
PROJ-AC-08 — Cap pressure is visible in diagnostics and never causes silent deletion of a visible lethal hazard.
13. Wave progression and encounter pacing
13.1 Campaign framework
The implementation preserves the Godot reference's principal progression framework:
- standard waves 1–9;
- Core boss at wave 10;
- standard waves 11–19;
- Omega boss at wave 20;
- standard waves 21–29;
- Apocalypse boss at wave 30;
- final Shadow encounter at wave 31;
- perk decisions at waves 5, 10, 15, 20, and 25;
- a short intermission between resolved encounters.
The campaign is divided into three acts plus a final duel:
| Act | Waves | Purpose |
| I — Acquisition | 1–10 | Teach roles, establish movement and first build direction |
| II — Combination | 11–20 | Combine roles, introduce elites and stronger cross-angle pressure |
| III — Mastery | 21–30 | Demand build use, lane reading, and high-density control |
| Finale | 31 | Mirror-like mobility and weapon duel against Shadow |
A successful first clear should target 30–45 minutes, with standard waves generally taking 35–75 seconds and bosses 2–5 minutes. Exact duration is a validation metric, not achieved by padding enemy counts.
13.2 Wave state machine
Idle
-> WaveIntro
-> SpawningAndCombat
-> DrainCommittedThreat
-> WaveResolved
-> RewardOrDraft
-> Intermission
-> NextWave
WaveIntro -> BossIntro -> BossCombat -> BossResolved -> RewardOrDraft
Any combat state -> PlayerDefeat -> Results / CheckpointRestart
WaveIntro
Duration target: 0.8–1.5 seconds.
Displays the wave number and, where applicable, a concise modifier or role introduction. It does not pause player movement unless a boss lockfield is being formed.
SpawningAndCombat
The director admits tokens according to the wave's cadence curve, active-threat cap, and authored events.
DrainCommittedThreat
Begins once the final pending token has entered or been reserved. The HUD switches from a spawn-progress presentation to remaining committed threat. No new ordinary tokens are created.
WaveResolved
Requires complete token resolution and deferred event drain. Hostile projectiles are purged. Remaining pickups follow the transition rules in Section 13.7.
RewardOrDraft
Ordinary waves may grant only score and checkpoint progression. Draft milestones present the specified perk choice. Boss waves can combine score, checkpoint update, and perk choice.
Intermission
Initial target: 3.0 seconds, matching the reference rhythm. The player may move and collect converging pickups. The countdown MAY be skipped after mandatory transition work completes. No enemy can attack.
13.3 Threat commitment instead of raw enemy count
The Godot formula 10 + wave * 5 is replaced by authored threat budgets. This avoids turning every later wave into a simple density increase and lets role combinations carry difficulty.
A wave definition includes:
- total threat budget;
- active threat cap;
- active entity cap;
- cadence keyframes or segments;
- allowed pack definitions and weights;
- role floors and ceilings;
- elite budget;
- surge events;
- cross-angle events;
- pacing release windows;
- expected duration band;
- checkpoint and draft behavior;
- deterministic seed salt.
Threat budget commits at wave start. The director may change admission cadence within the authored envelope, but it MUST not silently reduce total committed threat in response to low player health.
13.4 Pacing curve
Each standard wave uses a small dramatic curve:
- Establish — one readable pack or introduced role;
- Build — rising active threat and angular variety;
- Crest — one surge, cross-angle composition, or elite pressure event;
- Release — slower admission or a brief gap that lets the player reposition;
- Drain — final committed tokens enter; no new surprise escalation.
The pacing director MAY use current nearby threat, recent damage, and time-since-contact to decide exactly when within a legal timing window to admit the next pack. This is pacing adaptation, not hidden difficulty scaling. It MAY:
- advance a pack when the field is empty;
- delay a pack briefly while active threat exceeds the cap;
- select among equivalent authored sectors;
- choose an allowed pack variant of equal threat cost.
It MUST NOT:
- remove committed tokens because the player is hurt;
- increase enemy damage because the player is performing well;
- spawn inside safety margins;
- violate a role's telegraph floor;
- extend a wave indefinitely to chase a target duration.
13.5 Proposed 31-wave content map
The following is an implementation baseline. Budgets are relative tuning values, not final enemy counts.
| Wave | Budget | Active threat cap | Principal content and pacing purpose |
| 1 | 18 | 10 | Runners only; calibrate movement, aim, primary fire, and centered-camera motion |
| 2 | 24 | 12 | Introduce shooters singly behind runners; first visible projectile lanes |
| 3 | 30 | 14 | Introduce splitters; teach descendant liability and crowd control |
| 4 | 36 | 16 | Introduce chargers with generous wind-up; one small side arrival |
| 5 | 44 | 18 | First full mixed composition; mild crest; first perk draft after resolution |
| 6 | 48 | 20 | First announced directional surge; mostly runners/splitters |
| 7 | 54 | 21 | Introduce tank as a spatial anchor; shooters use lateral lanes |
| 8 | 60 | 22 | First cross-angle composition; one low-tier elite candidate |
| 9 | 68 | 24 | Core rehearsal: radial spacing pressure created by mixed arrivals; pre-boss release |
| 10 | Boss | N/A | Core lockfield encounter; three selections from the Stage 10 pool afterward |
| 11 | 62 | 22 | Post-boss reset with denser familiar roles; validate new build without immediate novelty |
| 12 | 68 | 24 | Alternating side packs; longer but lower-amplitude pressure curve |
| 13 | 74 | 25 | Shooter protection formation with tanks/splitters; target prioritization test |
| 14 | 80 | 26 | Introduce kamikaze in low counts with extended telegraph |
| 15 | 86 | 27 | Mixed role build check and one elite; Stage 15 draft after resolution |
| 16 | 92 | 28 | Split cascade wave with reserved descendant capacity and burst-control demands |
| 17 | 98 | 29 | Two separated surges with release window between them |
| 18 | 106 | 30 | Elite matrix: two different modifiers, never stacked on first presentation |
| 19 | 116 | 32 | Omega rehearsal: cross-angle ranged fans, heavy anchors, clear pre-boss drain |
| 20 | Boss | N/A | Omega lockfield encounter; Stage 20 draft afterward |
| 21 | 110 | 30 | Act III compression: familiar roles at faster legal cadence, no new mechanic |
| 22 | 118 | 31 | Champion pack and escort composition; focus-fire decision |
| 23 | 126 | 32 | Angle denial through shooters plus chargers; requires heading changes |
| 24 | 134 | 33 | Projectile-lane wave with strict hostile-bullet cap and visible safe movement seams |
| 25 | 142 | 34 | Convergence wave testing the near-complete build; Stage 25 draft afterward |
| 26 | 150 | 35 | Rush wave: melee-heavy surges and kamikaze punctuation |
| 27 | 160 | 36 | Endurance curve with two crests and a meaningful mid-wave release |
| 28 | 170 | 38 | Apocalypse rehearsal using wide angular arrivals and safe-wedge reading |
| 29 | 185 | 40 | Final standard gauntlet; all roles, bounded elites, no unreadable simultaneous introductions |
| 30 | Boss | N/A | Apocalypse lockfield encounter; no new perk afterward |
| 31 | Boss | N/A | Shadow finale with mirror weapons, mobility, interludes, and final phase |
Budget interpretation
A budget of 18 does not mean 18 entities. For example, it may be 12 runners plus 3 shooters, depending on costs and pack definitions. The director validates both threat and entity caps.
The active threat cap should grow more slowly than the total budget. Later waves become longer and more varied without putting the entire budget on screen at once.
13.6 Milestone and boss ordering
The recommended ordering is:
- wave 5 resolves → choose one Stage 5 perk → checkpoint;
- wave 10 boss resolves → choose three distinct Stage 10 perks from six → checkpoint;
- wave 15 resolves → choose one Stage 15 perk → checkpoint;
- wave 20 boss resolves → choose one Stage 20 perk → checkpoint;
- wave 25 resolves → choose one Stage 25 perk → checkpoint;
- wave 30 resolves → checkpoint for Shadow finale;
- wave 31 resolves → run result.
A checkpoint captures the state at the start of the next encounter, never in the middle of unresolved projectiles or encounter tokens.
13.7 Pickups across a moving world
Pickup handling must not punish forward travel by leaving rewards permanently behind.
Rules:
- pickups have finite lifetime, initial target 12–18 seconds;
- within the magnet radius they accelerate toward the player;
- after wave resolution, all eligible pickups enter transition convergence and fly to the player for up to 1.25 seconds;
- health or armor that cannot be consumed may convert to a small score value or expire, according to definition;
- pickups beyond the soft relevance radius are either converged camera-relatively or converted by policy; they do not remain as persistent world objects;
- pickup conversion never triggers combat kill effects;
- player death freezes reward resolution before the result screen.
The Stage 5 Magnet perk increases acquisition radius and attraction speed; it does not merely compensate for a broken base pickup system.
13.8 Checkpoint semantics
Checkpoints are wave-boundary snapshots containing:
- schema version;
- campaign seed;
- next wave index;
- player health and armor according to checkpoint-heal policy;
- selected perks and modifier stacks;
- weapon state that persists between waves;
- score and run statistics;
- deterministic RNG stream states or reconstructible salts;
- difficulty profile;
- content-definition hash or compatibility marker.
They do not contain:
- live enemies;
- projectiles;
- VFX;
- active pickups;
- partial boss phases;
- camera shake;
- transient UI state.
Loading reconstructs a clean start-of-wave state. The interface and documentation MUST call this a checkpoint, not imply arbitrary save-anywhere support.
13.9 Wave failure and stall handling
A wave stall detector records:
- time since last token defeat;
- time since any enemy was visible;
- pending and in-play token counts;
- recycle count;
- nearest active threat distance;
- spawn placement failures.
Initial thresholds:
- if no enemy is visible and tokens remain for 2.0 seconds, director accelerates a legal spawn/recycle attempt;
- if no valid spawn occurs for 5.0 seconds, placement expands its candidate attempts and emits diagnostics;
- if one token remains irrelevant beyond its recycle limits, use the safety resolution described in Section 11.5;
- if state remains inconsistent for 10.0 seconds in development, pause with a diagnostic overlay and dump the run state;
- production builds recover safely and record the fault.
No ordinary wave should be failed by a hidden timer. Timed challenge modes are separate future content.
13.10 Wave acceptance criteria
WAVE-AC-01 — Campaign data contains exactly 31 ordered encounter definitions with bosses at 10, 20, 30, and 31 and perk milestones at 5, 10, 15, 20, and 25.
WAVE-AC-02 — Standard waves complete only after all encounter tokens and deferred gameplay events resolve; rendering culls and pool destruction cannot advance progress.
WAVE-AC-03 — The director never reduces total committed threat based on player health or recent damage.
WAVE-AC-04 — Every standard wave has an authored establish/build/crest/release/drain pacing shape or an explicit documented exception.
WAVE-AC-05 — Across representative successful builds, median standard-wave duration is 35–75 seconds and a full clear is within the target campaign band without idle padding.
WAVE-AC-06 — No campaign regression seed stalls for more than 2 seconds without visible threat while unresolved tokens exist, except during an authored telegraph or release window.
WAVE-AC-07 — Transition convergence resolves or converts all eligible pickups before the next combat state.
WAVE-AC-08 — Checkpoint load produces a clean deterministic start of the next wave and never restores partial projectiles, VFX, enemies, or boss patterns.
14. Perk and modifier system
14.1 Design goals
Perks are the principal source of build identity. They SHOULD visibly alter how the player moves, fires, survives, or converts kills, rather than serving primarily as hidden percentage increases.
The system must support the reference progression while correcting prototype inconsistencies:
- every description matches implemented behavior;
- all damage paths participate in one event pipeline;
- recursive effects are bounded;
- perks are data-driven within a compact typed effect vocabulary;
- stacking and incompatibilities are explicit;
- perk logic does not become a universal scripting language.
A target distribution is approximately:
- 65–75% behavioral or event-driven modifiers;
- 25–35% numerical/statistical modifiers.
14.2 Perk definition model
struct PerkDefinition {
PerkId id;
LocalizedTextId name;
LocalizedTextId description;
PerkStage stage;
Rarity rarity;
SmallVector<StatModifier, 8> stat_modifiers;
SmallVector<TriggeredEffectDefinition, 8> effects;
SmallVector<PerkId, 4> prerequisites;
SmallVector<PerkId, 4> exclusions;
uint8_t max_stacks;
PresentationId card_presentation;
};
Supported initial stat operations:
- additive flat;
- additive percentage;
- multiplicative final;
- clamped minimum/maximum;
- override only for explicitly exclusive behavior.
Supported initial triggers:
- on primary fire;
- on secondary fire;
- on dash start/path/end;
- on projectile hit;
- on eligible kill;
- on pickup collected;
- on armor broken;
- on health threshold crossed;
- periodic while active;
- on lethal damage before death.
Supported initial effects:
- spawn projectile pattern;
- apply damage event;
- apply area damage;
- add/remove armor or health;
- modify cooldown;
- grant finite pierce or retarget count;
- apply status field;
- spawn/update companion drone;
- clear hostile projectiles under a defined policy;
- revive once;
- emit VFX/audio cue.
All triggered events carry ProcContext { source_perk, generation, root_event_id } and respect maximum generation and per-root-event limits.
14.3 Stage 5 pool: first directional identity
The player chooses one of three.
Magnet Field
- increases pickup acquisition radius from the base value to an initial 4.06 WU;
- increases attraction speed to approximately 5.31 WU/s with acceleration smoothing;
- visually adds a faint cyan orbit/field pulse only when a pickup is affected;
- does not attract enemies or hostile projectiles.
Dash Ram
- dash sweep emits contact damage through the standard damage path;
- each enemy may be hit once per dash;
- applies bounded knockback to ordinary enemies;
- boss damage is reduced by a configured coefficient;
- no reward is granted until the resulting DeathEvent resolves normally;
- dash remains invulnerable for its ordinary duration.
Chain Burst
- eligible enemy deaths create the bounded explosion specified in Section 12.9;
- generation and duplicate-trigger rules are visible in data validation;
- explosion deaths grant normal rewards once and can trigger only allowed follow-up generations.
14.4 Stage 10 pool: choose three of six
The Stage 10 boss reward presents six cards and allows three distinct selections. This is the largest build-defining moment.
Aegis Plating
- increases maximum armor;
- grants a fixed armor amount immediately;
- optionally grants a small armor pickup bonus;
- does not regenerate armor passively unless configured as a separate effect.
Overcharged Ammunition
- increases primary and scatter damage by a multiplicative factor;
- slightly increases hit-flash or projectile-core intensity;
- does not increase explosion or contact damage unless the modifier explicitly targets those channels.
Scatter Pack
- adds pellets to the secondary weapon;
- may increase spread or cooldown slightly to preserve role;
- pellet count, spread, and cooldown are defined together as one behavior package;
- card preview MUST show the resulting pattern.
Vampire Circuit
- restores bounded health on eligible kills;
- uses an internal per-second and per-event cap;
- mini-splitters or summons may grant reduced or zero healing;
- boss phase objects cannot be farmed for healing unless explicitly intended.
Vector Drive
- increases maximum movement speed modestly;
- recalculates spawn lead-distance constraints automatically;
- does not change dash distance unless a separate dash multiplier is included;
- camera remains exact-centered and does not add damping to disguise higher speed.
Rapid Cycling
- reduces primary fire interval through a clamped multiplicative modifier;
- may modestly increase heat/trail density presentation;
- cannot reduce interval below the global projectile-budget-safe floor.
14.5 Stage 15 pool: advanced movement and penetration
The player chooses one of three.
Atomic Dash
- emits a radial projectile or energy-spoke pattern at dash end;
- initial count: 12;
- projectiles inherit finite lifetime/range and a specific proc generation;
- cannot recursively trigger another Atomic Dash;
- dash-end VFX clearly distinguishes it from Chain Burst.
Piercing Rounds
- grants the finite penetration behavior specified in Section 12.7;
- applies to primary projectiles by default and to scatter only if the definition explicitly says so;
- card preview depicts sequential penetration rather than wall bounce.
Anti-Matter Chassis
- grants substantial maximum armor and immediate armor;
- reduces acceleration and/or maximum speed modestly;
- increases visual body outline/thickness;
- may increase dash collision mass without changing invulnerability;
- the trade-off MUST be stated numerically on the card.
14.6 Stage 20 pool: trajectory and space control
The player chooses one of three.
Vector Ricochet
- implements the one-time nearest-target retarget described in Section 12.8;
- cannot target concealed, dead, already-hit, or non-hostile entities;
- emits a clear angular spark and short connection line;
- has bounded target search radius and count.
Twin Barrel
- primary fire emits two parallel or slightly diverging projectiles;
- each projectile has a configured damage coefficient so total damage does not automatically double without cost;
- initial target: two projectiles at 70–80% base damage each;
- muzzle offsets are mirrored and stable relative to aim;
- fire-rate and projectile caps are validated against Rapid Cycling.
Stasis Field
- creates or maintains a player-centered field with initial radius 2.5 WU;
- slows eligible enemy movement and hostile projectiles by separate configured multipliers;
- does not change simulation tick rate;
- bosses have reduced or phase-specific susceptibility;
- visual boundary is faint and does not obscure bullets;
- all speed changes are modifiers applied in canonical movement/projectile systems.
14.7 Stage 25 pool: capstone utility
The player chooses one of three.
Orbital Drone
The implementation MUST match its description:
- orbits at approximately 0.86 WU;
- intercepts hostile projectiles inside a small collision/intercept radius with a cooldown or energy budget;
- acquires the nearest visible hostile in range and fires a low-rate projectile or beam;
- obeys target filters and projectile budgets;
- cannot attack concealed enemies;
- persists between waves but is hidden/idle during drafts and checkpoint transitions;
- uses ordinary damage events and grants player-aligned kill credit.
Hyper Scatter
- substantially increases secondary pellet count and/or creates a second delayed fan;
- balances with cooldown, spread, or damage coefficient;
- preserves a readable burst rather than filling the entire view indiscriminately;
- hard-validates maximum pellet count under Twin Barrel/Rapid Cycling combinations.
Phoenix Protocol
- one charge per run or checkpoint segment, as specified by campaign policy;
- intercepts lethal damage before player death;
- restores a configured health fraction;
- grants approximately 1.2 seconds of invulnerability;
- clears hostile projectiles through a non-damaging purge;
- emits unmistakable audio/VFX and HUD state change;
- cannot trigger more than once from the same root damage event;
- is consumed before checkpoint serialization if activated.
14.8 Numerical and behavioral limits
Global initial safeguards:
- primary fire interval floor: 0.055 s unless stress profiling explicitly supports lower;
- scatter pellet hard cap per trigger: 24;
- projectile-spawn effects per root event: 64;
- area-damage effects per root event: 32;
- proc generation depth: 2 by default, 3 only for audited content;
- healing per second from kill effects: configurable cap, initial 12% maximum health/s;
- armor and health maximums have authored upper bounds;
- movement speed perks participate in spawn/camera tests;
- no perk can remove all cooldown from dash or scatter;
- no perk can make the player permanently invulnerable through ordinary stacking.
Validation MUST evaluate known milestone combinations and reject definitions that exceed static bounds. Runtime counters protect against unforeseen data combinations.
14.9 Card presentation
Each card includes:
- icon or simple geometric schematic;
- name;
- one-sentence behavior description;
- exact important numbers and trade-offs;
- affected input/weapon marker;
- current-stack or interaction note where relevant;
- animated preview for trajectory-altering choices when practical.
Descriptions MUST be generated from or validated against definition values to reduce drift. A card may use curated prose, but automated tests compare embedded numeric tokens with data where possible.
14.10 Perk acceptance criteria
PERK-AC-01 — The campaign exposes the correct 3/6/3/3/3 stage pools and three selections at Stage 10.
PERK-AC-02 — Every perk description matches its implemented trigger, affected damage channel, limits, and trade-offs.
PERK-AC-03 — Dash, projectile, explosion, drone, and contact kills all resolve through the same death/reward pipeline.
PERK-AC-04 — Exhaustive authored milestone combinations cannot exceed configured projectile, proc-depth, healing, or invulnerability bounds.
PERK-AC-05 — Chain Burst, Vector Ricochet, piercing, and drone targeting never select concealed or invalid entities.
PERK-AC-06 — Phoenix Protocol consumes exactly one charge, survives neither duplicate damage events nor checkpoint exploits, and performs a non-rewarding projectile purge.
PERK-AC-07 — Orbital Drone both intercepts eligible hostile shots and attacks visible enemies, as represented by its card.
PERK-AC-08 — At least 70% of playtest participants can identify a selected perk's gameplay effect within the next wave without inspecting a statistics screen.
15. Boss encounter framework
15.1 Purpose of the lockfield
Bosses require authored spatial relationships that cannot be guaranteed in unrestricted travel. A boss encounter therefore creates a temporary local arena at the player's current logical position.
The sequence is:
- standard-wave/projectile cleanup completes;
- uncollected eligible pickups converge;
- a boss beacon appears at the camera anchor;
- the camera zooms out over 0.6–1.0 seconds;
- a visible lockfield boundary forms around the encounter anchor;
- player movement is gently clamped inside only after the boundary is readable;
- the boss appears with an intro telegraph;
- combat begins;
- on defeat, hostile projectiles purge, rewards resolve, boundary dissolves, and ordinary boundless travel resumes.
The lockfield anchor is stored in persistent logical coordinates. All boss-local patterns use a small coordinate frame relative to this anchor.
15.2 Lockfield geometry and movement
Initial targets:
- ordinary boss field radius: 8.0 WU;
- Shadow field radius: 9.0 WU if needed for mobility;
- camera view during ordinary bosses: approximately 32 × 18 WU at 16:9;
- boundary thickness: 0.08–0.14 WU presentation only;
- inner warning band: 0.5 WU;
- activation formation time: 0.8 s;
- boundary collision: analytic circle, independent of rendered mesh.
Player movement near the boundary:
- ordinary movement projects the attempted displacement onto the tangent rather than stopping both axes;
- dash uses a swept circle against the field boundary and ends at the valid point with optional tangent slide;
- camera remains centered on the field/player blend defined for the boss, never outside the lockfield;
- boundary collision cannot inflict damage;
- dangerous patterns must not be visually hidden beneath the boundary effect.
The player MUST receive a pre-contact glow and soft audio cue when within the warning band. The boundary is a combat rule, not an invisible clamp.
15.3 Boss camera
Boss camera behavior differs from standard waves only in framing:
- transition from player-centered 25 × 14.0625 WU to the boss field framing;
- target center is a weighted blend of player and boss constrained so the complete boundary remains visible where possible;
- no damping that affects aiming; zoom and center transition use a scripted interpolation before combat or a very small bounded presentation interpolation during it;
- logical cursor-to-world conversion uses the logical camera for that tick;
- screen shake remains a presentation offset only;
- HUD and edge indicators use boss-local visibility.
For radial-pattern bosses, the camera SHOULD frame the whole lockfield. For Shadow, it MAY use a slightly tighter player/boss framing so the duel feels personal, provided boundary and teleport telegraphs remain visible.
15.4 Shared boss rules
Every boss definition includes:
- health and optional armor pools;
- collision radius;
- movement controller;
- phase thresholds;
- pattern scheduler;
- minimum pattern telegraphs;
- projectile budget;
- safe-zone/readability constraints;
- lockfield configuration;
- minion/interlude definitions;
- camera profile;
- music state;
- checkpoint and reward behavior.
Shared requirements:
- patterns are scheduled by data/state machine, not a single random timer chain;
- no pattern starts without its minimum telegraph;
- simultaneous patterns have an authored compatibility matrix;
- projectile density has a measurable cap;
- at least one traversable safe route exists for every non-enrage pattern under baseline movement speed;
- dash may simplify a route but is not required more often than its unmodified cooldown permits;
- all phase transitions are clear in animation, color, audio, or field behavior;
- phase changes may purge bullets only when explicitly authored;
- boss contact, bullets, pulls, slashes, and adds use standard damage events;
- bosses cannot be recycled or culled by ordinary relevance systems.
15.5 Wave 10: Core
Identity
A large geometric reactor that teaches radial pattern reading and field-center awareness.
Initial reference mapping:
- shape: 8-sided core with white inner diamond;
- radius: approximately 0.70 WU;
- health: 350 initial target;
- color family: deep red/crimson with white hot core;
- phases: two.
Movement
Core remains near the field center and may orbit or drift within a 2.0–2.5 WU center zone. It must not pin itself against the boundary.
Phase 1
- radial burst: 8 projectiles, approximately every 1.2 s;
- projectile speed: approximately 4.1 WU/s;
- alternating angular offset between bursts;
- slow center drift;
- optional single aimed shot only after the radial lanes are established.
Phase 2
Begins near 50% health:
- radial burst increases to 12 projectiles;
- cadence approaches 0.8 s;
- projectile speed may increase to approximately 4.8 WU/s;
- periodic three-shot aimed fan with clear pre-aim line;
- never combine fan and radial burst so tightly that all safe exits close without dash.
Teaching objective
Core verifies that the player can read regular angular gaps, move around a center threat, and use the first build selections without requiring advanced role knowledge.
15.6 Wave 20: Omega
Identity
A heavy shielded gravity/control boss that challenges movement commitment and armor management.
Initial reference mapping:
- shape: 12-sided body with inner diamond;
- radius: approximately 0.94 WU;
- health: 750;
- armor: 200;
- color family: violet/indigo with white shield bands;
- phases: two or three depending on tuning.
Core mechanics
- a telegraphed radial pull toward the boss or field center;
- five-shot aimed fans;
- shield/armor break transition;
- optional gravity zones that alter velocity through explicit force modifiers.
Pull behavior
The pull MUST:
- show a field contraction at least 0.6 s before peak force;
- use a bounded acceleration rather than teleporting or directly setting position;
- remain compatible with player input and dash;
- never pull through the boss body or field boundary;
- have a center danger zone and outer recovery zone that are visually distinct;
- cease or weaken during incompatible fan patterns.
Fan behavior
- five projectiles with readable spread;
- aim snapshot occurs at a visible point in the telegraph;
- later phase may fire two fans with a delay rather than one unreadable dense burst;
- safe lateral paths remain available.
Teaching objective
Omega tests whether the player can manage forced movement, select escape angles, and exploit armor-break windows while retaining awareness of the circular field.
15.7 Wave 30: Apocalypse
Identity
The campaign-scale pattern boss: large, imposing, and focused on alternating radial structures rather than raw speed.
Initial reference mapping:
- shape: 16-sided body with layered inner geometry;
- radius: approximately 1.17 WU;
- health: 1,000;
- color family: orange-red, white core, dark shell;
- phases: at least three.
Pattern language
Candidate patterns:
- 12-spoke radial burst with broad gaps;
- 16-spoke radial burst with alternating rotating offset;
- paired concentric rings with one delayed gap alignment;
- safe-wedge sweep telegraphed by dim sectors before firing;
- short add interlude using limited runners or splitters, never while maximal bullet density is active.
Rules:
- rotating patterns have a bounded angular speed compatible with baseline movement;
- ring cadence leaves recovery intervals;
- the arena boundary and boss body do not create unavoidable pinch points;
- phase transitions change pattern grammar, not merely projectile count;
- the final phase may increase cadence but preserves at least one readable safe route.
Teaching objective
Apocalypse is the capstone of radial-pattern mastery and complete-build control before the more character-like Shadow duel.
15.8 Wave 31: Shadow
Identity
Shadow is the most valuable boss concept from the reference: a compact, mobile, player-like opponent that uses rapid fire, a scatter weapon, dashes, teleports, slashes, and minion interludes.
Initial reference mapping:
- shape/body: compact 6-sided or stylized angular figure;
- radius: approximately 0.34 WU;
- health: 600;
- final-phase armor: 135 initial target;
- colors: cyan/magenta duality with white weapon cores;
- preferred distance: approximately 3.4–5.9 WU;
- field radius: 9 WU initial target;
- phases: four primary combat phases plus interludes.
Movement
Shadow strafes around the player within a preferred distance band. It uses acceleration and maximum turn rate rather than instantaneous heading changes. It may dash laterally or across the player's aim, but every dash has a visible start flare.
Rapid fire
- cadence: approximately 0.15 s, later 0.12 s;
- projectile speed: approximately 13.75 WU/s;
- burst length and recovery are explicit; it does not fire forever at full cadence;
- muzzle direction follows an aim snapshot or bounded tracking rate;
- player can cross or dash through predicted lanes.
Scatter attack
- six pellets initially, nine in a later phase;
- cadence: approximately every 3.5 s, later 2.8 s;
- strong pre-fire cone preview;
- short recoil or recovery window creates an attack opportunity;
- pellet lifetime/range remain finite inside the field.
Teleport
- displacement target: approximately 3.9–5.5 WU;
- destination candidate must be valid inside the field and outside player overlap;
- departure and destination glyphs are visible for 0.35–0.5 s;
- Shadow cannot fire during the hidden interval;
- teleport cannot place Shadow directly behind the HUD-obscured edge or on an unresolved hazard cluster;
- destination selection is deterministic from the boss RNG stream.
Slash
- used inside approximately 2.3 WU;
- telegraphed arc appears before the damaging sweep;
- damage uses a swept sector/capsule query, not a frame-perfect point check;
- the visual slash exactly matches the damage volume within tolerance;
- one hit per player per slash;
- recovery creates a punish window.
Interludes
Replace the reference's very frequent 15% thresholds with three authored interludes at approximately 75%, 50%, and 25% health unless playtesting supports another cadence.
During an interlude:
- Shadow becomes untargetable or retreats to a visible field position;
- a bounded pack of minions enters through marked boundary gates;
- ordinary annular spawn logic remains disabled;
- the encounter cannot be dragged away;
- minion tokens resolve before Shadow returns;
- remaining hostile minion bullets are purged at return;
- interludes do not provide exploitable infinite healing or drops.
Final phase
- grants the configured armor layer;
- combines rapid bursts, scatter, and slash through a compatibility schedule;
- reduces downtime modestly;
- does not stack teleport, shotgun, and slash telegraphs simultaneously;
- music and field colors move to the cyan/magenta final state.
Teaching objective
Shadow tests mastery of the player's own movement grammar: aim, strafe, dash timing, burst reading, close-range disengagement, and target reacquisition.
15.9 Boss failure and recovery
On player defeat:
- simulation enters a deterministic defeat freeze after all same-tick lethal interception resolves;
- no further boss damage or reward events occur;
- checkpoint restart reloads the clean start of that boss wave;
- random pattern stream resets to checkpoint state unless a policy explicitly re-rolls the attempt;
- the lockfield reconstructs from logical anchor data;
- no stale projectiles, minions, VFX, or audio voices survive.
A boss may have a hard diagnostic timeout, but not an ordinary player-facing enrage timer in the baseline. Enrage MAY be added later as a difficulty modifier.
15.10 Boss acceptance criteria
BOSS-AC-01 — Bosses occur exactly at waves 10, 20, 30, and 31 and ordinary annular spawning is disabled during their combat states except authored interludes.
BOSS-AC-02 — Lockfield formation is visible before movement constraint activates; the player is never silently clamped.
BOSS-AC-03 — Dash and ordinary movement cannot cross the analytic boundary, jitter against it, or lose tangential movement.
BOSS-AC-04 — Every boss pattern satisfies its telegraph floor and projectile budget and has at least one traversable safe route at baseline movement/dash values.
BOSS-AC-05 — Camera, cursor-world conversion, collision, and projectile trajectories remain aligned throughout boss zoom and center transitions.
BOSS-AC-06 — Core, Omega, Apocalypse, and Shadow each have a mechanically distinct pattern grammar, not only different health and projectile counts.
BOSS-AC-07 — Shadow teleport and slash presentation matches destination and damage geometry within one fixed tick and a defined visual tolerance.
BOSS-AC-08 — Interlude entities are token-accounted, bounded, non-farmable, and completely resolved before Shadow resumes.
BOSS-AC-09 — Checkpoint restart reconstructs the boss encounter without leaked entities, projectiles, audio voices, UI state, or RNG divergence.
16. Difficulty scaling and balance principles
16.1 Difficulty dimensions
Difficulty should increase primarily through decision complexity, then through tempo, and only modestly through raw statistics.
Preferred scaling order:
- introduce a new readable role;
- combine known roles with complementary pressure;
- vary approach geometry;
- add surges, cross-angle timing, and elites;
- increase active threat within readability bounds;
- modestly increase cadence;
- apply bounded health, armor, speed, or damage scaling;
- alter boss phase grammar.
Avoid relying on:
- exponential health inflation;
- invisible enemy speed increases;
- off-screen attacks;
- shrinking telegraphs below human reaction floors;
- projectile density that obscures safe routes;
- arbitrary catch-up teleports;
- hidden adaptive damage changes.
16.2 Statistical scaling
Initial campaign-wide bounds for ordinary enemies:
- health multiplier by Act III: generally no more than 1.5–1.8× Act I baseline for the same unmodified role;
- movement speed multiplier: generally no more than 1.20×, with role-specific safety caps;
- contact/projectile damage multiplier: generally no more than 1.35× on default difficulty;
- shooter cadence multiplier: no faster than telegraph and projectile-budget limits permit;
- elite modifiers carry explicit threat-cost multipliers;
- bosses use authored phase changes rather than a generic global multiplier alone.
Exact curves SHOULD be piecewise by act, not automatically linear per wave. The player should be able to learn a role's timing and retain that knowledge.
16.3 Build-power compensation
Perks materially increase player power. Later waves respond through authored combinations and budgets, not by reading the selected perks and counter-picking them.
The director MAY know aggregate player metrics for diagnostics and optional difficulty profiles, but baseline campaign composition MUST be deterministic from campaign data and seed. It MUST NOT:
- spawn more tanks because the player chose piercing;
- suppress projectiles because the player chose drone;
- counter movement perks with untelegraphed speed;
- alter card offerings to force a specific build.
Balance should ensure multiple viable paths:
- projectile volume;
- penetration/ricochet;
- dash aggression;
- defense/sustain;
- scatter burst;
- companion/space control.
A build need not be equally strong in every wave, but no milestone choice should make a mandatory boss mechanically impossible.
16.4 Anti-kiting versus player freedom
The player earns safety by moving well. The design should not punish motion merely because the map is boundless.
The correct balance target is:
- straight-line retreat works briefly;
- prolonged retreat causes pressure to re-form ahead and laterally through fair spawns;
- turning through gaps, cutting across formations, and using dash creates stronger positional advantage than simply holding one direction;
- stationary play remains possible only with a sufficiently strong build and execution;
- no invisible leash drags the player back during standard waves.
Metrics to record:
- net displacement per wave;
- heading persistence time;
- time with no visible enemies;
- fraction of spawns ahead/lateral/behind;
- average nearest-threat distance;
- recycle count;
- player turn frequency;
- dash direction distribution.
Playtests should compare these metrics with subjective reports of freedom, pressure, and treadmill sensation.
16.5 Readability budget
The game has several independent visual-threat budgets:
- active hostile bodies;
- hostile projectiles;
- simultaneous dangerous telegraphs;
- elite indicators;
- large VFX occlusion;
- screen shake/flash intensity;
- edge indicators.
Wave definitions specify maximum simultaneous dangerous telegraphs, initial target three outside boss encounters. The director may have many ordinary enemies present, but it must not synchronize multiple chargers, kamikazes, surges, and elite bursts into an unreadable instant unless an explicitly tested late-wave composition allows it.
The highest-priority information order is:
- player and lethal collision threats;
- dangerous telegraphs and hostile projectiles;
- enemy bodies and role markers;
- pickups;
- damage numbers and score events;
- decorative particles and trails;
- background detail.
Lower-priority layers must yield opacity, density, or lifetime when the readability budget is stressed.
16.6 Optional difficulty profiles
The first implementation MAY expose three profiles, but default balance comes first.
| Parameter | Accessible | Standard | Expert |
| Player damage taken | 0.75× | 1.0× | 1.15× |
| Telegraph duration | 1.20× | 1.0× | 0.90×, never below floor |
| Encounter budget | 0.85× | 1.0× | 1.12× |
| Elite budget | Reduced | Authored | Increased within caps |
| Checkpoint heal | Higher | Authored | Lower |
| Score multiplier | Lower/neutral | 1.0× | Higher |
Profiles MUST preserve role grammar, spawn fairness, and boss safe routes. Expert difficulty may demand faster execution, not violate core readability rules.
16.7 Balance telemetry
Every run records at least:
- seed, build/version, difficulty, input device;
- selected perks;
- wave start/end times;
- damage dealt by source and channel;
- damage taken by source;
- deaths and near-death events;
- health/armor pickup collection and waste;
- kill counts by role;
- boss phase durations;
- projectile counts and cap peaks;
- spawn placement retries and recycling;
- player speed, displacement, and dash use;
- frame/simulation performance percentiles.
Internal tools SHOULD support filtering results by seed, perk path, wave, and failure cause.
16.8 Balance acceptance criteria
BAL-AC-01 — Every ordinary enemy role retains recognizable timing across acts; no default statistical multiplier bypasses its telegraph or counterplay.
BAL-AC-02 — At least four materially different perk archetypes can complete the campaign in expert internal hands without relying on debug advantages.
BAL-AC-03 — No mandatory boss requires a perk that may not have been offered.
BAL-AC-04 — Standard-difficulty deaths are attributable in replay/telemetry to visible threats in at least 98% of reviewed cases; unexplained/off-screen deaths are release blockers.
BAL-AC-05 — Prolonged straight-line movement does not create more than 2 seconds of unintended zero-pressure time and does not produce visible unfair spawns.
BAL-AC-06 — Lower-priority VFX automatically yield before projectile or telegraph readability is compromised.
BAL-AC-07 — Difficulty profiles modify authored parameters without changing checkpoint semantics, spawn fairness, deterministic ordering, or core role behavior.
17. Visual design and presentation language
17.1 Reference-derived visual identity
The uploaded Godot game establishes a coherent low-asset visual language that should be retained in spirit:
- near-black midnight/navy background;
- a sparse, faint orthogonal grid;
- cyan player body and aim language;
- warm gold player projectiles;
- crimson hostile projectiles;
- saturated shape-coded enemy roles;
- regular polygons with white or high-value inner details;
- rings, square fragments, trails, muzzle flashes, impact pulses, and restrained camera shake;
- minimal technical HUD presentation;
- bosses represented by larger multi-sided cores and an inner white diamond;
- Shadow distinguished by cyan/magenta duality and slash arcs.
The PixelBullet version should look deliberate and polished, not like debug primitives. It achieves that through proportion, motion, layering, material response, and effects rather than expensive content production.
17.2 Rendering mode
Use PixelBullet's existing 3D Vulkan path in a constrained 2.5D presentation:
- orthographic camera;
- gameplay on a horizontal or camera-facing plane;
- thin extruded or flat regular-polygon meshes;
- unlit/emissive primary shading with optional subtle surface response;
- small height separation between grid, actors, projectiles, and effects;
- restrained contact shadow or glow under important bodies;
- no perspective distortion in the baseline gameplay camera.
This approach exercises the engine's normal mesh/material/instance path while preserving the precision and clarity of the 2D reference.
17.3 World layer
Background
Initial target background color: approximately linearized equivalent of Color(0.02, 0.02, 0.05) from the reference, adjusted during HDR/tone-map calibration.
The background MUST remain darker than all gameplay silhouettes and MUST not bloom.
Infinite grid
The grid is procedurally evaluated from logical world coordinates, not represented by streamed geometry tiles.
Initial targets:
- minor spacing: 0.78125 WU, corresponding to 50 reference pixels;
- major line every 8 or 10 minor cells;
- minor alpha near 0.03 at reference exposure;
- major alpha near 0.06–0.08;
- anti-aliased line width stable under camera zoom;
- phase derived from integer chunk plus local position so rebasing does not shift the pattern.
The grid MAY subtly deform or brighten near bosses, pickups, or major effects, but it must not reduce projectile contrast.
Stable ambient markers
An infinite identical grid can feel stationary or treadmill-like. Add sparse deterministic markers generated from hashed logical cells:
- dim coordinate crosses;
- occasional larger grid nodes;
- very faint arcs, brackets, or glyph-like technical marks;
- rare low-profile geometric debris silhouettes;
- no collision or gameplay consequence in the baseline.
Markers MUST:
- be stable for the same logical coordinate and seed;
- enter/leave through normal culling without popping in the visible region;
- use low contrast and no hostile colors;
- occupy a bounded instance budget;
- provide visible parallax/travel reference without implying a destination system.
The initial implementation should not add decorative authored biomes. Visual variation may be tied to campaign acts through palette/exposure shifts and marker motifs rather than streamed map content.
17.4 Player visual
Reference proportions:
- body radius: 0.25 WU;
- circular or high-sided cyan core;
- narrow white/cyan weapon stem aligned to aim;
- optional inner ring indicating armor or dash state;
- faint aim line extending only far enough to aid orientation;
- direction-independent body silhouette so mouse aim is clear.
Required states:
- idle/low-motion pulse;
- movement stretch or trail aligned to velocity, not aim;
- primary recoil;
- scatter recoil with stronger short flash;
- dash compression/elongation and afterimage;
- hit flash and brief invulnerability indication;
- armor-hit versus health-hit distinction;
- Phoenix state if equipped/consumed;
- death collapse/shatter.
The player's exact collision radius MUST be represented consistently. Decorative glow may extend beyond it but should not imply a larger hitbox.
17.5 Enemy role palette and shape grammar
Baseline mapping inferred from the reference:
| Role | Shape | Color family | Motion signature |
| Runner | Triangle | Magenta | Direct, agile pursuit |
| Shooter | Square | Acid/lime green | Approach, hold lane, recoil on fire |
| Charger | Diamond/four-side | Orange | Wind-up compression, committed streak |
| Splitter | Pentagon | Turquoise | Heavy pulse, fracture on death |
| Tank | Hexagon | Violet/purple | Slow, steady anchor |
| Kamikaze | Narrow triangle | Yellow | Accelerating pulse and danger ring |
| Mini-splitter | Small triangle | Cyan | Fast, simple child pursuit |
Color is redundant information. Shape, outline, size, motion, telegraph, and audio together communicate role.
Enemy presentation requirements:
- front/heading cue where behavior needs direction;
- hit flash with no more than a few frames of full-white saturation;
- health/armor indication only for elites, bosses, or damaged heavy enemies when useful;
- elite modifier icon or outline pattern independent of hue;
- death response appropriate to role: shatter, split, implode, or burst;
- concealed/pre-entry state not rendered as an ordinary enemy body;
- arming state visibly distinct but not mistaken for invulnerability unless it is actually invulnerable.
17.6 Projectile visual hierarchy
Player projectiles
- gold/yellow core;
- short bright head with restrained trail;
- scatter pellets slightly smaller or shorter-lived;
- perk modifications visible through doubled lanes, penetration streaks, retarget arcs, or colored edge accents;
- never visually resemble hostile crimson projectiles.
Hostile projectiles
- crimson/red body with high-value center;
- outline or shape remains visible over boss fields;
- dangerous boss variants may differ by ring, speed trail, or core pattern but remain in hostile family;
- motion blur/trail never extends so far that current collision position is ambiguous.
Collision alignment
Visual center, simulated position, and collider MUST agree within a small documented tolerance. Trails are strictly historical and non-colliding.
17.7 Boss visual language
Core, Omega, and Apocalypse scale the regular-polygon grammar:
- 8, 12, and 16 sides respectively;
- layered shell and white inner diamond/core;
- phase changes alter inner rotation, emissive bands, shell segmentation, or orbiting details;
- large effects telegraph from geometry before projectiles appear;
- boundary and boss pattern colors remain separable.
Shadow should appear more character-like without requiring a full humanoid asset:
- compact angular torso/core;
- articulated or implied weapon arms through separate geometric segments;
- cyan/magenta asymmetry;
- readable aim, dash, teleport, and slash poses;
- a silhouette close enough to the player to suggest mirroring, but distinct enough to track instantly.
17.8 VFX taxonomy
VFX are generated from typed presentation events and may be scaled independently from gameplay.
Required categories:
- muzzle flash;
- projectile trail;
- impact spark;
- hit flash;
- damage ring;
- enemy death fragments;
- splitter fracture;
- kamikaze pulse/explosion;
- dash afterimage;
- pickup attract trail;
- perk proc signature;
- surge border telegraph;
- elite telegraph;
- boss phase transition;
- lockfield formation/dissolution;
- player damage and death;
- Phoenix activation.
Each definition includes priority, maximum concurrent count, lifetime, instance cost, reduction policy, and whether it may be culled while visible.
17.9 Camera shake and screen effects
Shake uses a separate presentation transform. It MUST NOT alter:
- logical camera center;
- cursor-to-world conversion;
- spawn visibility tests;
- collision;
- UI anchoring;
- boss boundary checks.
Initial maximum ordinary shake translation: 0.10–0.18 WU equivalent. Boss or Phoenix events may briefly exceed this within an accessibility-adjustable cap.
Screen effects:
- brief low-opacity damage vignette;
- optional chromatic or radial distortion only if it does not shift perceived projectile centers;
- flash intensity and duration sliders;
- no continuous heavy bloom over hostile bullets;
- pause and draft states may desaturate the world, but gameplay hazards are already purged/frozen as specified.
17.10 Draw ordering and depth
Recommended layer order:
- background clear;
- infinite grid and ambient markers;
- low-priority ground decals/fields;
- pickups and non-danger fields;
- ordinary enemies and player shadows/glows;
- actor bodies;
- gameplay projectiles and dangerous telegraphs;
- high-priority impacts/slashes;
- presentation-only particles;
- RmlUi.
Dangerous telegraphs and hostile projectiles MUST not be hidden by opaque particles, pickup glows, or actor decorative layers.
17.11 Rendering implementation
Initial geometry set:
- unit disc or high-sided circle;
- triangle, square, pentagon, hexagon, octagon, dodecagon, hexadecagon;
- quad for beams/trails;
- ring mesh or shader primitive;
- optional arc mesh for slash/telegraph.
Per-instance data may include:
struct ShapeInstanceGpu {
float2 position_camera_relative;
float rotation;
float scale;
uint32_t packed_color;
uint16_t shape_variant;
uint16_t flags;
float pulse;
float hit_flash;
float emissive_scale;
float layer;
};
Use instanced draws grouped by pipeline, shared mesh, and blend/depth mode. [R6] DXC compiles the HLSL shader source to SPIR-V as part of the normal PixelBullet shader pipeline. Shader variants should be bounded; per-instance flags are preferable to large permutation counts when branch cost is small.
17.12 Visual acceptance criteria
VIS-AC-01 — The player, hostile projectile, dangerous telegraph, and every enemy role remain identifiable in color and desaturated capture tests.
VIS-AC-02 — Grid and ambient markers remain phase-stable through at least 10,000 origin rebases and do not visibly jump.
VIS-AC-03 — Visual projectile centers and simulated colliders agree within 0.03 WU or the documented per-definition tolerance at all supported frame rates.
VIS-AC-04 — Lower-priority particles cannot occlude hostile projectiles or dangerous telegraphs beyond the defined readability threshold.
VIS-AC-05 — Standard combat rendering uses bounded shared geometry and instancing rather than one unique mesh/material/draw object per entity. [R6]
VIS-AC-06 — All dangerous boss patterns telegraph through visible geometry before collision becomes active.
VIS-AC-07 — Camera shake and screen effects produce no measurable change to aim conversion, spawn visibility, or collision outcomes.
VIS-AC-08 — Accessibility settings can reduce shake, flashes, bloom, grid contrast, and particle density without changing gameplay state.
18. User interface and feedback requirements
18.1 UI scope
RmlUi owns player-facing interface surfaces:
- in-run HUD;
- perk draft;
- pause/options overlay;
- checkpoint/restart messaging;
- boss bar and phase cues;
- results/run summary;
- minimal run-start configuration if required.
The implementation does not reproduce the Godot project's terminal boot sequence, profile browser, elaborate main menu, portrait sheet, or five-slot manual-save shell.
Developer/debug controls remain in PixelBullet's existing editor/ImGui tooling and are not mixed into the player HUD.
18.2 HUD layout
Reference layout target at 16:9:
Upper left
- health bar and numeric value;
- armor bar beneath health when armor exists;
- Phoenix charge icon when owned;
- compact status icons for persistent defensive effects.
Lower center or lower left
- dash cooldown ring/bar with input glyph;
- scatter cooldown bar with input glyph;
- primary fire normally omits a cooldown indicator unless heat/ammo is added later;
- active drone or field state where relevant.
Upper center
- wave number and act;
- standard-wave committed-threat progress;
- short wave-intro title;
- boss health/armor bar and phase cue during boss encounters.
Upper right
- score;
- elapsed run time;
- optional performance-independent combo/streak only if implemented later.
World edge
- surge approach arc;
- dangerous off-screen elite indicator;
- boss/teleport destination cue where needed;
- no indicator for every ordinary enemy.
The HUD must remain sparse. It communicates current resources, immediate cooldowns, progression, and exceptional off-screen danger—not a comprehensive simulation dashboard.
18.3 Wave-progress representation
Standard waves should show committed threat progress rather than raw “enemies remaining” when packs and split descendants make entity count misleading.
Possible presentation:
- progress bar from total committed threat to defeated/resolved threat;
- numeric remaining threat optional in accessibility/debug mode;
- icon when final tokens have been admitted and the wave is in drain state;
- no progress gain from recycling or culling;
- split descendants remain represented by their parent token liability.
Boss encounters replace this with health/armor and phase presentation.
18.4 Perk draft UI
The draft pauses combat after projectiles and effects are safely transitioned.
Requirements:
- three cards on ordinary milestones;
- six cards at Stage 10 with three selections and clear remaining-picks counter;
- keyboard/gamepad navigation and direct mouse selection;
- no accidental selection on the same input edge that skipped the intermission;
- hover/focus shows expanded numeric detail and known interactions;
- selected card animates into the build strip or summary;
- cards remain readable from 1280×720 through supported high-DPI modes;
- selection emits a command to gameplay; RmlUi does not mutate ECS components directly;
- the gameplay layer validates stage, eligibility, duplicate rules, and checkpoint state before accepting.
A compact build summary is accessible from pause and results, not necessarily always displayed.
18.5 Feedback channels
Every important event uses at least two appropriate channels among visual, audio, animation, UI, and haptics:
| Event | Required feedback |
| Player health hit | body flash + sound; optional vignette/haptic |
| Armor hit/break | distinct shell flash + sound + armor-bar response |
| Dash ready | cooldown completion pulse + subtle cue |
| Scatter ready | bar pulse + optional quiet mechanical cue |
| Dangerous spawn/surge | border telegraph + positional audio |
| Charger commitment | shape compression/line + charge sound |
| Kamikaze danger | increasing pulse + warning tone |
| Eligible kill | shatter/impact + role-appropriate sound |
| Perk proc | restrained signature VFX/audio, subject to coalescing |
| Wave clear | progress resolution + stinger |
| Boss phase | geometry change + stinger + bar marker |
| Phoenix | full signature effect + HUD charge removal |
Repeated high-frequency events must be coalesced so feedback remains informative.
18.6 Off-screen information
The centered design can produce important threats just beyond the view. Indicators are limited to threats that require advance awareness:
- announced directional surge;
- armed elite entering soon;
- boss/Shadow teleport destination if near edge;
- authored returning threat, should one be introduced later.
Indicators show direction and urgency, not exact hidden target position unless the mechanic requires it. Ordinary runners and shooters have no persistent arrows; their spawn rules ensure fair visible entry.
18.7 Accessibility
Required options:
- screen shake: 0–100%;
- flash intensity: low/standard/high or continuous slider;
- bloom/emissive intensity;
- particle density;
- grid visibility/contrast;
- aim-line visibility and length;
- hostile projectile outline thickness;
- color-vision palettes or role-outline enhancement;
- high-contrast telegraphs;
- damage-number toggle;
- audio cue captions for meaningful warnings;
- input rebinding;
- hold/toggle behavior where applicable;
- cursor size and high-contrast cursor;
- UI scale.
Accessibility changes MUST NOT alter deterministic simulation except explicit difficulty settings.
18.8 RmlUi data model
The UI consumes a copy/projection such as:
struct RunHudModel {
float health;
float max_health;
float armor;
float max_armor;
float dash_cooldown_fraction;
float scatter_cooldown_fraction;
uint32_t wave_index;
uint32_t act_index;
float wave_progress;
bool wave_draining;
int64_t score;
double run_time_seconds;
BossHudModel boss;
SmallVector<StatusHudItem, 8> statuses;
SmallVector<EdgeIndicatorModel, 8> edge_indicators;
};
Gameplay publishes a new or incrementally updated model after each simulation tick. The RmlUi integration marks changed variables dirty and lets data binding update documents, consistent with its intended model/view separation. [R7]
UI event listeners create validated commands:
- SelectPerk(PerkId);
- PauseRequested;
- ResumeRequested;
- RestartFromCheckpoint;
- AbandonRun;
- SetAccessibilityOption;
- SetAudioOption.
No RmlUi callback may retain raw ECS component pointers.
18.9 UI acceptance criteria
UI-AC-01 — HUD remains readable and non-overlapping at 16:9, 16:10, 21:9, and 4:3 safe-area test configurations from 1280×720 upward.
UI-AC-02 — Wave progress derives from encounter-token resolution and cannot advance from recycling, culling, or entity-pool reuse.
UI-AC-03 — Stage 10 requires exactly three valid distinct selections before continuation; other stages require one.
UI-AC-04 — A selection input cannot leak from intermission skip into an unintended card choice.
UI-AC-05 — RmlUi reads a presentation model and emits commands; it never directly owns gameplay truth or ECS lifetime. [R7]
UI-AC-06 — Off-screen indicators appear only for configured dangerous/announced events and accurately reflect logical direction under camera shake and rebasing.
UI-AC-07 — Accessibility controls change presentation independently and are serialized separately from run checkpoints.
UI-AC-08 — Mouse, keyboard, and gamepad can complete all required draft, pause, restart, and results interactions.
19. Audio and effects requirements
19.1 Audio direction
The audio identity should match the visual economy:
- synthetic, compact, and highly readable;
- per-role motifs rather than realistic weapon simulation;
- crisp transients for player fire and impacts;
- low-frequency weight reserved for bosses, armor breaks, and major perks;
- restrained ambient/music bed so warnings remain audible;
- no dependency on the Godot project's included music or unverified third-party assets.
All source audio must be original, licensed for the project, or procedurally generated under clear provenance.
19.2 Required cue families
Player
- primary fire variants;
- scatter fire;
- dash start/travel/end;
- armor hit/break;
- health hit;
- pickup health/armor/score;
- cooldown ready cues, subtle and optional;
- death;
- Phoenix activation;
- perk-specific signatures.
Enemies
- role entry/arming where dangerous;
- shooter fire;
- charger wind-up/commit/impact;
- splitter fracture;
- kamikaze pulse/detonation;
- tank heavy movement or hit weight, used sparingly;
- elite modifier warnings;
- ordinary and heavy death layers.
Encounter
- directional surge cue with stereo direction;
- wave intro/clear;
- perk draft open/selection;
- boss lockfield formation;
- boss intro and phase transitions;
- boss defeat;
- checkpoint confirmed;
- run victory/defeat.
19.3 Music structure
A minimal implementation may use:
- one base combat track with intensity stems;
- one boss stem/set for Core/Omega/Apocalypse;
- one distinct Shadow cue;
- short transition stingers.
Preferred later structure:
- Act I, II, and III intensity variants;
- build/crest/release stem control driven by encounter phase;
- boss-specific identity layers;
- music transitions quantized or crossfaded without blocking simulation.
Music is presentation-only. It follows run state but cannot determine gameplay timing.
19.4 miniaudio resource policy
Use miniaudio's resource-management facilities for shared loading and appropriate in-memory versus streaming behavior. [R8]
Policy:
- high-frequency SFX decoded into memory;
- music streamed;
- large or infrequent assets may use asynchronous decode/preload;
- procedural synth cues generated once at startup/content load or baked into assets, not allocated and synthesized for every shot;
- one immutable audio definition may be played by many voices;
- bus-level gain for master, music, SFX, warnings, and UI;
- device changes handled without losing gameplay state.
19.5 Voice prioritization and coalescing
Initial simultaneous one-shot voice budget: 32, excluding music streams. The final number is platform-profiled.
Priority order:
- player damage/death and Phoenix;
- boss telegraphs and dangerous role warnings;
- nearby hostile shots/impacts;
- player weapons;
- wave/draft UI;
- ordinary enemy deaths;
- low-priority particles/debris.
Coalescing rules:
- multiple ordinary deaths in one short window become one layered cluster sound plus limited accents;
- rapid primary fire uses a voice pool and controlled retrigger/pitch variation;
- repeated Chain Burst events use rate-limited layers;
- sounds below audibility or beyond the local audio radius may be culled before voice allocation;
- no warning cue may be dropped because decorative deaths consumed all voices.
19.6 Spatialization
Use camera-relative stereo panning and distance attenuation in the gameplay plane.
Requirements:
- player weapon cues remain centered with slight muzzle offset only if useful;
- off-screen surge and dangerous-entry warnings indicate direction;
- ordinary off-screen concealed enemies emit no combat sound that implies visible threat;
- boss field cues use boss-local position but remain audible across the field;
- origin rebasing produces no source jumps because audio positions are rebuilt from camera-relative transforms;
- extreme pan does not make a critical warning inaudible in one ear; critical cues retain a center component.
Full HRTF is not required for the baseline.
19.7 Audio captions
Captions cover meaningful non-speech cues, not every shot:
- [Surge approaching from left];
- [Charger winding up] when off-screen/edge-relevant;
- [Kamikaze alarm];
- [Boss field forming];
- [Phoenix activated];
- [Armor broken].
Captions include directional labels generated from logical camera space and remain correct under shake.
19.8 Audio acceptance criteria
AUD-AC-01 — High-frequency fire and impact paths perform no per-event heap allocation or PCM synthesis after warm-up.
AUD-AC-02 — Music streams while repeated SFX use shared in-memory resources or cached procedural buffers through miniaudio. [R8]
AUD-AC-03 — Voice saturation cannot suppress player damage, dangerous telegraphs, boss warnings, or Phoenix cues.
AUD-AC-04 — Origin rebasing and camera shake cause no audible pan discontinuity or source teleport.
AUD-AC-05 — Surge and dangerous off-screen cues communicate the correct logical direction in stereo and captions.
AUD-AC-06 — All shipped audio has documented provenance and no Godot-reference asset is copied without explicit compatible permission.
AUD-AC-07 — Master, music, SFX, warning, and UI gains persist independently from run checkpoints.
20. Technical architecture and system responsibilities
20.1 Architectural principle
Gameplay truth lives in a fixed-step, data-driven ECS simulation. Rendering, RmlUi, audio, and particles consume immutable or transient presentation outputs. They do not participate in combat authority.
The implementation should be a product-owned PixelBullet surface using reusable application, asset, test, and editor patterns. Its interactive executable and headless adapter are Arena-owned composition surfaces; neither is the generic tools/scene_runner, which remains an authored-scene tool and editor companion. The product should not become a second engine hidden inside one monolithic game script.
20.2 Runtime state boundaries
Recommended conceptual top-level ownership:
BoundlessVectorArenaApp
RunSession
FixedStepSimulation
ECS World
RunStateMachine
Deterministic RNG streams
Encounter/Boss state
WorldOrigin state
PresentationBridge
Render snapshots
VFX events
Audio events
HUD/draft model
Persistence
Checkpoint codec
Run result/statistics
Diagnostics
Counters, traces, seed/replay capture
The labels above are illustrative implementation direction, not existing or pre-approved C++ type names. A product-owned RunSession concept owns one campaign attempt. Returning to the front end destroys the session and all transient state.
20.3 Core systems
The system names in this section describe required responsibility boundaries. Phase 0 may select different concrete types, files, or Bazel targets while preserving those boundaries and the acceptance criteria.
RunStateMachineSystem
- authoritative run phase;
- validates legal transitions;
- starts/ends waves and boss states;
- coordinates cleanup, drafts, checkpoints, and results;
- exposes a small state projection to UI.
InputSamplingSystem
- samples device input at render/platform frequency;
- resolves actions and device mappings;
- stores timestamped or frame-associated command state;
- fixed simulation consumes the appropriate command snapshot;
- edge actions are consumed exactly once.
PlayerMotorSystem
- applies acceleration/deceleration/reversal rules;
- normalizes input magnitude;
- integrates local velocity/position;
- handles dash state and sweep requests;
- submits movement constraint requests for boss boundary;
- does not move the camera directly.
CameraAndWorldOriginSystem
- owns logical camera anchor and render interpolation snapshots;
- performs deterministic origin-rebase decisions;
- converts logical world, local simulation, and camera-relative render coordinates;
- publishes logical frustum for spawning/visibility;
- owns presentation shake separately.
EncounterDirectorSystem
- consumes wave definitions and encounter-token state;
- advances pacing segments;
- admits packs within threat/entity caps;
- requests sectors and placements;
- detects drain and completion;
- records pacing telemetry.
SpawnPlacementSystem
- samples/validates annular candidates;
- predicts visibility time;
- tracks sector heat/reservations;
- creates placement results, not entities directly.
EnemyIntentSystem
- updates role state machines;
- computes desired movement and fire/ability requests;
- respects visibility/arming and boss state;
- does not perform direct damage.
SteeringAndMovementSystem
- resolves desired velocity, local avoidance, catch-up, and movement constraints;
- integrates enemy positions;
- applies field/status modifiers;
- maintains previous position for interpolation/collision.
WeaponAndAbilitySystem
- updates cooldowns;
- consumes fire/dash/boss pattern requests;
- applies weapon/perk modifiers;
- emits bounded ProjectileSpawnRequest, AreaEffectRequest, or Audio/VfxCue events;
- validates root/proc budgets.
ProjectileMovementSystem
- integrates projectile trajectories;
- updates lifetime and travel distance;
- handles simple homing/retarget transitions if defined;
- records swept segments;
- does not resolve damage itself.
SpatialBroadphaseSystem
- builds/updates the uniform grid;
- exposes deterministic local queries;
- owns no gameplay effects.
CollisionSystem
- performs swept projectile versus actor queries;
- performs contact/dash/boundary/area queries;
- emits contact or DamageEvent records;
- enforces one-hit and collision-mask rules.
DamageResolutionSystem
- applies immunity, armor, health, damage channel, and source attribution;
- emits HealthChanged, ArmorBroken, and DeathEvent;
- never spawns drops or destroys entities immediately.
DeathAndProcSystem
- resolves each death once;
- updates encounter tokens and score;
- creates drops;
- dispatches eligible on-kill/on-death perk effects;
- enforces proc context/depth;
- queues entity destruction after all dependent events.
PickupSystem
- attraction and collection;
- health/armor/score application;
- transition convergence;
- lifetime and conversion policy.
PerkModifierSystem
- builds cached derived player statistics from base values and selected perks;
- registers typed event reactions;
- invalidates/rebuilds only when build state changes;
- exposes derived values for diagnostics and card previews.
BossDirectorSystem
- creates/destroys lockfield;
- owns boss phase scheduler and authored pattern compatibility;
- controls interludes and boss camera profile;
- uses ordinary weapon, projectile, damage, and token systems for outcomes.
LifetimeAndRelevanceSystem
- expires projectiles, pickups, and VFX requests;
- transitions distant enemies to catch-up/recycle;
- applies active-region and absolute guards;
- records abnormal cleanup.
PresentationExtractionSystem
- reads stable gameplay components after the fixed tick;
- creates render snapshot arrays and compact instance data;
- converts local positions to camera-relative values;
- emits no gameplay mutation.
VfxEventSystem
- consumes typed cues;
- applies quality budgets and coalescing;
- maintains cosmetic-only lifetimes/particles;
- can drop low-priority effects without gameplay consequence.
AudioEventSystem
- consumes typed audio cues;
- applies voice priority, panning, coalescing, and buses;
- uses miniaudio resources;
- feeds captions when configured.
UiProjectionSystem
- creates RunHudModel, draft models, results data, and edge indicators;
- marks RmlUi data values dirty;
- validates incoming UI commands through the run state machine.
CheckpointSystem
- serializes only clean boundary state;
- validates schema/content compatibility;
- reconstructs next-wave state;
- never serializes live entity handles.
DiagnosticsSystem
- per-system timings;
- counts/caps/retries;
- deterministic state checksums;
- run seed and command capture;
- debug draw for frusta, spawn annulus, sectors, grid cells, token state, and boss safe routes.
20.4 Fixed-tick order
Canonical 60 Hz order:
- consume input and validated run/UI commands;
- advance run state, wave director, and boss scheduler;
- update player, enemy, and boss intent;
- resolve weapon/ability requests into spawn/effect queues;
- integrate player and actor movement;
- apply boss boundary constraints;
- perform origin rebase if scheduled and translate local state coherently;
- integrate projectiles and update lifetimes/ranges;
- rebuild/update spatial broadphase;
- generate projectile, contact, dash, slash, pickup, and area-query events;
- resolve armor, health, immunity, and damage;
- resolve deaths, encounter tokens, score, drops, and bounded perk procs;
- resolve pickup collection/convergence and relevance/recycling;
- commit entity creation and destruction in deterministic queues;
- evaluate wave/boss completion after deferred gameplay events drain;
- extract presentation snapshot and UI model;
- publish VFX/audio cues and deterministic checksum.
The exact split into ECS schedules may differ, but causal ordering MUST be documented and tested. Systems must not mutate collections while another system iterates them unless the ECS explicitly guarantees safe deferred structural changes.
20.5 Event structures
Representative transient events:
struct DamageEvent {
EntityId source;
EntityId target;
AbilityId ability;
DamageChannel channel;
float amount;
float2 point_local;
float2 normal_local;
ProcContext proc;
DamageFlags flags;
};
struct DeathEvent {
EntityId victim;
EntityId killer;
AbilityId source_ability;
EncounterTokenId token;
DamageChannel channel;
ProcContext proc;
};
struct SpawnPackRequest {
SpawnPackId pack;
EncounterTokenRange tokens;
AngularSector preferred_sector;
Tick earliest_tick;
Tick latest_tick;
SpawnRequestFlags flags;
};
struct VfxCue {
VfxId id;
float2 position_local;
float2 direction;
PresentationPriority priority;
uint64_t root_event_id;
};
Events use bounded vectors, frame arenas, ring buffers, or preallocated streams. Release builds must have deterministic overflow behavior and diagnostics.
20.6 Jolt responsibility
Jolt MUST NOT own baseline enemy, player, projectile, pickup, or boss collision. These objects are kinematic 2D gameplay primitives with specialized deterministic rules.
Jolt MAY later be used for:
- decorative 3D debris;
- optional physical obstacles in a variant arena;
- showcase-specific rigid-body interactions;
- non-authoritative presentation bodies.
Any later Jolt integration must not make core wave completion or projectile behavior frame-rate-dependent.
20.7 Vulkan and DXC responsibility
Vulkan renderer responsibilities:
- orthographic render camera;
- shared polygon meshes;
- instanced gameplay bodies/projectiles/markers;
- dynamic trail/ring/arc geometry where needed;
- depth/blend ordering;
- GPU buffers and synchronization;
- optional GPU particle update after correctness baseline;
- performance instrumentation.
DXC responsibilities:
- compile HLSL sources to SPIR-V through PixelBullet's shader pipeline;
- produce reflection/metadata as expected by engine conventions;
- define bounded variants for unlit geometry, trails/rings, fields, and post effects;
- support development diagnostics and asset validation.
Gameplay code MUST not depend on shader-side collision or hidden GPU simulation state.
20.8 RmlUi and miniaudio responsibility
RmlUi:
- renders UI documents;
- binds presentation data;
- emits input commands;
- contains no combat authority. [R7]
miniaudio:
- resource loading/streaming;
- voice playback and buses;
- device output;
- spatial panning/attenuation;
- contains no encounter timing authority. [R8]
20.9 Threading
Correctness baseline MAY run simulation systems serially. Parallelism should be introduced only across deterministic, order-independent work:
- enemy intent by chunks/archetypes with stable result buffers;
- projectile integration;
- broadphase insertion with partitioned buffers;
- collision candidate generation followed by deterministic merge;
- presentation extraction;
- VFX simulation.
Damage/death/proc resolution should remain serial or deterministically partitioned until equivalence is proven. Worker scheduling must not change replay checksums.
20.10 Technical architecture acceptance criteria
ARCH-AC-01 — Gameplay produces identical deterministic checksums for the same seed and input stream at 30, 60, 144, and uncapped render rates.
ARCH-AC-02 — Rendering, RmlUi, audio, and VFX can be disabled in the product-owned headless adapter without changing gameplay outcomes.
ARCH-AC-03 — Every damage source enters DamageEvent resolution and every death is processed exactly once through DeathEvent handling.
ARCH-AC-04 — Structural ECS changes are deferred or otherwise safe and do not invalidate active iterators.
ARCH-AC-05 — Core collision and movement do not depend on Jolt or render-frame timing.
ARCH-AC-06 — Presentation extraction contains camera-relative floats only; persistent logical coordinates do not leak into shaders as large raw values.
ARCH-AC-07 — UI and audio integrations can be restarted or reloaded without corrupting RunSession gameplay state.
ARCH-AC-08 — Parallel execution, when enabled, matches the serial reference checksum for audited seeds.
21. Data structures, configuration, and content authoring
The structures in this section are recommended schema direction. They do not assert that these types, filenames, or ownership splits already exist. Phase 0 owns the final product-local schema and target design.
21.1 Coordinate structures
constexpr float kWorldChunkSize = 256.0f;
struct WorldPosition2D {
int64_t chunk_x = 0;
int64_t chunk_y = 0;
float local_x = 0.0f;
float local_y = 0.0f;
};
struct LocalTransform2D {
float2 previous_position;
float2 position;
float rotation;
};
struct WorldOrigin2D {
WorldPosition2D logical_origin;
float2 accumulated_local_shift_for_diagnostics;
uint64_t rebase_count;
};
WorldPosition2D is used only where persistence or logical-distance traversal matters: run anchor, camera logical location, boss anchor, markers, checkpoint diagnostics. Most active entities store LocalTransform2D relative to current origin.
All conversion helpers MUST be centralized and unit-tested. Arbitrary code must not manually combine chunks and offsets.
21.2 Core gameplay components
Recommended initial components:
- LocalTransform2D;
- Velocity2D;
- CircleCollider;
- Team / CollisionMask;
- Health;
- Armor;
- DamageImmunity;
- PlayerTag;
- EnemyAgent;
- EnemyRoleState variants or compact role-specific components;
- BossState;
- WeaponState;
- DashState;
- ProjectileComponent;
- DamageSourceMetadata;
- Lifetime;
- PickupComponent;
- EncounterMembership;
- ActivationState;
- StatusModifierSet;
- ShapeVisual;
- TrailSource;
- AudioEmitterTag only where persistent emitter behavior exists.
Avoid a single untyped “properties dictionary.” Components and definitions should be strongly typed and validated.
21.3 Enemy archetype definition
struct EnemyArchetypeDefinition {
EnemyArchetypeId id;
ShapeVisualDefinition visual;
float radius;
float base_health;
float base_armor;
float move_speed;
float acceleration;
float turn_rate;
float contact_damage;
float contact_cooldown;
float threat_cost;
ActivationDefinition activation;
RelevanceDefinition relevance;
DropTableId drops;
ScoreValue score;
EnemyBehaviorVariant behavior;
};
EnemyBehaviorVariant is a tagged set of role-specific data:
- runner pursuit;
- shooter range/fire settings;
- charger wind-up/commit/recovery;
- splitter child definition/count;
- tank steering/weight;
- kamikaze pulse/explosion.
Definitions may inherit from curated templates at authoring time, but runtime data should be flattened and immutable.
21.4 Projectile and weapon definitions
struct ProjectileDefinition {
ProjectileId id;
float speed;
float radius;
float lifetime_seconds;
float max_range;
float damage;
DamageChannel channel;
uint8_t pierce_count;
uint8_t retarget_count;
uint8_t max_impacts_per_tick;
ProjectileCleanupPolicy cleanup;
ShapeVisualDefinition visual;
TrailDefinitionId trail;
AudioCueId impact_audio;
VfxId impact_vfx;
};
struct WeaponDefinition {
WeaponId id;
ProjectileId projectile;
float fire_interval;
uint16_t projectile_count;
float spread_radians;
float speed_variance;
float damage_multiplier;
RecoilDefinition recoil;
AudioCueId fire_audio;
VfxId muzzle_vfx;
};
Validation requires finite positive lifetime/range, safe counts, legal cleanup, and damage/channel consistency.
21.5 Spawn pack definition
struct SpawnPackDefinition {
SpawnPackId id;
SmallVector<SpawnPackMember, 12> members;
FormationKind formation;
float formation_width;
float min_member_separation;
float entry_spread_seconds;
SpawnMode allowed_modes;
ThreatCost total_cost;
uint16_t reserved_descendant_capacity;
SmallVector<SpawnPackId, 4> equivalent_variants;
};
A pack's computed cost and descendant capacity are validated from its members. Content authors should not manually enter a conflicting total without an override warning.
21.6 Wave definition
struct WaveDefinition {
uint32_t wave_index;
EncounterKind kind;
ThreatCost total_budget;
ThreatCost active_threat_cap;
uint16_t active_entity_cap;
SmallVector<WeightedPack, 16> pack_table;
SmallVector<RoleQuota, 8> role_quotas;
SmallVector<PacingSegment, 8> pacing;
SmallVector<AuthoredEncounterEvent, 8> events;
ThreatCost elite_budget;
DurationRange expected_duration;
Optional<PerkStage> reward_stage;
Optional<BossDefinitionId> boss;
uint64_t seed_salt;
};
A standard wave's total tokens are generated deterministically at start from budget, pack table, quotas, and seed. A boss wave references an explicit boss definition and optional interlude packs.
21.7 Pacing segment definition
struct PacingSegment {
PacingPhase phase;
float min_duration;
float max_duration;
float min_spawn_interval;
float max_spawn_interval;
float target_active_threat_fraction;
uint8_t max_simultaneous_danger_telegraphs;
SectorSelectionPolicy sector_policy;
};
Validation ensures durations and cadence can plausibly admit the committed budget under caps. A content tool SHOULD visualize predicted threat over time.
21.8 Boss definition
struct BossDefinition {
BossDefinitionId id;
EnemyArchetypeDefinition body;
LockfieldDefinition lockfield;
CameraProfileId camera;
SmallVector<BossPhaseDefinition, 8> phases;
SmallVector<BossPatternDefinition, 24> patterns;
PatternCompatibilityMatrix compatibility;
SmallVector<BossInterludeDefinition, 4> interludes;
AudioStateId music_state;
CheckpointPolicy checkpoint;
};
Boss pattern data includes telegraph, active, and recovery durations; projectile/effect requests; safe-route metadata used by tests; and phase eligibility.
21.9 Encounter tokens
struct EncounterToken {
EncounterTokenId id;
EncounterTokenState state;
SpawnPackId source_pack;
ThreatCost cost;
uint8_t recycle_count;
uint16_t live_entity_count;
uint16_t unresolved_descendant_count;
Tick state_enter_tick;
};
Entity components reference token IDs; tokens do not retain raw entity pointers. A separate small relation maps token to current entities for diagnostics and lifecycle updates.
21.10 Random streams
Use independent deterministic streams derived from campaign seed:
- wave composition;
- spawn sector/placement;
- enemy behavior variation;
- boss pattern selection;
- drops;
- perk presentation/order where not fixed;
- cosmetic-only randomness.
Cosmetic RNG MUST NOT perturb gameplay RNG. Adding a new particle must not alter boss patterns or drops.
Recommended derivation:
stream_seed = Hash64(campaign_seed, stream_id, wave_index, definition_seed_salt)
Stream state or sufficient reconstruction data is checkpointed.
21.11 Configuration format and validation
Definitions should use PixelBullet's established authored YAML and typed, versioned validation patterns unless Phase 0 records a justified alternative. Arena-authored and generated runtime content belongs under the product asset root and resolves through product-local @assets; @shared remains a distinct, explicitly allowed shared dependency rather than the product's default depot. Runtime should load a validated, versioned representation.
Required validation passes:
- schema and required fields;
- typed ID existence and uniqueness;
- finite numeric values and legal ranges;
- projectile lifetime/range/cap rules;
- perk trigger/effect and proc-depth rules;
- pack threat and descendant capacity;
- wave budget/cap feasibility;
- boss pattern telegraph and compatibility;
- audio/VFX/UI asset references;
- localization/text presence for player-facing data;
- checkpoint compatibility version.
Development builds fail fast with file/field diagnostics. Release builds reject incompatible content cleanly rather than continuing with partially initialized definitions.
21.12 Hot reload
Development-only hot reload MAY support:
- visual/material values;
- audio/VFX definitions;
- numerical enemy/weapon/perk data between waves;
- wave definitions before the wave begins;
- RmlUi documents/styles.
It SHOULD NOT hot-reload structural component layouts or replace an active boss state machine in place. Incompatible reload requests defer until a clean session restart.
Deterministic regression runs disable hot reload.
21.13 Authoring and debug tools
BulletSketch remains the authored-content tool. Play in Viewport is an in-process authored-scene preview, and Run Standalone invokes the generic scene runner for an authored scene or snapshot. The planned selectable asset-base mode will let those authored-scene workflows edit and preview product-local content without launching the complete Arena product. Complete sessions run through the future boundless-vector-arena executable; a product-owned headless adapter drives deterministic automation. Editor Run Product integration is optional and deferred.
Required internal controls:
- choose campaign seed;
- start any wave or boss with a synthetic valid build;
- grant/remove perks;
- set health/armor and invulnerability;
- spawn a role, pack, surge, or elite in a selected sector;
- visualize logical frustum, expanded region, spawn annulus, sectors, heat, placement candidates, and predicted entry time;
- visualize active/soft/hard relevance radii;
- display encounter-token graph and state;
- display uniform-grid cells and query candidates;
- freeze/step fixed simulation;
- inspect projectile lifetime/range/proc generation;
- show boss pattern scheduler and safe-route samples;
- force origin rebase;
- export run seed/input/checksum trace;
- display CPU/GPU/system budgets.
These tools are part of implementation quality, not optional polish.
21.14 Data acceptance criteria
DATA-AC-01 — All gameplay content loads through typed, versioned definitions with actionable field-level validation errors.
DATA-AC-02 — No runtime combat behavior depends on stringly typed dictionary lookups in hot loops.
DATA-AC-03 — Independent RNG streams prevent cosmetic changes from altering gameplay checksums.
DATA-AC-04 — Wave, pack, perk, projectile, and boss definitions are validated against hard caps and lifecycle requirements before a run starts.
DATA-AC-05 — Checkpoints contain stable IDs and versioned values, never raw pointers, transient entity IDs, or renderer/audio handles.
DATA-AC-06 — Debug tools can inspect every spawn, token, projectile, origin, boss-pattern, and budget state required to diagnose acceptance failures.
DATA-AC-07 — Incompatible hot reloads defer or require restart and cannot corrupt an active deterministic session.
22. Performance, scalability, and object management
22.1 Performance philosophy
The world is logically unbounded but computationally bounded. Cost should depend on the current active encounter and visible presentation, not on distance traveled or elapsed run duration.
The implementation must remain stable under:
- long continuous movement;
- late-wave enemy counts;
- high fire-rate/perk combinations;
- boss bullet patterns;
- origin rebasing;
- UI and audio event bursts;
- reduced frame rate without simulation divergence.
22.2 Baseline platform and frame target
The project should name a concrete baseline development platform before final optimization sign-off. Until then, the initial target is:
- 1920×1080;
- 60 Hz fixed simulation;
- 60 FPS presentation minimum on the selected baseline discrete GPU/desktop-class CPU;
- support for higher render rates without simulation changes;
- headless simulation faster than real time for automated tests.
Initial frame budgets on baseline hardware:
| Area | P95 target | P99 guard |
| Total fixed simulation tick | ≤ 8 ms | ≤ 12 ms |
| Render-thread CPU preparation/submission | ≤ 3 ms | ≤ 5 ms |
| GPU frame at 1080p standard quality | ≤ 8 ms | ≤ 12 ms |
| RmlUi update/render CPU | ≤ 1 ms typical | ≤ 2 ms during draft transitions |
| Audio event processing | ≤ 0.5 ms typical | ≤ 1 ms burst |
These leave margin for editor/dev overhead and platform variation. Final shipping targets should be established from measured PixelBullet baselines.
22.3 Normal-play and stress capacities
Initial normal-play hard or design caps:
| Object | Normal campaign target/cap |
| Active enemies | 350 ordinary; up to 500 for explicitly tested interlude/stress content |
| Gameplay projectiles | 2,500 preferred, 3,000 absolute campaign guard |
| Pickups | 128 |
| Concurrent gameplay fields | 64 |
| VFX particles/instances | 8,000 quality-dependent |
| Ambient marker instances | 2,000 visible/cached target |
| Audio one-shot voices | 32 plus music |
| Edge indicators | 8 |
| Deferred damage events/tick | 8,192 guard |
| Spawn placement requests/tick | 128 guard |
Mandatory stress scenario:
- 800 active enemies;
- 6,000 gameplay projectiles;
- 20,000 cosmetic VFX instances;
- continuous movement and periodic rebasing;
- 60 seconds;
- no crash, data corruption, unbounded allocation, or invalid token state.
The stress case may run below 60 FPS on baseline hardware, but simulation correctness and graceful presentation degradation must remain intact.
22.4 CPU data layout
Recommended hot-path layout:
- dense ECS archetypes or SoA pools for projectiles and simple enemies;
- compact component fields with 32-bit local floats;
- stable/generational entity IDs;
- pre-reserved vectors and free lists;
- frame arenas for transient events and query results;
- no per-entity virtual dispatch in movement/collision hot loops;
- role state represented by tagged compact data or archetype-specific systems;
- immutable definition pointers/indices stable for session lifetime;
- cache derived player statistics rather than recomputing perk graphs per shot.
Storage should distinguish:
- authoritative gameplay entities;
- transient gameplay events;
- render snapshot instances;
- cosmetic VFX entities;
- UI presentation values;
- audio cues.
22.5 Allocation policy
After run warm-up, ordinary simulation ticks SHOULD perform zero general-purpose heap allocations.
Allowed allocation moments:
- session creation;
- content load;
- capacity growth in development with diagnostics;
- wave-boundary preparation if reserved pools require deliberate expansion;
- UI document transitions under RmlUi's own managed behavior;
- asynchronous audio/asset work outside the deterministic hot path.
Release builds should reserve validated campaign maxima or use bounded growth strategies. Any capacity overflow must have explicit fallback and telemetry.
22.6 Broadphase complexity
A uniform grid with 1.0–1.5 WU cells should keep local collision queries near O(n + candidate pairs) for this obstacle-free 2D field.
Requirements:
- cell storage cleared/reused without freeing memory each tick;
- insertion based on collider AABB or center for small circles;
- swept projectile queries enumerate cells intersected by swept AABB;
- oversized boss/field objects use a special list or multi-cell insertion with duplication control;
- query result deduplication where objects span cells;
- telemetry for average/max occupants and candidate count;
- cell-size tuning based on measured role density and projectile sweep length.
No all-projectile-versus-all-enemy pass is permitted.
22.7 Rendering scalability
Use shared meshes and instancing for repeated geometry. [R6]
Recommended flow:
- presentation extraction writes compact CPU instance arrays by render class;
- arrays are copied into persistently managed or ring-buffered GPU upload memory;
- renderer issues one or a small number of draws per shape/pipeline class;
- trails/rings use separate batched buffers;
- low-priority VFX are culled or reduced before upload;
- ambient markers are generated/cached by visible logical cells;
- indirect draws are considered only after CPU profiling.
Initial renderer constraints:
- no unique material instance per actor;
- color/emission/hit flash supplied per instance;
- no descriptor allocation per projectile;
- no per-entity command-buffer rebuild abstraction that defeats batching;
- transparent blending order designed to avoid global per-particle sort where possible;
- camera-relative positions preserve float precision.
22.8 GPU particle strategy
The correctness baseline may use CPU-authored batched particles. A GPU particle path is optional.
If implemented:
- particles are cosmetic only;
- spawn commands derive from presentation events;
- buffer overflow drops lowest-priority particles deterministically from the presentation perspective;
- no gameplay collision or timing depends on GPU particle state;
- origin rebase is represented by camera-relative spawn and camera delta, not rewriting historical logical coordinates;
- capture/debug mode can disable GPU particles and retain core event visualization.
22.9 Audio scalability
- cache high-frequency source data;
- reuse voices;
- coalesce repeated cues;
- calculate audibility/priority before voice allocation;
- keep music streaming separate;
- cap captions independently so a sound cluster does not create unreadable text spam;
- record dropped/coalesced cue counts.
22.10 UI scalability
HUD binding should update changed values, not rebuild the document every tick. [R7]
- stable data model names;
- dirty only changed variables;
- event lists use bounded models;
- damage numbers and transient labels are pooled or limited;
- pause/draft documents may load ahead of first use;
- UI animation cannot stall fixed simulation.
22.11 Graceful degradation
When frame or budget pressure occurs, degrade in this order:
- reduce ambient marker density;
- reduce decorative trail segment count;
- reduce low-priority death fragments and sparks;
- reduce bloom/post quality;
- coalesce low-priority audio;
- reduce cosmetic damage numbers;
- simplify non-danger animation detail.
Do not degrade:
- player/enemy/projectile simulation;
- dangerous telegraphs;
- hostile projectile visuals;
- spawn fairness;
- boss safe-route geometry;
- wave/token accounting;
- critical audio warnings.
Dynamic quality adjustment MAY react to sustained frame pressure but must be presentation-only and visible in diagnostics.
22.12 Long-run stability
A two-hour automated travel/combat soak MUST monitor:
- resident memory;
- ECS/pool capacities and live counts;
- descriptor and GPU-buffer usage;
- audio resource/voice counts;
- RmlUi document/model lifetime;
- origin rebase count;
- logical-coordinate magnitude;
- token creation/resolution;
- RNG state/checksum;
- frame-time percentiles;
- allocation counts.
No metric should grow monotonically with world distance or wave restarts except bounded logs/statistics explicitly retained.
22.13 Performance acceptance criteria
PERF-AC-01 — Standard campaign P95/P99 fixed-tick, render CPU, GPU, UI, and audio times meet the selected baseline budgets.
PERF-AC-02 — Ordinary post-warm-up simulation ticks perform zero general-purpose heap allocations in profiling builds.
PERF-AC-03 — Collision uses spatial queries and exhibits no O(projectiles × enemies) full scan in traces.
PERF-AC-04 — Rendering batches repeated shapes/projectiles through shared meshes and instance data and allocates no descriptor/material object per entity. [R6]
PERF-AC-05 — The mandatory 800-enemy/6,000-projectile/20,000-VFX stress case remains correct, bounded, and recoverable.
PERF-AC-06 — A two-hour travel/combat/restart soak has no monotonic memory, handle, descriptor, audio-resource, or token leak.
PERF-AC-07 — Presentation quality degradation never removes dangerous telegraphs or visible lethal projectiles.
PERF-AC-08 — Performance counters expose active entities, projectiles, broadphase candidates, event-buffer high-water marks, draws/instances, GPU timings, voices, spawn retries, and rebase count.
23. Edge cases, failure states, and implementation risks
23.1 Edge-case policy
The game must remain completable, deterministic, and readable under unusual input, aspect ratio, performance, and content combinations. Edge handling should preserve gameplay truth first, then presentation quality.
Recovery logic MUST:
- avoid rewarding the player for entities that were merely culled or repaired;
- avoid inventing invisible damage;
- leave diagnostics sufficient to reproduce the event;
- prefer a clean state transition over continuing with corrupted token or boss state;
- remain bounded so recovery itself cannot loop indefinitely.
23.2 Input edge cases
Zero-length aim vector
When cursor/gamepad aim is at or extremely near the player center:
- preserve the last valid aim direction;
- do not generate NaN normalization;
- expose a small dead radius for mouse aim only if necessary;
- gamepad aim below deadzone falls back to last valid aim;
- firing remains deterministic.
Simultaneous opposite movement inputs
- digital axes cancel to zero on that axis;
- analog and digital sources are resolved by the active-device policy;
- input normalization prevents diagonal speed advantage;
- device switching cannot leave a stale axis latched.
Dash with no movement input
- use current nontrivial velocity direction;
- otherwise use last movement direction;
- otherwise use aim direction;
- otherwise use a fixed default direction only as an unreachable safety fallback;
- resulting direction is shown consistently in debug state.
Input during pause/draft/transition
- gameplay actions are suppressed while the relevant UI owns focus;
- input edges are flushed or generation-stamped on state transition;
- no held fire produces an unintended card selection;
- resume may restore held-fire behavior only after one simulation tick or explicit action policy.
Lost focus or device disconnect
- platform focus loss pauses or safely zeroes movement/fire according to product policy;
- gamepad disconnect produces a clear UI notice and does not preserve last analog movement;
- fixed simulation does not consume an unbounded real-time delta on refocus.
23.3 Camera and aspect-ratio edge cases
Ultrawide
Ultrawide views expose more horizontal area and could make spawning easier or increase player range advantage.
Rules:
- gameplay frustum uses the actual supported aspect;
- spawn annulus and predicted entry calculations adapt to it;
- camera vertical span remains the principal scale target while horizontal visibility expands only to a supported cap if balance requires;
- UI uses safe regions and does not cover center combat;
- hostile range/lifetime remains defined in world units, not screen fractions;
- balance tests include 21:9.
A competitive-equivalence crop is not required for this single-player product, but extreme aspects MAY letterbox beyond the validated range.
4:3 or narrow window
- retain minimum vertical/horizontal combat visibility;
- permit modest zoom-out if required;
- validate boss field framing;
- UI reflows instead of obscuring the player;
- below minimum window dimensions, show a supported-resolution warning.
Live resize
- logical frustum updates at a safe frame/tick boundary;
- existing spawned enemies are not instantly invalidated or activated unfairly;
- placement requests revalidate against the new frustum;
- cursor-world conversion uses the matching camera snapshot;
- no camera or grid jump.
Camera shake at edge
Shake never modifies logical visibility or spawn tests. An enemy may become visually exposed a few pixels earlier due to presentation shake; expanded spawn margins must make this harmless.
23.4 Movement and speed edge cases
Extreme speed combinations
Derived speed changes require:
- dynamic spawn lead distance;
- swept player contact/dash collision;
- bounded acceleration and turn behavior;
- active-region/catch-up radii large enough for validated maximum speed;
- no camera damping;
- diagnostics if authored perks exceed the supported speed envelope.
Reversal during dash
Dash direction locks at dash start. Ordinary input does not redirect it unless a future perk explicitly supports steering. The player regains motor control at dash end with velocity according to configured carry-over.
Boss-boundary dash
The dash sweep stops or slides at the analytic boundary. It cannot:
- tunnel out;
- become stuck outside due to floating-point error;
- receive multiple boundary contacts;
- continue rendering an afterimage beyond the legal path.
High-speed charger crossing origin rebase
Rebase occurs at a deterministic stage and shifts previous/current positions consistently. The charger sweep and telegraph remain continuous.
23.5 Spawn and enemy edge cases
Player continuously moves faster than a role
- the role may enter CatchUp outside view;
- CatchUp may use a bounded speed multiplier;
- it remains non-attacking while outside expanded view;
- if it cannot re-engage, it recycles with the same token;
- the campaign cannot stall behind the player.
No valid spawn candidate
- retry across more sectors and candidate radii within configured safe limits;
- delay admission while preserving pacing state;
- do not shrink reaction time below the floor;
- emit retry telemetry;
- after bounded failure, choose an equivalent pack or invoke the diagnosed safety path.
Spawn becomes visible after resize or zoom transition
- ordinary spawning is paused during camera zoom transitions;
- accepted but not instantiated placements are revalidated;
- concealed entities that become visible unexpectedly remain harmless and receive a full arming period, while a diagnostic records the event.
Split at entity cap
- descendant capacity is reserved before admitting the parent;
- if a non-content fault still prevents full spawn, create the allowed number, preserve token liability correctly, and report a release-blocking diagnostic;
- never silently suppress descendants while granting full parent reward.
Enemy handle lost or component corrupted
Development builds assert and dump token/entity mapping. Production resolves the token through the safety valve only after preventing rewards and hostile effects.
All active enemies outside view
The director accelerates legal relevance/spawn handling. It does not teleport an active enemy into view or allow off-screen fire.
23.6 Projectile and proc edge cases
Owner dies before projectile impact
Projectile retains source team and scoring attribution through immutable source metadata. A stale owner handle is never dereferenced.
Target dies earlier in the same tick
Collision candidates may generate hits, but damage resolution checks target life state and ordered event identity. A death is emitted once; later damage may be ignored or recorded as overkill without duplicate rewards.
Piercing projectile crosses many overlapping targets
- resolve earliest time of impact;
- apply finite pierce and per-tick impact cap;
- deterministic entity-ID tie-break for equal TOI;
- retire and diagnose if the impact guard is reached.
Ricochet has no target
Projectile expires or continues according to its definition; it does not select concealed enemies or scan indefinitely.
Chain effects collide with cap
Gameplay area-damage events have reserved capacity and strict root-event limits. Decorative VFX may drop. If authoritative event capacity is still exceeded, development fails loudly; release applies a documented deterministic truncation order and records a fatal-quality telemetry event.
Time scale, pause, or hitch
- lifetime uses simulation ticks, not wall-clock time;
- pause advances no gameplay age/distance;
- render hitch is clamped to bounded fixed-step catch-up;
- simulation does not process hundreds of steps after an OS stall.
23.7 Pickup edge cases
Full health/armor
Definition decides whether pickup waits, converts to score, partially applies, or expires. The result is shown once and cannot be repeatedly collected.
Pickup far behind
Transition convergence or relevance conversion resolves it. It never remains as permanent logical-world state.
Player dies during pickup convergence
Defeat state freezes collection after same-tick deterministic ordering. Checkpoint reconstruction does not restore unresolved pickups.
Magnet and origin rebase
Attraction velocity/targeting uses local transforms shifted coherently; no pickup jumps or loses target.
23.8 Boss edge cases
Player outside forming lockfield
The field forms around the current player anchor, so the player starts inside. If numerical error places the player beyond the boundary, project them to the nearest valid interior point before collision activates and record a diagnostic.
Boss overlaps player after teleport
Destination validation expands both radii plus safety margin. Invalid candidates are resampled. If all fail, use a deterministic safe fallback position and extend telegraph rather than overlap.
Boss pattern has no safe route
Automated pattern validation and recorded-playback tests should catch this. Runtime may prevent incompatible pattern overlap; it should not dynamically delete bullets based on player state unless the pattern explicitly contains a purge.
Boss phase changes on the same tick as death
Death has priority over nonterminal phase transition. No new phase pattern or armor is created after lethal resolution.
Shadow interlude add remains hidden
Token/relevance rules inside the lockfield force resolution. Interlude has its own timeout diagnostics and cannot recycle through the world annulus.
Checkpoint content changed
A content hash/version mismatch uses an explicit compatibility policy:
- migrate supported data;
- restart from an earlier safe campaign boundary;
- or reject the checkpoint with a clear development/user message.
It never loads mismatched stable IDs as arbitrary entities.
23.9 Origin and coordinate edge cases
Rebase during active effects
All authoritative local positions, previous positions, target points, field anchors, spawn candidates, broadphase origin, and presentation snapshot bases shift together. Historical camera-relative trail points either shift or are stored relative to an effect anchor.
Very long travel
Integer chunks support practical indefinite travel. Tests should cover magnitudes far beyond a normal campaign. Hashing ambient cells must handle signed 64-bit coordinates without overflow-dependent undefined behavior.
Negative coordinates
Chunk normalization and grid phase work symmetrically across zero. Floor division must be mathematically correct for negative values rather than relying on truncation toward zero.
Serialization
World positions serialize explicit signed chunks and normalized offsets. Endianness/version rules follow PixelBullet asset/save conventions.
23.10 UI/audio/render failure cases
RmlUi document reload failure
Keep gameplay paused in a safe state, show a fallback diagnostic UI in development, and never resume without required controls. Release assets should be prevalidated.
Audio device loss
Continue simulation silently, attempt device recovery through the audio layer, and preserve bus settings. Audio failure cannot block wave completion.
Shader/pipeline failure
Development displays a clear fallback/error material and diagnostic. Release startup should fail cleanly if mandatory gameplay pipelines cannot be created; it must not render invisible hostile projectiles.
GPU buffer overflow
Drop low-priority cosmetic instances first. Gameplay bodies/projectiles use reserved capacity and visible fault diagnostics if exceeded.
23.11 Risk register
| Risk | Likelihood | Impact | Mitigation | Fallback/trigger |
| Boundless movement becomes one-direction treadmill | Medium | High | Sector heat, cross-angle packs, stable markers, anti-kiting metrics, playtests | Reweight director; fallback to larger bounded arena only if validation repeatedly fails |
| Spawn feels unfair or visibly pops | Medium | High | Predicted entry time, expanded frustum, arming, Monte Carlo tests | Increase margins/telegraphs; never relax floor |
| Waves stall on irrelevant enemies | Medium | High | token accounting, catch-up, recycling, safety valve, soak tests | Diagnose role/placement; safety resolve only as last resort |
| Camera-centered motion causes discomfort | Low-medium | Medium | no lag/lookahead, restrained grid, shake controls, stable markers | accessibility profile; optional very small visual-only deadband only after tests, never default |
| Boss lockfield feels inconsistent with boundless promise | Medium | Medium-high | diegetic formation, current-position anchor, only on boss waves, dissolve afterward | larger field and transition polish; permanent arena only if boss tests fail |
| Infinite grid looks cheap/empty | Medium | Medium | 2.5D material polish, stable markers, act motifs, strong VFX | add authored procedural motifs, not persistent map content |
| Perk combinations explode event/projectile counts | Medium | High | typed limits, static validation, proc depth, hard caps, stress matrix | rebalance or exclude incompatible combinations |
| Origin rebase creates visible discontinuity | Low-medium | High | central coordinate API, deterministic tick stage, previous/current shift, long-run tests | increase threshold; temporary double camera anchor only if measured necessary |
| Determinism breaks under threading | Medium | Medium-high | serial reference, stable merge/order, checksums | ship serial systems until parallel path proves identical |
| RmlUi becomes coupled to ECS | Medium | Medium | presentation model and command boundary, integration tests | reject direct component bindings in review |
| Audio saturation hides warnings | Medium | Medium | priorities, reserved warning voices, coalescing | reduce decorative cue density |
| Scope expands into open-world systems | Medium | High | explicit non-goals and active-bubble model | require design change record before terrain/streaming/navigation work |
| Full 31-wave campaign tuning exceeds schedule | High | Medium-high | data-driven waves, early representative act slices, telemetry, reuse roles | reduce pack variants/elite set, not campaign spine or correctness systems |
| Visual effects dominate gameplay readability | Medium | High | priority layers, budgets, accessibility, capture tests | lower effect density/intensity by default |
23.12 Risk acceptance criteria
RISK-AC-01 — Every high-impact risk has an owner, observable metric, validation stage, and explicit mitigation before content-complete status.
RISK-AC-02 — No recovery path grants score, drops, healing, perk procs, or wave progress unless an actual eligible defeat occurred.
RISK-AC-03 — No failure in UI, audio, VFX, or decorative rendering can corrupt authoritative encounter state.
RISK-AC-04 — Negative coordinates, long travel, resize, focus loss, owner death, cap pressure, and boss-boundary dash have automated regression coverage.
RISK-AC-05 — Triggering the fixed-arena fallback requires measured failure against Section 2.4 thresholds and a recorded design decision, not implementation convenience.
24. Testing and validation plan
24.1 Test layers
The project requires five complementary layers:
- unit/property tests for deterministic math, data, and lifecycle rules;
- headless integration tests for complete system interactions;
- campaign regression and replay tests for authored seeds;
- performance/soak tests for boundedness and stability;
- human playtests for feel, readability, pacing, and engagement.
A passing build requires all applicable automated tests plus the current playtest gate. Automated correctness cannot prove fun; subjective playtests cannot replace deterministic lifecycle checks.
24.2 Unit and property tests
Coordinate math
- chunk/local normalization, including negative values;
- world-to-local and local-to-world round trips;
- origin shift invariance;
- grid/marker hash stability;
- serialization round trip at extreme chunk values;
- camera-relative conversion precision.
Movement
- digital/analog normalization;
- acceleration, deceleration, reversal timing;
- dash direction fallback order;
- dash duration/distance at fixed tick;
- boss boundary projection and tangent slide;
- status/speed modifier clamping.
Camera
- player center at standard-wave logical camera;
- cursor-to-world conversion at supported aspects and zooms;
- shake independence;
- interpolation endpoints;
- frustum expansion.
Spawn placement
Property-based generation over:
- aspect ratio;
- view zoom;
- player velocity;
- enemy speed/radius/acceleration;
- angular sector;
- pack size/formation;
- negative/large logical coordinates.
Assertions:
- outside expanded frustum;
- minimum predicted visibility time;
- separation and cap legality;
- deterministic candidate result for seed;
- no NaN or unbounded retry.
Collision/projectiles
- segment-circle time of impact;
- grazing and zero-length segments;
- smallest target at maximum speed;
- multiple target ordering;
- pierce/retarget/recent-hit behavior;
- lifetime/range expiration;
- owner invalidation;
- origin rebase invariance;
- hostile visible-exit cleanup.
Damage/death/procs
- armor-before-health policy;
- invulnerability and contact cooldown;
- one death per entity;
- reward exactly once;
- dash/explosion/drone/projectile equivalence;
- chain-generation termination;
- Phoenix lethal interception;
- pickup/drop eligibility;
- recycled entity no-reward invariant.
Encounter tokens
- pending/reserved/in-play/recycle/defeated transitions;
- split descendant liability;
- recycling preserving token;
- wave completion invariant;
- structural entity deletion not resolving token;
- safety-valve diagnostics.
Data validation
- missing IDs;
- invalid finite values;
- zero/infinite projectile lifetime;
- impossible wave cap/budget;
- perk recursion and cap violation;
- boss pattern compatibility;
- checkpoint version mismatch.
24.3 Headless integration tests
Required scenarios:
- start run, complete wave, intermission, next wave;
- wave 5 draft and checkpoint;
- wave 10 three-of-six draft;
- checkpoint save/load and deterministic replay;
- one test for each enemy role and elite modifier;
- directional surge telegraph/activation;
- straight-line player movement with recycling;
- splitter death at near-capacity;
- every player damage source generating normal reward path;
- every perk individually and representative combinations;
- boss lockfield form/fight/dissolve;
- each boss phase transition;
- Shadow teleport/slash/interludes;
- player death before/after Phoenix;
- window/frustum profile changes at safe test boundaries;
- forced origin rebase during fire, dash, charge, pickup attraction, and boss pattern;
- presentation/audio/UI disabled with identical checksum.
Headless tests should run through the product-owned headless adapter and reuse existing PixelBullet test conventions where practical. The generic scene runner is not the Arena runtime.
24.4 Deterministic replay tests
A replay contains:
- build/content version;
- campaign seed;
- difficulty;
- fixed-tick input commands;
- optional checkpoint origin;
- expected periodic state checksums;
- expected final run summary.
Golden replays:
- basic waves 1–5;
- Core and reward selection;
- Act II role combinations;
- Omega;
- high-perk Act III stress;
- Apocalypse;
- Shadow full fight;
- a complete campaign clear;
- one defeat/restart path;
- one extreme travel/rebase path.
Render frame rate is varied while fixed input/tick stream remains constant. Checksums must match.
Checksum scope includes authoritative:
- run state and wave index;
- world origin/logical anchor;
- entity IDs and relevant components in stable order;
- token states;
- RNG stream states;
- score/build/player resources;
- boss state;
- gameplay event queues after tick completion.
It excludes cosmetic particles, audio voice state, UI animation, and presentation shake.
24.5 Spawn Monte Carlo tests
Run millions of placement attempts offline across:
- validated aspect ratios;
- all roles and elite speed variants;
- maximum player speed and dash-related approach conditions;
- moving/zooming camera profiles;
- sector heat patterns;
- surge formations;
- negative and very large coordinates.
Collect:
- rejection causes;
- accepted visibility-time distribution;
- sector distribution;
- retries per success;
- invalid/overlap rate;
- pack distortion;
- projected active-density distribution.
Acceptance is based on both zero safety violations and practical placement success rate.
24.6 Campaign simulation and bot tests
Simple scripted agents are useful even if they do not play optimally:
- stationary fire;
- constant-direction movement;
- circle-strafe;
- random walk;
- threat-avoidance heuristic;
- boss safe-route test agent.
Use them to detect:
- stalls;
- spawn starvation;
- runaway token counts;
- impossible pattern overlap;
- cap violations;
- deterministic divergence;
- extreme duration outliers.
A bot win rate is not a balance target. Bots reveal structural failures and produce comparable telemetry.
24.7 Performance and soak matrix
Standard representative scenes
- early wave with low density;
- shooter/splitter mixed mid-wave;
- late Act III peak;
- high fire-rate/twin/pierce build;
- Chain Burst split cascade;
- drone plus hostile projectile pressure;
- each boss's densest legal pattern;
- full HUD/draft transition.
Stress scenes
- 800 enemies, 6,000 projectiles, 20,000 VFX;
- worst-case broadphase cell clustering;
- maximum simultaneous death/proc event burst;
- audio one-shot saturation;
- repeated UI draft open/close;
- 10,000 origin rebases;
- two-hour campaign/restart travel soak.
Record CPU/GPU timings, allocations, high-water marks, memory, and dropped presentation events.
24.8 Visual/readability tests
Capture scripted situations with:
- full color;
- grayscale;
- simulated color-vision deficiencies;
- low/high bloom;
- reduced particles;
- 1280×720, 1080p, 1440p, ultrawide;
- maximum legal hostile projectile density;
- overlapping pickup and perk effects;
- boss field and phase transitions.
Evaluation questions:
- can testers locate the player instantly?
- can they distinguish friendly and hostile fire?
- can they identify role before contact?
- can they read charge, kamikaze, surge, teleport, and slash telegraphs?
- is the safe route visible?
- does background travel read without distracting?
- do hitboxes feel aligned with art?
24.9 Gameplay playtest stages
Stage A: movement and camera
Test without progression complexity:
- centered camera comfort;
- acceleration/deceleration/reversal;
- aim stability;
- dash control;
- infinite-grid travel perception.
Gate:
- at least 80% of target internal testers prefer the tuned boundless movement over the fixed-screen reference for continuous combat;
- no recurring reports of camera lag, aim drift, or motion sickness attributable to avoidable background behavior.
Stage B: spawn fairness and wave flow
Test representative waves with temporary fixed weapons/build.
Gate:
- no visible spawn pop in reviewed sessions;
- dangerous entries are anticipated correctly;
- no frequent straggler hunt or empty chase;
- players describe pressure as surrounding/re-forming, not cheating.
Stage C: perk builds
Test all milestone choices and representative combinations.
Gate:
- multiple build identities are recognized;
- descriptions match observed effects;
- no dominant mandatory selection across all content without a deliberate balance rationale;
- performance stays within target.
Stage D: bosses
Test each boss in isolation and campaign context.
Gate:
- lockfield feels intentional and readable;
- patterns have understandable failure causes;
- Shadow feels like a culmination rather than a different game;
- no boss requires a specific random perk.
Stage E: full run
Gate:
- target completion duration and pacing;
- act escalation is perceptible;
- fatigue does not peak far before wave 30;
- full-run restarts/checkpoints behave as promised;
- testers consider the boundless structure more sustainable than a single fixed screen.
24.10 Comparative validation against fixed arena
To validate the design decision, run controlled A/B sessions with equivalent:
- player weapons and movement speed;
- enemy roles;
- threat budget;
- perk build;
- 10–15 minute representative slice.
Compare:
- dash use and direction diversity;
- wall/corner dwell time;
- net movement and turn frequency;
- perceived freedom;
- spawn fairness;
- tactical variety;
- clarity and fatigue;
- preference;
- performance.
The boundless version is considered a meaningful improvement when it produces higher movement/approach variety and player preference without materially worse clarity or unexplained damage.
24.11 Release-blocking validation criteria
The product cannot be called implementation-complete until:
- all system acceptance criteria marked MUST pass;
- campaign regression seeds complete without stalls or state corruption;
- deterministic replays match across supported render rates;
- spawn Monte Carlo has zero accepted safety violations;
- full campaign and boss paths have human playtest sign-off;
- baseline performance and two-hour soak pass;
- no off-screen/untelegraphed deaths remain in reviewed standard-difficulty reports;
- checkpoint compatibility and failure behavior are documented;
- all shipped content and audio/visual assets have verified provenance.
25. Phased implementation plan
25.1 Planning assumptions
This is a production implementation plan, not a disposable prototype. Each phase leaves tested engine/game infrastructure and a runnable product slice.
Estimate assumptions:
- one experienced engineer familiar with PixelBullet;
- existing application/layer, Vulkan mesh/material, scene/ECS, RmlUi, miniaudio, input, asset, authoring, and test infrastructure is reusable but may need product-driven extensions;
- the generic authored-scene runner is not extended into an Arena runtime;
- no new network layer;
- no authored terrain, navmesh, or asset-heavy character pipeline;
- design/engineering work may overlap, but estimates are person-days rather than elapsed calendar promises;
- tuning and polish uncertainty is substantial.
Conservative total: 63–98 person-days. If the relevant PixelBullet primitives are already mature and reusable, the likely implementation band is 50–75 person-days. Uncertainty is approximately ±35–40%, concentrated in rendering integration, RmlUi binding maturity, content tuning, and boss polish.
25.2 Phase 0 — product skeleton, schemas, and observability
Estimate: 4–6 person-days.
Implement:
- product Bazel ownership, product-local asset root, and explicit runtime closure boundary;
- generic selectable BulletSketch asset-base support for authored product content;
- a product-owned RunSession concept, run-state skeleton, typed IDs, initial schemas, fixed-step harness, deterministic seed streams, replay command format, checksums, and diagnostics;
- a product-owned headless adapter with startup, shutdown, and deterministic smoke coverage;
- an interactive product composition root and empty RmlUi HUD model/document seam;
- baseline build and asset validation.
Acceptance gate:
- the product ownership and asset boundaries build without depending on tools/scene_runner or the broad shared depot;
- BulletSketch can select the product asset base for authored-scene workflows without launching the full product;
- the interactive product and product-owned headless adapter launch and tear down cleanly;
- executes deterministic empty fixed ticks;
- same seed/input produces same checksum at varied render rates;
- schema errors are actionable;
- clean teardown has no live ECS/UI/audio resources.
Relevant criteria: ARCH-AC-01, ARCH-AC-02, DATA-AC-01, DATA-AC-03.
25.3 Phase 1 — boundless world, player motor, and camera
Estimate: 5–8 person-days.
Implement:
- orthographic 2.5D camera;
- exact-centered standard-wave tracking;
- cursor/gamepad world aim;
- acceleration/deceleration/reversal model;
- dash state and swept path;
- chunk/local logical coordinates;
- deterministic origin rebase;
- procedural grid and minimal stable markers;
- presentation interpolation and shake separation;
- aspect/resize handling;
- debug visualization and rebase controls.
Acceptance gate:
- 60-minute unrestricted travel with no visible grid, player, cursor, trail, or camera discontinuity;
- movement meets timing targets and feels responsive in Stage A playtest;
- camera shake does not affect aim or logical frustum;
- negative and extreme coordinates pass tests;
- no render-rate-dependent movement.
Relevant criteria: movement/camera/world criteria from Sections 7–9, VIS-AC-02, RISK-AC-04.
25.4 Phase 2 — combat kernel and bounded object lifecycle
Estimate: 7–11 person-days.
Implement:
- primary and scatter weapons;
- projectile data/pool and finite lifecycle;
- uniform-grid broadphase;
- swept projectile-circle collision;
- player/enemy contact and damage cooldown seam;
- canonical damage, armor, health, death, and reward events;
- pickups and transition convergence foundation;
- audio/VFX event streams with temporary cached test cues;
- gameplay/presentation budget diagnostics.
Acceptance gate:
- no tunneling at maximum supported speed;
- projectiles expire by impact/lifetime/range/cleanup;
- all damage paths resolve identically;
- post-warm-up hot path has no general heap allocation;
- headless and interactive checksums agree;
- 60-minute firing soak leaks nothing.
Relevant criteria: PROJ-AC-*, ARCH-AC-03, PERF-AC-02, PERF-AC-03.
25.5 Phase 3 — encounter director, spawning, and enemy roster
Estimate: 8–12 person-days.
Implement:
- encounter tokens and wave state machine;
- threat budgets and pacing segments;
- 16-sector heat/reservation system;
- predicted off-screen placement and pack formations;
- activation/arming states;
- catch-up/recycling and stall diagnostics;
- runner, shooter, splitter, charger, tank, kamikaze, and mini roles;
- directional surge and cross-angle events;
- local avoidance;
- elite modifier foundation;
- Monte Carlo and straight-line soak suites.
Acceptance gate:
- zero visible spawn violations in required Monte Carlo run;
- no off-screen attacks;
- straight-line waves complete without stragglers;
- all roles are readable and token-accounted;
- tank appears correctly through authored packs, avoiding the prototype's unreachable branch problem;
- wave 1–9 representative slice passes Stage B playtest.
Relevant criteria: SPWN-AC-*, ENMY-AC-*, WAVE-AC-02/03/06.
25.6 Phase 4 — campaign, perks, checkpoints, and UI
Estimate: 9–14 person-days.
Implement:
- all 29 standard-wave definitions and act pacing data;
- perk modifier/effect vocabulary;
- five milestone pools and Stage 10 multi-pick flow;
- all baseline perks;
- bounded proc behavior;
- wave-boundary checkpoints;
- full HUD, draft, pause, restart, and results RmlUi surfaces;
- edge indicators and accessibility controls;
- build and wave telemetry;
- definition/card consistency tests.
Acceptance gate:
- waves 1–29 run in correct sequence around boss placeholders;
- milestone selections and checkpoints match campaign framework;
- all perk combinations pass static/runtime budget tests;
- every perk visibly and textually matches behavior;
- RmlUi remains a model/command client, not gameplay authority;
- Stage C playtest identifies multiple viable build identities.
Relevant criteria: WAVE-AC-01, PERK-AC-*, UI-AC-*, DATA-AC-04/05.
25.7 Phase 5 — boss framework and four encounters
Estimate: 12–18 person-days.
Implement:
- lockfield formation, analytic boundary, zoom/framing, and dissolve;
- boss scheduler, phase data, pattern compatibility, safe-route tooling;
- Core;
- Omega;
- Apocalypse;
- Shadow including rapid fire, scatter, dash, teleport, slash, and interludes;
- boss checkpoints, music states, HUD, and transitions;
- boss pattern replay/test fixtures.
Suggested internal order:
- lockfield + Core to prove radial grammar;
- Omega to prove forces/fans;
- Shadow to prove mobile duel/interludes;
- Apocalypse to assemble campaign-scale pattern polish.
Acceptance gate:
- all boss criteria pass;
- movement/dash boundary behavior is stable;
- safe routes exist at baseline build;
- no mandatory perk dependency;
- restart/checkpoint reconstructs cleanly;
- Stage D playtest signs off lockfield and each boss identity.
Relevant criteria: BOSS-AC-*, BAL-AC-03, UI-AC-06, AUD-AC-03.
25.8 Phase 6 — visual, audio, and interaction polish
Estimate: 8–13 person-days.
Implement/refine:
- final geometry/material/shader presentation;
- stable marker motifs and act palette shifts;
- batched trails, rings, arcs, fragments, and fields;
- role/boss animations and telegraphs;
- VFX priority/degradation;
- complete cached SFX set, buses, coalescing, panning, and captions;
- music/stem integration;
- UI motion and card previews;
- color/readability/accessibility tuning;
- controller feedback where supported.
Acceptance gate:
- visual and audio acceptance criteria pass;
- no unlicensed reference assets remain;
- grayscale/color-vision and low-effects captures preserve gameplay information;
- warning voices survive saturation;
- Stage E full-run presentation feedback is coherent.
Relevant criteria: VIS-AC-*, AUD-AC-*, accessibility requirements.
25.9 Phase 7 — optimization, balancing, and hardening
Estimate: 10–16 person-days.
Implement/refine:
- CPU/GPU profiling and batching fixes;
- capacity reservation and zero-allocation verification;
- stress and long-run leak fixes;
- deterministic threading only where proven beneficial;
- campaign/boss balance passes;
- complete golden replays;
- resize/focus/device-loss/error recovery;
- checkpoint migration/failure policy;
- documentation and build/package surfaces;
- release configuration and final acceptance matrix.
Acceptance gate:
- baseline budgets and mandatory stress/soak pass;
- full campaign regression and replay suite passes;
- comparative boundless-versus-fixed validation supports the recommendation;
- all release-blocking criteria in Section 24.11 pass;
- risk register has no unmitigated high-impact item.
25.10 Work that must not precede the foundations
Do not begin by building:
- elaborate main menu/terminal presentation;
- multiple save slots;
- portrait/caption narrative sequences;
- GPU-only gameplay collision;
- procedural terrain or streamed world chunks;
- a general ability scripting VM;
- multiplayer synchronization;
- meta-progression;
- large quantities of decorative particles;
- all four bosses before damage, projectile, token, and lockfield foundations are proven.
Those activities would increase visible scope without reducing the central design risks.
25.11 Schedule decision gates
Gate A — boundless foundation
After Phase 1, reject the approach only if centered movement/grid/origin handling fails Section 2.4 criteria after documented tuning.
Gate B — encounter integrity
After Phase 3, boundless spawning and wave completion must pass fairness/straggler tests. Failure here is the strongest trigger for reconsidering the fixed arena.
Gate C — campaign viability
After Phase 4, representative Acts I–III must show sustainable pacing and perk differentiation before all boss polish is funded.
Gate D — boss compatibility
After the Core and Shadow implementations, the temporary lockfield must feel intentional and preserve the product's identity.
Gate E — final recommendation confirmation
Phase 7 A/B comparison determines whether the boundless version meaningfully improves movement and long-term structure. The default expectation is yes; evidence controls final sign-off.
26. Consolidated definition of done
The implementation is accepted as the specified PixelBullet Boundless Vector Arena when all of the following are true.
26.1 Product and loop
- A new run proceeds through waves 1–31 with bosses at 10, 20, 30, and 31.
- Perk milestones occur at 5, 10, 15, 20, and 25, with three Stage 10 selections.
- Standard waves permit unrestricted travel with a player-centered camera.
- Boss waves form and dissolve visible temporary lockfields.
- Wave-boundary checkpoints recover cleanly and are not presented as mid-wave saves.
- A complete successful run reaches the intended duration and pacing range after tuning.
26.2 Feel and clarity
- Movement has short, controlled inertia without sliding.
- Aim remains exact under movement, rendering interpolation, shake, resize, and boss zoom.
- Dash is useful in all directions and never fails due to a screen edge during standard waves.
- Shapes, motion, color, audio, and telegraphs make enemy roles legible.
- No ordinary enemy attacks before visible activation.
- No reviewed standard-difficulty death is caused by an unexplained off-screen or invisible threat.
26.3 Boundless-world integrity
- Logical travel is effectively unbounded for the campaign.
- Active simulation remains local and bounded.
- Integer chunks plus camera-relative floats preserve precision.
- Origin rebasing is visually and mechanically seamless.
- Grid and ambient markers remain coordinate-stable.
- Distance traveled does not increase memory, entity, draw, audio, or save-state size.
26.4 Encounter integrity
- Every standard wave has finite committed tokens and a defined pacing structure.
- Off-screen placement meets visibility-time rules.
- Sector heat and authored events vary approach direction without cheating.
- Irrelevant enemies catch up or recycle without rewards or lost progress.
- Waves cannot stall on invisible stragglers.
- Split descendants and elites respect token, threat, and entity caps.
26.5 Combat integrity
- All projectiles have finite lifetime/range and deterministic cleanup.
- Fast bullets use swept collision.
- All damage sources use one damage/death/reward path.
- Perk recursion, piercing, ricochet, healing, and projectile counts are bounded.
- Boss patterns are telegraphed, capped, and traversable.
- Player, enemy, projectile, and effect visuals align with collision.
26.6 Architecture
- Fixed 60 Hz authoritative simulation is decoupled from render rate.
- The product-owned headless adapter produces identical gameplay without renderer, UI, VFX, or audio.
- ECS systems have documented responsibilities and safe structural-change ordering.
- Vulkan renders repeated geometry through shared meshes/instances.
- DXC compiles the bounded HLSL shader set to SPIR-V through the engine pipeline. [R9]
- RmlUi consumes a presentation model and emits commands. [R7]
- miniaudio uses cached/in-memory SFX and streamed music with bounded voices. [R8]
- Jolt is not required for core 2D combat.
26.7 Quality and performance
- Automated unit, integration, replay, campaign, spawn, stress, and soak suites pass.
- Baseline CPU/GPU/UI/audio budgets pass at P95/P99 targets.
- Ordinary hot ticks allocate no general heap memory after warm-up.
- Quality degradation affects cosmetics before gameplay information.
- Accessibility controls preserve critical information.
- All content and assets have verified provenance.
- Risk register contains no unowned high-impact risk.
26.8 Final recommendation criterion
The boundless design remains the shipped recommendation when controlled comparison demonstrates:
- greater movement and dash expression;
- greater approach/composition variety;
- equal or acceptably close combat clarity;
- no increase in unexplained damage or wave stalls;
- positive player preference;
- acceptable engineering/performance cost.
If those conditions are not met after the specified systems and tuning—not merely after an incomplete implementation—the project should adopt the prior fixed-arena presentation while retaining the reusable damage, projectile, token, perk, UI, audio, and rendering architecture.
Appendix A. Godot reference interpretation
A.1 Use of the reference
The uploaded Godot project is treated as:
- a visual mood and proportion reference;
- proof that the basic weapon/enemy/perk/boss loop is promising;
- a source of initial timing and numeric relationships;
- evidence of intended wave/perk/boss ordering.
It is not treated as:
- a code architecture to translate;
- a physics model to retain;
- a scene organization requirement;
- a UI/front-end specification;
- a persistence model to reproduce;
- a source of automatically licensed assets.
The active combat is procedurally drawn and manually simulated, so the design can be detached cleanly from Godot.
A.2 Reference viewport and conversion
Reference viewport: 1600 × 900.
Initial conversion used in this specification:
1 WU = 64 reference pixels
reference visible size = 25.0 × 14.0625 WU
This preserves ratios while providing readable engine-scale values. It is a tuning baseline, not a requirement that PixelBullet expose pixels as gameplay units.
A.3 Reference player values
| Property | Godot reference | PixelBullet initial interpretation |
| Player radius | 16 px | 0.25 WU |
| Move speed | 280 px/s | 4.375 WU/s |
| Primary interval | 0.11 s | 0.11 s baseline |
| Primary projectile speed | 950 px/s | 14.84 WU/s |
| Primary spread | ±0.06 rad | retain as starting target |
| Scatter pellets | 6 | 6 baseline |
| Scatter spread | approximately ±0.35 rad plus jitter | retain/tune |
| Scatter speed | 850–1050 px/s | 13.28–16.41 WU/s |
| Scatter cooldown | 1.0 s | 1.0 s baseline |
| Dash duration | 0.15 s | 0.15 s |
| Dash speed multiplier | 2.8× | approximately 12.25 WU/s |
| Dash distance | 117.6 px | approximately 1.84 WU |
| Dash cooldown | 1.8 s | 1.8 s |
The reference uses immediate digital velocity. PixelBullet adds short acceleration/deceleration/reversal convergence because the world moves around a centered player, while preserving a crisp arcade response.
A.4 Reference enemy values
| Role | Radius | Speed | Health | Reference behavior retained |
| Runner | 0.1875 WU | 3.28 WU/s | 2 | direct pursuit |
| Shooter | 0.2344 WU | 2.19 WU/s | 3 | approach/hold around 4.06 WU and fire |
| Charger | 0.25 WU | 2.66 WU/s; 6.91 WU/s commit | 4 | wind-up and committed charge |
| Splitter | 0.2813 WU | 2.03 WU/s | 3 | spawns mini children |
| Tank | 0.375 WU | 1.41 WU/s | 8 | slow spatial anchor |
| Kamikaze | 0.1719 WU | 5.0 WU/s | 1 | fast pulsing contact threat |
| Mini-splitter | 0.125 WU | 3.44 WU/s | 1 | simple child pursuit |
The reference's ordinary wave random branch makes the tank effectively unreachable because broader earlier conditions consume the qualifying range. PixelBullet uses explicit pack tables and quotas, eliminating ordering bugs of that kind.
A.5 Reference progression retained
- standard wave progression through 31;
- bosses at 10, 20, 30, and 31;
- perk stages at 5, 10, 15, 20, and 25;
- three selections at Stage 10;
- approximately three-second intermissions;
- directional surge concept;
- Core, Omega, Apocalypse, and Shadow identities;
- health, armor, pickups, score, dash, primary, and scatter verbs.
A.6 Reference behavior deliberately changed
| Reference behavior | PixelBullet decision | Reason |
| Player clamped to 1600×900 screen | Boundless standard waves | Stronger movement and sustainable encounter flow |
| Camera effectively fixed | Exact player-centered logical camera | Required by boundless proposal |
| Enemies spawned at screen borders | Validated off-screen annulus with arming | Fairness under moving camera |
| Bullets removed mainly by leaving viewport | TTL + range + active-region cleanup | Boundless lifetime safety |
| Wall ricochet perk | nearest-target Vector Ricochet | No standard-wave walls |
| 10 + wave * 5 population formula | threat-token budgets and pacing | Avoid raw density/repetition |
| Multiple manual damage/death paths | canonical damage/death/proc events | Correct rewards and composition |
| Per-event procedural PCM creation | cached/generative-once cues and voice pool | Performance and consistency |
| Save reconstructs current wave but appears general | explicit wave-boundary checkpoint | Accurate product semantics |
| Bosses rely on screen clamp | temporary diegetic lockfields | Preserve authored patterns in boundless game |
| Shadow interlude every ~15% | three authored interludes | Better pacing and less repetition |
A.7 Reference visual palette
Approximate intent, to be calibrated in PixelBullet's color pipeline:
- background: near-black navy;
- grid: very low-alpha cool gray/blue;
- player: cyan with white aim/weapon detail;
- player projectiles: gold/yellow;
- hostile projectiles: crimson;
- runner: magenta;
- shooter: lime/green;
- charger: orange;
- splitter: turquoise;
- tank: violet;
- kamikaze: yellow;
- bosses: increasingly large red/violet/orange cores with white inner diamond;
- Shadow: cyan and magenta.
The palette is semantic, not a mandate to copy exact sRGB constants.
Appendix B. Initial tuning constants
These values collect starting targets from the specification. They belong in data/configuration and are expected to change through tuning.
B.1 Simulation and camera
| Constant | Initial value |
| Fixed tick | 60 Hz |
| Reference view | 25.0 × 14.0625 WU |
| Boss view | approximately 32 × 18 WU |
| World chunk size | 256 WU |
| Rebase trigger | 64 WU from local origin |
| Rebase alignment | 32 WU |
| Minor grid | 0.78125 WU |
| Player radius | 0.25 WU |
| Player max speed | 4.375 WU/s |
| Acceleration to 95% | ≤0.08 s |
| Deceleration to stop | ≤0.06 s |
| Full reversal | ≤0.10 s |
| Dash duration | 0.15 s |
| Dash distance | approximately 1.84 WU |
| Dash cooldown | 1.8 s |
B.2 Spawn and relevance
| Constant | Initial value |
| Angular sectors | 16 |
| Static off-screen margin | 1.5 WU |
| Spawn band width | 4–6 WU |
| Ordinary reaction floor | 0.65–0.80 s |
| Charger reaction floor | 1.00 s |
| Kamikaze reaction floor | 1.10 s |
| Surge telegraph | 0.6–0.9 s |
| Soft relevance extra radius | 8 WU beyond view circumradius |
| Hard relevance extra radius | 18 WU |
| Absolute guard extra radius | 24 WU |
| Outside-soft recycle dwell | 4–6 s |
| Token recycle limit | 3 |
B.3 Projectile and effects
| Constant | Initial value |
| Primary speed | 14.84 WU/s |
| Primary lifetime | 1.55 s |
| Primary max range | 22.5 WU |
| Scatter speed | 13.28–16.41 WU/s |
| Scatter lifetime | 0.70–0.85 s |
| Scatter max range | 10.5–13 WU |
| Hostile ordinary lifetime | 2.5–3.25 s |
| Max projectile impacts/tick | 8 |
| Chain radius | 1.72 WU |
| Chain damage | 3.5 initial |
| Chain max generation | 2 |
| Ricochet target radius | 4.5 WU |
| Stasis radius | 2.5 WU |
| Scatter pellet hard cap | 24 |
| Proc spawn cap/root event | 64 projectile effects |
B.4 Boss field
| Constant | Initial value |
| Ordinary field radius | 8 WU |
| Shadow field radius | 9 WU |
| Formation time | 0.8 s |
| Inner warning band | 0.5 WU |
| Core health | 350 |
| Omega health/armor | 750 / 200 |
| Apocalypse health | 1,000 |
| Shadow health/final armor | 600 / 135 |
B.5 Budgets
| Constant | Initial value |
| Active enemies | 350 normal, 500 special guard |
| Gameplay projectiles | 2,500 preferred, 3,000 absolute campaign guard |
| Pickups | 128 |
| Gameplay fields | 64 |
| VFX instances | 8,000 normal quality |
| Audio one-shot voices | 32 plus music |
| Damage events/tick guard | 8,192 |
Appendix C. Requirement traceability matrix
| User-requested area | Primary sections |
| Recommendation and rationale | 1, 2, 26 |
| Core goals and pillars | 3, 4 |
| Complete gameplay loop | 5, 13 |
| Movement, input, inertia, camera | 7, 8, 23, 24 |
| World-space/coordinate strategy | 9, 21, 23 |
| Enemy spawning/activation/despawning/distribution | 10, 11 |
| Projectile lifetime/range/cleanup/performance | 12, 22 |
| Wave progression/pacing | 13, 16 |
| Boss structure/arena | 15 |
| Difficulty/balance | 16 |
| Visual design | 17, Appendix A |
| UI/feedback | 18 |
| Audio/effects | 19 |
| Technical architecture | 20 |
| Data/configuration | 21 |
| Performance/scalability/object management | 22 |
| Edge cases/failure states/risks | 23 |
| Testing/validation | 24 |
| Phased implementation | 25 |
| Acceptance criteria | Sections 7–26 and consolidated Section 26 |
Appendix D. Research references
The research informs the implementation principles; it does not replace project-specific validation.
[R1] Valve — “The AI Systems of Left 4 Dead,” Mike Booth, 2009. Procedural population, bounded active area, replayability, structured unpredictability, and dramatic pacing. https://steamcdn-a.akamaihd.net/apps/valve/2009/ai_systems_of_l4d_mike_booth.pdf
[R2] Unity Technologies — Cinemachine Position Composer documentation, 3.1.7. Dead/soft zones, damping as camera-response lag, and look-ahead jitter sensitivity. https://docs.unity3d.com/Packages/com.unity.cinemachine%403.1/manual/CinemachinePositionComposer.html
[R3] Glenn Fiedler — “Fix Your Timestep!” Fixed-step simulation, render/simulation decoupling, frame-time sensitivity, and catch-up headroom. https://gafferongames.com/post/fix_your_timestep/
[R4] Godot Engine documentation — “Large world coordinates.” Floating-point precision at distance, double-precision trade-offs, and origin-shifting alternative. https://docs.godotengine.org/en/stable/tutorials/physics/large_world_coordinates.html
[R5] Box2D documentation — “Simulation,” bullets and continuous collision detection. Sweeping old-to-new transforms and time-of-impact handling to prevent tunneling. https://box2d.org/documentation/md_simulation.html
[R6] Khronos Vulkan Documentation Project — “Instancing” sample. Rendering many instances of shared geometry with variable per-instance parameters. https://docs.vulkan.org/samples/latest/samples/api/instancing/README.html
[R7] RmlUi documentation — “Data binding.” Model-view-controller data binding and dirty-variable updates. https://mikke89.github.io/RmlUiDoc/pages/data_bindings.html
[R8] miniaudio manual — high-level API and resource management. Shared resource loading, in-memory decoding, streaming, asynchronous loading, and reference counting. https://miniaud.io/docs/manual/index.html
[R9] Microsoft DirectX Shader Compiler — SPIR-V CodeGen documentation. HLSL-to-SPIR-V mapping and Vulkan-targeted compilation. https://github.com/microsoft/DirectXShaderCompiler/blob/main/docs/SPIR-V.rst
Closing design decision
The fixed screen is the safer implementation, but it is not the stronger long-term design for this concept. The boundless, player-centered structure creates more meaningful movement, keeps dash useful, supports richer arrival geometry, avoids permanent corner behavior, and demonstrates reusable PixelBullet systems that the existing representative-surface suite does not yet exercise together.
The design succeeds by remaining disciplined:
- the world is unbounded logically but local computationally;
- the camera is centered but not lagged;
- projectiles are finite;
- enemies enter fairly, activate visibly, and recycle without cheating;
- waves retain authored progression and finite threat;
- bosses temporarily create the space their patterns require;
- presentation is rich but gameplay remains geometrically legible;
- every subsystem has measurable acceptance criteria.
On those terms, Boundless Vector Arena is the recommended PixelBullet implementation baseline.