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:
@@ -25,7 +25,7 @@ The house rules for *writing* code against the protocol — never a `*_RETURN` i
|
||||
|
||||
libakerror reserves statuses 0–255 for the host's `errno` values and its own `AKERR_*`
|
||||
codes; consumers allocate upward from `AKERR_FIRST_CONSUMER_STATUS`, which is **256**.
|
||||
libakgl claims a band of five starting there, under the owner string `"libakgl"`:
|
||||
libakgl claims a band of six starting there, under the owner string `"libakgl"`:
|
||||
|
||||
```c excerpt=include/akgl/error.h
|
||||
#define AKGL_ERR_OWNER "libakgl"
|
||||
@@ -36,12 +36,13 @@ libakgl claims a band of five starting there, under the owner string `"libakgl"`
|
||||
#define AKGL_ERR_HEAP (AKGL_ERR_BASE + 2) /**< A heap pool has no free object left to hand out */
|
||||
#define AKGL_ERR_BEHAVIOR (AKGL_ERR_BASE + 3) /**< A component did not behave the way its contract requires */
|
||||
#define AKGL_ERR_LOGICINTERRUPT (AKGL_ERR_BASE + 4) /**< Actor logic is telling the physics simulator to skip it */
|
||||
#define AKGL_ERR_COLLISION (AKGL_ERR_BASE + 5) /**< A collision query could not be answered; the message says why */
|
||||
```
|
||||
|
||||
**`AKGL_ERR_LIMIT` is not a status code.** It is `AKGL_ERR_BASE + 5`, one past the last
|
||||
**`AKGL_ERR_LIMIT` is not a status code.** It is `AKGL_ERR_BASE + 6`, one past the last
|
||||
one, and exists only so `AKGL_ERR_COUNT` can be computed from it. Nothing in `src/` raises
|
||||
it and `akgl_error_init` does not name it. Do not write a `HANDLE(e, AKGL_ERR_LIMIT)`
|
||||
arm — it would catch nothing, and if a sixth real code is ever added it would silently
|
||||
arm — it would catch nothing, and if a seventh real code is ever added it would silently
|
||||
start catching that instead.
|
||||
|
||||
| Code | Value | Means | Raised by | What the caller does |
|
||||
@@ -51,10 +52,11 @@ start catching that instead.
|
||||
| `AKGL_ERR_HEAP` | 258 | A pool has no free slot | every `akgl_heap_next_*` | **Normally a missing release, not a small pool.** See [Chapter 5](05-the-heap.md) before raising `AKGL_MAX_HEAP_*` |
|
||||
| `AKGL_ERR_BEHAVIOR` | 259 | A component did not behave the way its contract requires | **Nothing in the library.** Only `tests/` raises it, through `testutil.h` | Available to you for the same purpose: asserting a contract in your own code |
|
||||
| `AKGL_ERR_LOGICINTERRUPT` | 260 | **Not a failure — a control signal.** "Skip the rest of this step for this actor" | your own `movementlogicfunc` | Raise it deliberately. See the note below |
|
||||
| `AKGL_ERR_COLLISION` | 261 | A collision query could not be answered | **One cause only**: `akgl_collision_test`, when the ccd arena is exhausted. The message carries the high-water mark | Raise `AKGL_CCD_ARENA_BYTES` to the reported figure. See [Chapter 15](15-collision.md) |
|
||||
|
||||
`akgl_error_init` reserves the band all-or-nothing and registers a name for each of the
|
||||
five: `"SDL Error"`, `"Registry Error"`, `"Heap Error"`, `"Behavior Error"`,
|
||||
`"Logic Interrupt"`. Those names are what a stack trace prints.
|
||||
six: `"SDL Error"`, `"Registry Error"`, `"Heap Error"`, `"Behavior Error"`,
|
||||
`"Logic Interrupt"`, `"Collision Error"`. Those names are what a stack trace prints.
|
||||
|
||||
Two rows deserve more than a cell.
|
||||
|
||||
@@ -87,7 +89,7 @@ grepping every `FAIL_*` and `HANDLE*` site in `src/`, not by reading header pros
|
||||
| `AKERR_OUTOFBOUNDS` | A value did not fit its destination, or an index ran off the end. `aksl_strncpy` truncation, an array index past the end of a JSON array (`akgl_get_json_array_index_*`), a ninth child on an actor, a tile past `AKGL_TILEMAP_MAX_*`, a control map id out of range |
|
||||
| `AKERR_VALUE` | A value parsed but was not usable: a version string that is not semver (`akgl_game_load_versioncmp`), two surfaces that differ (`akgl_compare_sdl_surfaces`), a zero-sized destination or an overlapping copy from the `aksl_` wrappers |
|
||||
| `AKERR_RELATIONSHIP` | **One site**: `akgl_actor_add_child`, when the child already has a parent. Detach it first |
|
||||
| `AKERR_API` | Two distinct meanings, so read the message. (1) **The function is not implemented** — `akgl_physics_arcade_collide` and `akgl_render_2d_draw_mesh` both `FAIL_RETURN(..., AKERR_API, "Not implemented")`, and both are reached by ordinary-looking calls. (2) **A savegame does not match this build** — `akgl_game_load` and `akgl_game_load_versioncmp` |
|
||||
| `AKERR_API` | Two distinct meanings, so read the message. (1) **The function is not implemented** — `akgl_render_2d_draw_mesh` does `FAIL_RETURN(..., AKERR_API, "Not implemented")`, and it is reached by an ordinary-looking call. (2) **A savegame does not match this build** — `akgl_game_load` and `akgl_game_load_versioncmp` |
|
||||
| `AKERR_IO` | A read or write failed, or a savegame had trailing data after its name tables. Distinct from `AKERR_EOF` — that separation is the whole reason `aksl_fgetc` exists |
|
||||
| `AKERR_EOF` | End of input. Sometimes the *desired* outcome: `require_at_eof` in `src/game.c` handles it and treats anything else as a failure |
|
||||
| `AKERR_INDEX` | **libakgl never raises this.** It appears once, as a `HANDLE_GROUP` arm in `akgl_get_json_with_default`, so that a caller whose *own* code raises it still gets a default. An out-of-range JSON array index arrives as `AKERR_OUTOFBOUNDS` |
|
||||
@@ -122,7 +124,7 @@ status yourself. If you do either, call `akerr_exit()`.
|
||||
|
||||
### `akgl_error_init()` must run before anything that can raise
|
||||
|
||||
`akgl_error_init` claims the status band *and* registers the five names. A code raised
|
||||
`akgl_error_init` claims the status band *and* registers the six names. A code raised
|
||||
before it runs has no name in the registry, so every stack trace carrying it prints
|
||||
**"Unknown Error"** instead of "Heap Error" — and the status number, 258, means nothing to
|
||||
a reader.
|
||||
|
||||
Reference in New Issue
Block a user