SubItem API¶
SubItem is the visual and animation layer used by every active object. Players, enemies, characters, and items all inherit these fields through flattening.
Free item/subitem slots can be initialized with
initialize(pack_name, entity_name, animation_id, mode = 2). Player/enemy slots
and occupied slots are rejected. Helpers created during a cinematic are removed
when it ends; see Script-owned cinematics.
Identity And Visual State¶
| Property | Type | Read/Write | Detail |
|---|---|---|---|
name |
string |
read | Internal entity name. Exact bridge name is Name. |
classic_name |
string |
read | Name of the Classic entity this one behaves as, followed through its logic references: "Pipe" for a mod's bat that references Classic Pipe. nil when it has no Classic base. Use it to tell weapon kinds apart. |
is_throw_only_weapon |
bool |
read | The item's own logic.json sets throwOnlyWeapon: a weapon that is only thrown, never swung or stabbed. |
is_melee_only_weapon |
bool |
read | The item's own logic.json sets meleeOnlyWeapon: a weapon that is never thrown. |
is_breakable_weapon |
bool |
read | The item's own logic.json names a brokenWeapon: it breaks into that entity on its first hit. |
thrown_damage |
int |
read | Damage the item deals when it hits as a projectile: its logic projectileDamage, followed through logic references. |
pack_name |
string |
read | Content pack name resolved from the pack hash. |
pack_hash |
int |
read | Runtime hash for the current pack. Exact bridge name is PackHash. |
is_enabled |
bool |
read | True when the slot exists. Exact bridge name is IsEnabled. |
object_index |
int |
read | Global object ID for this object. Exact bridge name is ObjectIndex. |
entity_type |
int |
read/write | Runtime hash or type ID for the entity. |
palette_pack |
int |
read/write | Pack hash for palette lookup. |
palette_line |
int |
read/write | Palette row/index. |
ignore_rendering |
bool |
read/write | When true, the animation updater does not advance frame progress through the normal rendered path. |
custom_z_order |
int |
read/write | Manual render depth in raw engine 16.16 units. Unlike Lua position/screen-position fields, this field does not divide by PositionMultiplier (1000). For a Lua ground coordinate, assign ground * 1000. |
Animation And Facing¶
| Property | Type | Read/Write | Detail |
|---|---|---|---|
is_facing_right |
bool |
read/write | Main facing flag. Changes hitbox orientation, forward/backward input interpretation, and spawn direction. |
direction_signal |
int |
read | 1 when facing right, -1 when facing left. |
object_mode |
int |
read/write | Behaviour mode used by original and reference controllers. For many player standing states, 2 returns to active standing logic. |
current_animation_id |
int |
read/write | Editor-facing animation ID. Internally stored doubled. Prefer set_animation for transitions. |
current_animation_frame |
int |
read/write | Current animation logic frame. Advanced after movement scripts run. |
next_animation_id |
int |
read/write | Queued animation ID. The animation controller copies it into current animation later. |
next_animation_frame |
int |
read/write | Start frame used when the animation ID changes, or when the current animation loops. Setting this alone does not seek an animation already playing. |
is_animation_over |
bool |
read/write | Read checks whether the current frame has reached the animation duration. Writing true finishes the animation. Writing false has no effect. |
referenced_object_id |
int |
read/write | Generic linked object ID used by some behaviours. |
Screen Position¶
| Property | Type | Read/Write | Detail |
|---|---|---|---|
screen_position_x |
int |
read/write | Screen X in script units. Internally scaled by 1000. |
screen_position_y |
int |
read/write | Screen Y in script units. Internally scaled by 1000. |
Generic Script State¶
| Property | Type | Read/Write | Detail |
|---|---|---|---|
custom_value_1 through custom_value_10 |
int |
read/write | Per-object script storage. Use for timers, mode selectors, one-shot flags, and stored object IDs. |
Read and write these through named properties, such as e.custom_value_1.
Bracket access such as e["custom_value_1"] uses the native entity indexer and
does not read that property. For indexed storage helpers, use a table of
functions that access the named properties explicitly.
Position changes after physics¶
A scene post-update script runs after character physics has cached screen_position_x/y for rendering. When it makes an instantaneous pose-position change, update those screen coordinates in the same tick as the position/offset and has_just_teleported. Otherwise the new pose is rendered at the previous origin for one frame. For a world-positioned character, use screen_position_x = position_x + position_offset_x and the corresponding Y expression.
Internal Buffers¶
These are exposed because several original behaviours use them. Prefer custom_value_* unless you are matching or extending an original behaviour that already depends on these buffers.
| Property | Type | Read/Write | Detail |
|---|---|---|---|
customVelocity_DecBuffer_0_4_X |
int |
read/write | Original decimal/fixed buffer X. Use exact spelling. |
customVelocity_DecBuffer_0_4_Y |
int |
read/write | Original decimal/fixed buffer Y. Use exact spelling. |
customVelocity2_DecBuffer_8_C_X |
int |
read/write | Secondary original buffer X. Use exact spelling. |
customVelocity2_DecBuffer_8_C_Y |
int |
read/write | Secondary original buffer Y. Use exact spelling. |
customDecBuffer_10 |
int |
read/write | Original behaviour scratch field. Use exact spelling. |
customDecBuffer_14 |
int |
read/write | Original behaviour scratch field. Use exact spelling. |
customBulletLifetimeDecBuffer_18 |
int |
read/write | Original projectile lifetime/scratch field. Use exact spelling. |
has_just_teleported |
bool |
read/write | Set for an authored instantaneous position/pose change to skip sprite and position smoothing that tick. Also set by the engine for throw anchors and nonzero animation entries. Clears residual grab glide, except on the newly entered grab itself. |
Grab Offsets¶
| Property | Type | Read/Write | Detail |
|---|---|---|---|
front_grab_offset |
int |
read | Front grab offset from logic data converted to script units. |
back_grab_offset |
int |
read | Back grab offset from logic data converted to script units. |
held_front_grab_offset |
int |
read | Distance this entity is held at when grabbed from the front (logic heldFrontGrabOffset), in script units; 0 when unset (the grabber's front_grab_offset applies). |
held_back_grab_offset |
int |
read | Same for a hold from behind (logic heldBackGrabOffset); 0 when unset (the grabber's back_grab_offset applies). Native grab strikes on an entity held at its own distance are tested as if it stood at the holder's own grab offset, so they reach it. |
Methods¶
set_animation(animation_id, start_frame = 0)¶
Queues an animation change. The argument is the editor-facing ID. Internally the engine stores animation IDs doubled, and the bridge performs that conversion.
The change is fully applied by the animation update step. Return false after decisive animation changes if you need to stop the old controller from continuing during the current frame.
start_frame is used on an ID transition (and as the loop restart frame), not
as an immediate seek of an unchanged animation. An already-playing animation
normally increments current_animation_frame later in this same frame. A
script-owned pose clock must account for that increment when positioning linked
actors. Shared throw controllers also read the thrower's current progress before
the animation update: a queued throw ID can otherwise be paired with the old
hold's progress. Test delayed throws and the rendered frame after the animation
pass, not just the queued ID and start frame.
character.set_animation(0)
character.object_mode = 2
return false
play_sound(pack_name, sound_name, channel_id = 0, pitch_percentage = 100)¶
Schedules an audio effect on the object's audio index.
Only loaded sounds play. Sounds are loaded with the entities that reference them (default sounds, hitbox and sound-event sounds, dependencies.json); a sound that only a script plays must be listed in the sounds of some loaded entity's dependencies.json, or it stays silent.
character.play_sound("My Pack", "guard-impact", 1, 100)
show_hit_effect(offset_x, offset_y, big = true, target_id = -1)¶
Shows the hit sparkle a hitbox contact shows (the big or small Classic spark, drawn in front of every entity), for hits a script applies itself, such as damage written directly to a held actor. offset_x and offset_y are Lua position units from this object: offset_x ahead along its facing, offset_y up. With target_id (an object index) the target also gets the hit vibration a hitbox contact gives it. It only schedules the visual; it does not apply damage or hit pause.
-- a knee halfway to the held enemy, 40 px up
local ahead = victim.position_x - character.position_x
if ahead < 0 then ahead = -ahead end
character.show_hit_effect(ahead / 2, 40 * 65536 / 1000, true, victim.object_index)
start_palette_fade(frames)¶
Fades the entity's sprite in from black over frames simulation frames, starting this frame: it is drawn fully dark at the start and at its normal palette when the fade ends. 0 (or a negative value) cancels a fade in progress. The fade start and duration are saved in the entity's state, so it is replay, rollback and netplay safe; the darkening itself is view-only.
-- an entity appearing out of the dark over one second
entity.start_palette_fade(60)
clear_referenced_items()¶
Clears linked/referenced items through the controller. Use when a move owns spawned helper objects and must clean them up.
Example: One-Time Sound¶
return function()
local item = game.this_item
if item == nil then
return true
end
if item.custom_value_1 == 0 then
item.custom_value_1 = 1
item.play_sound("My Pack", "spawn", 0)
end
return true
end