Skip to main content

Actors and Collisions

Actor.h

Header: core/src/Actor/Actor.h

PhysicsMode

ValueMeaning
HIGH_PERFFast correction against the first blocking collision.
BALANCEDChecks nearby blockers before resolving movement.
HIGH_FIDELITYSplits movement into smaller balanced steps.

Actor

FieldTypeMeaning
typeActorTypeGenerated actor kind.
tagsTags[5]Tags used by scene queries and collision filters.
current_animationAnimation*Current animation, or NULL.
animation_stateAnimationState*Animation playback state, or NULL.
x, yuint16_tWorld position, using subpixel coordinates with a ratio of 16:1.
colliderCollider*Optional owned collider.
childActor*First child in the actor hierarchy.
siblingActor*Next sibling in the actor hierarchy.
parentActor*Parent actor, if any.
physics_modePhysicsModeMovement collision mode.
followeduint8_tNonzero when the camera follows this actor.
pending_removaluint8_tInternal flag set when removal must wait for the current actor or collision pass to finish.

Globals

NameTypeMeaning
THIS_ACTORActor*Actor used by the current actor function.

Functions

FunctionDescription
void set_tag(Tags tag, uint8_t index) BANKED;Writes a tag into THIS_ACTOR->tags[index] when index < 5.
void set_actor_animation(Animation* animation) NONBANKED;Replaces the current animation and its playback state.
void move_actor(int16_t dx, int16_t dy) BANKED;Moves THIS_ACTOR and its children using physics_mode.
void set_actor_position(uint16_t x, uint16_t y) BANKED;Moves THIS_ACTOR and its children to a new position. Check Coordinate model for important notes on absolute movement.
void attach_child(Actor* child) BANKED;Appends child to the end of THIS_ACTOR's child list.
void detach_child(Actor* child) BANKED;Removes child from THIS_ACTOR's child list.
void set_collider(Collider* collider) BANKED;Replaces the current collider, records THIS_ACTOR in collider->parent, and enables it. The new collider starts with no callbacks, so add them after attaching it.

Behavior notes

  • Actors own their colliders. Replacing or destroying an actor frees the collider it holds.
  • Destroying an actor detaches it from its parent and leaves its children alive as independent scene actors.
  • Movement also applies to child actors.
  • An axis-aligned move on a childless actor with no blocking collider uses a short path. Both horizontal and vertical variants preserve the moved axis's map bound and collider synchronization; diagonal, zero-delta, hierarchy, and blocking-physics cases use the full path.
  • Scene map bounds are cached by set_scene_map(). Use that function to replace a scene map instead of assigning THIS_SCENE->map directly.
  • An axis-aligned short path assumes the unchanged coordinate is already valid. Use set_actor_position() or move_actor(0, 0) if project code has deliberately placed the actor beyond the other map bound and needs both axes clamped.

ActorRegistry.h

Header: core/src/Actor/ActorRegistry.h

Generated macro list

NameMeaning
ACTORSActor type list generated into a managed block in ActorRegistry.h. The default placeholder is empty.
ACTOR_TAGSProject tag list generated into a managed block in ActorRegistry.h and consumed by the Tags enum. The default placeholder is empty.

ActorType

Default value in the shipped core:

  • NUM_ACTORS

Project code generation adds real actor type entries before NUM_ACTORS.

Tags

Default value in the shipped core:

  • TAG_NONE

Projects extend this enum and reuse it for actor tags and collider tags.

Functions

FunctionDescription
struct Actor* create_actor(ActorType type) BANKED;Allocates the concrete actor struct for type, sets actor->type, temporarily sets THIS_ACTOR while calling the actor init function, restores the previous THIS_ACTOR, and returns the new actor as Actor*. Returns NULL for invalid types or allocation failure.

Creating actors from scripts

Use create_actor() instead of manually allocating an actor. Actor scripts may extend the base Actor struct, so the registry factory is responsible for using the correct sizeof(...).

Actor* enemy = create_actor(_Enemy);
if(enemy != NULL){
Actor* previous_actor = THIS_ACTOR;
THIS_ACTOR = enemy;
set_actor_position(80 * 16, 40 * 16);
add_actor(enemy);
THIS_ACTOR = previous_actor;
}

create_actor() sets THIS_ACTOR only while the actor init function runs. If you need helper functions such as set_actor_position() to target the returned actor, save the current THIS_ACTOR, assign the new actor, then restore the saved value afterwards. Once added, the current scene owns the actor and will destroy it during scene cleanup.

Collider.h

Header: core/src/Collisions/Collider.h

CollisionCallback

