Swept narrowphase for fast movers: AKGL_COLLISION_FLAG_BULLET does nothing #56

Open
opened 2026-08-02 18:33:42 -04:00 by tachikoma · 0 comments
Collaborator

Source: TODO.md, "Swept narrowphase for fast movers" (at bbb7b8f)

AKGL_COLLISION_FLAG_BULLET is defined, documented as reserved, and does
nothing.

Sub-stepping bounds how far an actor travels between tests, and it is capped at
AKGL_COLLISION_MAX_SUBSTEPS (8) sub-steps of at most
AKGL_COLLISION_SUBSTEP_FRACTION (0.5) of a cell, so the speed above which
tunnelling returns is:

    v_max = substeps * fraction * cellsize / max_timestep
          = 8 * 0.5 * 16 / 0.05
          = 1280 px/s        on 16-pixel tiles at the default max_timestep

Check your own numbers against that: a game with 8-pixel tiles halves it, and a
game that raises physics.max_timestep lowers it proportionally. A walking
character is nowhere near it; a projectile is a projectile.

The fix is a swept test rather than more sub-steps -- sweeping the shape's
AABB over the sub-step's motion, testing that, and resolving at the time of first
contact rather than at the end position.

It belongs behind the flag so it is paid for only by the shapes that need it,
which is what the flag was reserved for.

Files: src/collision.c, include/akgl/collision.h


Filed by Tachikoma (Claude Code, Opus 5, 1M context)

**Source:** TODO.md, "Swept narrowphase for fast movers" (at bbb7b8f) `AKGL_COLLISION_FLAG_BULLET` is defined, documented as reserved, and **does nothing.** Sub-stepping bounds how far an actor travels between tests, and it is capped at `AKGL_COLLISION_MAX_SUBSTEPS` (8) sub-steps of at most `AKGL_COLLISION_SUBSTEP_FRACTION` (0.5) of a cell, so the speed above which tunnelling returns is: ``` v_max = substeps * fraction * cellsize / max_timestep = 8 * 0.5 * 16 / 0.05 = 1280 px/s on 16-pixel tiles at the default max_timestep ``` Check your own numbers against that: a game with 8-pixel tiles halves it, and a game that raises `physics.max_timestep` lowers it proportionally. A walking character is nowhere near it; **a projectile is a projectile.** **The fix is a swept test rather than more sub-steps** -- sweeping the shape's AABB over the sub-step's motion, testing that, and resolving at the time of first contact rather than at the end position. It belongs behind the flag so it is paid for only by the shapes that need it, which is what the flag was reserved for. **Files:** `src/collision.c`, `include/akgl/collision.h` --- Filed by Tachikoma (Claude Code, Opus 5, 1M context)
tachikoma added this to the 1.0.0 milestone 2026-08-02 18:33:42 -04:00
tachikoma added the api-gapblast-radius:medium labels 2026-08-02 18:33:42 -04:00
tachikoma added the status::grooming label 2026-08-02 18:49:25 -04:00
Sign in to join this conversation.