Document collision, and correct what it made false elsewhere
The new chapter 15 covers the opt-in setup, where resolution runs in the step and why it runs after the move, shapes and the z-extrusion trap, the asymmetric masks and the defaults that matter more than the mechanism, tiles as a source rather than proxies, the response hook and the three ways it is easy to write wrongly, sensors, the four queries, both partitioners, and what is still not implemented. Collision falsified claims in eight other chapters. The physics chapter said "There is no collision detection, at all" and that collide always raises AKERR_API; actors had six behaviour hooks; the heap had five pools and four non-claiming acquires; the status band held five codes; and the design philosophy had exactly two pluggable subsystems. The appendix gains a collision.h status section, the three new pool ceilings and a table of the collision constants that are deliberately not in a public header. Also fixes chapter labels the renumbering commit left pointing at their old numbers -- "18. Utilities" linked to 19-utilities.md. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KzBDV2fqgnUAcqCKqKvc71
This commit is contained in:
@@ -278,10 +278,11 @@ the actors already processed advanced and the rest not.
|
||||
/*
|
||||
* A movement logic function that pins an actor to a floor at y = 400.
|
||||
*
|
||||
* The arcade backend never calls collide and never consults the tilemap, so
|
||||
* standing on something is the caller's job. Doing it here rather than after
|
||||
* the step is what keeps the actor from being drawn inside the floor for one
|
||||
* frame.
|
||||
* With no collision world attached the backend consults nothing, so standing
|
||||
* on something is the caller's job. Doing it here rather than after the step is
|
||||
* what keeps the actor from being drawn inside the floor for one frame. A game
|
||||
* that attaches a world (Chapter 15) deletes this function instead of writing
|
||||
* it.
|
||||
*/
|
||||
akerr_ErrorContext AKERR_NOIGNORE *stand_on_floor(akgl_Actor *obj, float32_t dt)
|
||||
{
|
||||
@@ -318,23 +319,13 @@ akerr_ErrorContext AKERR_NOIGNORE *frozen_in_cutscene(akgl_Actor *obj, float32_t
|
||||
Stated plainly, because all of it is reachable by an ordinary-looking call and none of it
|
||||
announces itself at compile time.
|
||||
|
||||
**There is no collision detection, at all.**
|
||||
**Collision is [Chapter 15](15-collision.md), and it is opt-in.** A backend with no
|
||||
collision world attached does exactly what it did before collision existed: `move` is
|
||||
`position += velocity * dt` and consults nothing. Attach a world and the step resolves after
|
||||
every sub-move.
|
||||
|
||||
- `akgl_physics_arcade_collide` always raises `AKERR_API` with the message "Not
|
||||
implemented". It is deliberately loud rather than silently permissive.
|
||||
- **`akgl_physics_simulate` never calls `collide`.** Not for the arcade backend, not for
|
||||
the null one, not ever. The vtable slot exists and the simulation does not use it.
|
||||
- `akgl_physics_arcade_move` does `position += velocity * dt` and nothing else. It does not
|
||||
clamp to the map, consult the tilemap, or test anything. **An actor walks straight
|
||||
through a wall and off the edge of the world.**
|
||||
|
||||
`akgl_physics_null_collide` *succeeds*, and that is not an oversight: the null backend's
|
||||
contract is "nothing collides", which is an answer. The arcade one means "nobody has
|
||||
written this yet", and a caller who reaches it should find out.
|
||||
|
||||
Until it exists, collision belongs in your `movementlogicfunc`, as in the example above.
|
||||
The sidescroller tutorial in [Chapter 20](20-tutorial-sidescroller.md) does exactly that and
|
||||
says why. `akgl_collide_*` in [Chapter 19](19-utilities.md) gives you the rectangle tests.
|
||||
What remains missing here is the *feel*, below, and that is a different list from the one
|
||||
this section used to carry.
|
||||
|
||||
### Four gaps in the feel
|
||||
|
||||
@@ -358,9 +349,10 @@ clear either — `simulate` recomputes `v` as `e + t` every step.
|
||||
## Statuses
|
||||
|
||||
`akgl_physics_simulate` propagates whatever an actor's `movementlogicfunc`, or the
|
||||
backend's `gravity` or `move`, raises, and **the first failure aborts the whole step** —
|
||||
backend's `gravity`, `move` or `collide`, raises, and **the first failure aborts the whole
|
||||
step** —
|
||||
the actors already processed are advanced and the rest are not. The status meanings are in
|
||||
[Chapter 4](04-errors.md); the ones you will meet here are `AKERR_NULLPOINTER` (a `NULL`
|
||||
`self` or `self->move`), `AKERR_API` (`collide`, always), `AKERR_VALUE` and `ERANGE` (a
|
||||
`self` or `self->move`), `AKERR_VALUE` and `ERANGE` (a
|
||||
`physics.*` property that is not a number, or does not fit a `double`), and
|
||||
`AKGL_ERR_LOGICINTERRUPT`, which is not a failure.
|
||||
|
||||
Reference in New Issue
Block a user