typedef FAR_PTR CollisionCallback;

Inside a callback, use THIS_COLLIDER and OTHER_COLLIDER to inspect the collision pair. Each collider exposes its owning actor through parent, so callbacks can use THIS_COLLIDER->parent and OTHER_COLLIDER->parent without searching the scene.

Collider

FieldTypeMeaning
x, yuint16_tWorld position.
typeuint8_tCollider kind, usually from ColliderType.
iduint8_tActive collision slot.
is_blockinguint8_tNonzero when the collider blocks movement.
width, heightuint16_tCollider bounds.
tagsTags[5]Five tag slots used by filtered collision queries.
on_collisionCollisionCallback[MAX_COLLISION_CALLBACKS]Collision callbacks.
on_collision_exitCollisionCallback[MAX_COLLISION_CALLBACKS]Exit callbacks.
num_collision_callbacksuint8_tNumber of valid collision callbacks.
num_collision_exit_callbacksuint8_tNumber of valid exit callbacks.
parentstruct Actor*Owning actor assigned by set_collider(). May be NULL for an unattached collider.
pending_disableuint8_tInternal flag set when structural removal from the active-collider list is deferred.

Globals

NameTypeMeaning
THIS_COLLIDERCollider*Active collider for the current check or callback.
OTHER_COLLIDERCollider*Other collider in the current check or callback.

BoxCollider.h

Header: core/src/Collisions/BoxCollider.h

BoxCollider

FieldTypeMeaning
baseColliderEmbedded collider base record.

This is the only collider shape currently supported.

CollisionManager.h

Header: core/src/Collisions/CollisionManager.h

Functions

FunctionDescription
void enable_collider(Collider* collider) BANKED;Cancels a pending disable, returns if the collider is already active, or adds an inactive collider to the active list.
void disable_collider(Collider* collider) BANKED;Immediately removes an active collider. Do not call it while the collision manager is iterating callbacks.
void disable_collider_deferred(Collider* collider) BANKED;Logically disables a collider immediately and queues its physical removal for the next Game Manager safe point.
void set_collision_callback(Collider* collider, CollisionCallback callback) BANKED;Appends a collision callback if there is capacity.
void set_collision_exit_callback(Collider* collider, CollisionCallback callback) BANKED;Appends an exit callback if there is capacity.
void check_collisions(Collider* out[], uint8_t max_collisions, uint8_t* num_collisions) BANKED;Collects colliders overlapping THIS_COLLIDER.
void check_collisions_with_tags(Collider* out[], uint8_t max_collisions, uint8_t* num_collisions, Tags tag) BANKED;Same as check_collisions(), but only for colliders carrying tag.
void check_blocking_collisions(Collider* out[], uint8_t max_collisions, uint8_t* num_collisions) BANKED;Collects blocking colliders overlapping THIS_COLLIDER.
void check_blocking_collisions_with_tags(Collider* out[], uint8_t max_collisions, uint8_t* num_collisions, Tags tag) BANKED;Same as check_blocking_collisions(), but only for colliders carrying tag.

Behavior notes

  • Active colliders are capped by MAX_ACTIVE_COLLIDERS.
  • Callback arrays are capped by MAX_COLLISION_CALLBACKS.
  • Collision query functions only collect overlaps. Collision and exit callbacks are dispatched by run_collision_callbacks(), which is called from update_game() when COLLISION_CALLBACKS_EVERY_FRAME is enabled.
  • Use disable_collider_deferred() from collision and exit callbacks. The collider is skipped immediately and removed from the compact active list at the next Game Manager safe point. Once either collider is marked disabled, remaining callbacks for that pair do not run.
  • Call remove_actor_deferred(), rather than remove_actor() or destroy_actor(), when removing a scene actor from a callback. Immediate removal, direct destruction, and collider replacement must not be done while collision callbacks are running.
  • Enabling a previously inactive collider is not deferred. Do it before or after the collision callback pass. Enabling an active collider with a pending deferred disable cancels that disable without registering the collider twice.

ColliderRegistry.h

Header: core/src/Collisions/ColliderRegistry.h

Constants

NameValueMeaning
MAX_ACTIVE_COLLIDERS20Maximum active colliders.
MAX_COLLISION_CALLBACKS4Maximum callbacks stored per enter or exit array.
MAX_COLLISION_STATE_BYTES(((MAX_ACTIVE_COLLIDERS * MAX_ACTIVE_COLLIDERS) + 7) / 8)Storage for active collision pairs.

ColliderType

ValueMeaning
BOX_COLLIDERAxis-aligned box collider.
NUM_COLLIDERNumber of collider kinds.