Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/NeonD00m/feces/llms.txt

Use this file to discover all available pages before exploring further.

Hooks let you run callbacks when feces applies incoming replication data. They are set on the client-side feces instance and fire during feces:apply(). Each hook type corresponds to a different lifecycle event in the replication process — a new entity arriving, a component value changing, a component being removed, or an entity being destroyed.
Only one callback per hook type can be active at a time. Calling a hook method again overwrites the previous callback — there is no subscription list. If you need multiple listeners for the same event, set up your own signal or event dispatcher and call it from the single registered callback.

added(callback)

Fires after a newly replicated entity has all of its components set. Use this to run initialization logic that depends on the entity already having its full component set for that replication frame. Signature: feces:added(callback: (entity: LocalEntity) -> ())
added fires after all components in the packet have been applied to the entity. This means that inside the callback you can safely read any component value that arrived in the same packet — unlike changed, which fires before the new value is written.
feces:added(function(entity)
    if world:has(entity, PlayerTag) then
        print("new player added", entity)
        return
    end
    print("entity added", entity)
end)

changed(callback)

Fires before a component’s new value is set on an entity. Use this to compare the incoming value against the previous state, or to react to a component being added for the first time. Signature: feces:changed(callback: (entity: LocalEntity, component: Component, value: any) -> ())
Because changed fires before the new value is written, you can call world:get(entity, component) inside the callback to read the previous value. You can also call world:has(entity, component) to distinguish between a component being added for the first time (false) versus an existing value being updated (true).
feces:changed(function(entity, component, value)
    local had = world:has(entity, component)
    if not had then
        print("component added", component)
        return
    end
    local previous = world:get(entity, component)
    print("component changed", component, previous, "->", value)
end)

removed(callback)

Fires before a component is removed from an entity. Use this to read the component’s last value or perform cleanup before the data disappears from the world. Signature: feces:removed(callback: (entity: LocalEntity, component: Component) -> ())
Because removed fires before the component is actually removed, world:get(entity, component) still returns the previous value inside the callback. After apply completes, the component will no longer exist on the entity.
feces:removed(function(entity, component)
    local previous = world:get(entity, component)
    print("component removed", component, "had the value of", previous)
end)

deleted(callback)

Fires before an entity is deleted from the world. Use this to read any remaining component values or run cleanup logic before the entity ceases to exist. Signature: feces:deleted(callback: (entity: LocalEntity) -> ())
feces:deleted(function(entity)
    if world:has(entity, PlayerTag) then
        print("player has left the game", entity)
        return
    end
    print("entity deleted", entity)
end)

Hook Execution Order

When feces:apply() processes a packet, hooks fire in this order for each entity and component:
  1. deleted — fires for each entity marked for deletion (before world:delete).
  2. added — fires for each entity that did not previously exist in the local world (after its components are set).
  3. removed — fires for each component being removed from an existing entity (before world:remove).
  4. changed — fires for each component value being set or updated (before world:set).
All four hooks are optional. If a hook has not been registered, feces simply skips it.

Build docs developers (and LLMs) love