Skip to content

Interaction

Interaction is how the player acts on the world with a single key. Any object can show an interaction prompt and call your script when it is used. Feather also includes ready-made interactions that need no script: doors that swing open and can be locked with a key item, switches that open and close linked doors, item pickups, containers, and carrying and throwing physics objects.

All of them use the Interact action (E by default; West on a gamepad), and their state is kept in saves.

  • Interaction prompts on any object, with custom text, that call on_interact(id).
  • Doors that swing about a hinge, optionally locked with an item that can be used up.
  • Switches — levers or buttons — that toggle doors and other switches.
  • Pickups that put an item in the inventory and remove the object.
  • Containers the player opens to take and put items.
  • Carrying and throwing dynamic bodies, with thrown objects dealing blunt damage to enemies.
  1. Select the object.
  2. In Details → Tags & interaction, turn on Interactable (E).
  3. Enter the Prompt text, for example “Read” or “Talk”.
  4. Handle the interaction in a world script:
fn on_interact(id) {
if id == "27" {
print("The note reads: meet me at the lighthouse.");
}
}

The prompt appears when the player is within the interaction distance, set in Window → Game logic → Game settings → Interaction distance (0.5–20 m, default 2.5 m). Scripts can change a prompt at runtime with set_interact(id, prompt).

  1. Select the door object and choose Details → Add Component → Door.
  2. Set how far it Swings, where the Hinge sits, and how long it Takes.
  3. To lock it, turn on Locked and choose the Key item. Turn on Uses up the key to take the key from the player when it unlocks.
  4. Give the door a Kinematic body so it pushes things as it moves.
Field Description Range Default
open_degrees How far it swings; negative swings the other way −180 to 180° 95°
hinge Hinge in the object’s local box; [-0.5, 0, 0] is the left edge ±5 [−0.5, 0, 0]
seconds Time to open or close 0.05–30 s 0.7 s
locked_with Item ID that unlocks it; null is never locked — None
consume_key Unlocking uses the key up On/off Off
starts_open Open when Play starts On/off Off
sound Sound cue or sound played when it moves — Empty
  1. Select the lever or button and choose Details → Add Component → Switch.
  2. Under Opens and closes, choose Add a door for each door or switch it drives.
  3. Set the Prompt, and whether it Starts on or works Only once.
Field Description Range Default
targets Object IDs of the doors or switches it drives Up to 32 None
prompt Prompt text 1–80 characters Pull
once Can only be used once On/off Off
starts_on On when Play starts On/off Off
tilt Degrees the switch object tips when on; 0 keeps it still −120 to 120° 40°
sound Sound played when used — Empty

A Pickup component puts its item in the inventory when the player interacts with it, and the object disappears. A Container opens a screen to take and put items. Both are covered in Items and inventory.

The player looks at a dynamic body and presses Interact to pick it up, and presses it again to set it down. The Throw action (left mouse by default) hurls it. Heavier objects fly slower, and thrown objects deal blunt damage to enemies they hit.

Configure it in Window → World & terrain → Items → Carrying & throwing.

Setting Field Range Default
Pick up physics objects carry On/off On
Heaviest carry_max_mass 0–10,000 kg 60 kg
Held at hold_distance 0.5–6 m in front of the camera 1.8 m
Throw speed throw_speed 0–60 m/s for a light object 13 m/s
Throw damage throw_damage 0–10 blunt damage per kg·m/s 0.12
Throw action throw_action An input action ID throw

Door, lever, pickup, chest and throw sounds can be replaced with your own cues in Built-in sounds under the player’s game feel settings; see Player and traversal.

Function Description
use_object(id) Acts as if the player pressed Interact on the object: opens doors, pulls switches, takes pickups
door_open(id) Whether a door is open
carry_object(id) Picks up a dynamic body, including one that has settled at rest
throw_carried(), drop_carried() Throws or sets down what the player carries
carrying() The ID of the carried object, or ()
use_tool() Casts the worn tool where the camera aims
set_interact(id, prompt) Changes an object’s prompt
tune("interaction", patch) Changes the carrying and throwing settings at runtime, for example a heavier carry_max_mass after an upgrade

on_interact(id) still runs when the player uses a door, switch or pickup, so you can add behaviour on top of the built-in one.

// A world script: react when the player pulls lever 40 and gate 41 opens.
fn on_interact(id) {
if id == "40" && door_open(41) {
print("The gate is open. Guards are coming.");
}
}
  • A switch drives at most 32 targets.
  • A door’s hinge must be within ±5 of the object’s local box.
  • Only dynamic bodies up to carry_max_mass can be carried.
Terminal window
# Lock door 41 with the "key" item, used up on unlock
feather-cli --connect .feather-session.json command scene.update \
--json '{"id":41,"patch":{"door":{"open_degrees":-100,"locked_with":"key","consume_key":true}}}'
# A lever (object 40) that opens door 41
feather-cli --connect .feather-session.json command scene.update \
--json '{"id":40,"patch":{"switch":{"targets":[41],"prompt":"Pull lever"}}}'
# Let the player lift heavier objects
feather-cli --connect .feather-session.json command interaction.set \
--json '{"patch":{"carry_max_mass":120,"throw_speed":16}}'

interaction.get lists the carrying settings and the level’s doors, switches and pickups.