Recipes
Doors buttons levers and press-to-interact
The player walks up to a door and it opens, or presses a key near a lever and a gate lifts. There is no
InteractableComponent, DamageOnContactComponent, or button component (all stripped patterns); interaction is authored as a trigger or an input action plus a script that mutates the target.engine v1.0.234since script-semantic-patch-ops.v1, action-catalog.v1.0.232, physics.v1, mutation.v1, hierarchy.v1, audio.v1Copy for LLM
Use this for
a door that opens on approach or on a key press; buttons, levers, switches, and pressure plates; any "when the player interacts, something happens" object
Not for
teleport pads that move the player (see teleporters-and-portals); a platform that moves on its own with no input (see moving-platforms-and-elevators); collecting an item on touch (see collectibles-and-scoring)
Pairs with: Input mapping actions bindings keyboard mouse gamepad touch, Moving platforms, elevators, rotating hazards, and objects on a patrol path, Physics colliders rigid bodies triggers and joints, Audio sound effects music and positional feedback
The recipe
Author with project_apply_script_semantic_patch using the ai_safe op pack.
- Give the interactive object a trigger
ColliderComponent(collision:"trigger") sized to the reach zone, viaproject_add_component. Asolidcollider blocks the player instead of detecting them. - Auto path (open on approach):
addTriggerHandler{ "handlerKey":"onApproach" }. Inside the handler body (whole-body GessaScript viareplaceScriptFromGessaScript) open the door:ctx.entity.patchComponentthe door'sTransformComponentto the openpositionorrotation, thenctx.audio.playa latch sound. SetsetBooleanState{ "field":"doorOpen", "value": true }so re-entry is idempotent. - Press path (open on key): declare an
interactaction (see input-mapping-actions-bindings) andaddActionHandler{ "actionKey":"interact" }. In the body, confirm the player is in range before acting:ctx.physics.overlapTesta small shape at the player, orctx.world.findthe nearest door and compare positions, THEN patch it open. - Show that an object is usable with a
HighlightComponent(enabled:true, pick acolor) toggled on while the player is inside the trigger. - Hinged swing vs slide: to swing, parent the door mesh under a hinge entity with
ctx.entity.setParentand patch the hingerotation; to slide, patch the doorposition. If the mesh carries anopenclip, drive anAnimationStateComponent(clipKey:"open",playMode:"once") instead.
Pitfalls
addActionHandlerfires for the action everywhere, not only near the object. Always gate with an overlap or distance check, or the far door opens too.- Transform and component patches run on the server authority (
hierarchy.server_authority); the door opens for every player, which is what you want for a shared door. Do not try to open it client-side. - A door whose mesh origin is centered rotates around its middle, not its edge. Parent it under a hinge pivot and rotate the parent.
- Track open/closed with
setBooleanState, not a local variable, so a reload or a second player sees the same door state.
Verify
simulation_run(qa.run.start) to prove approach and press both open the door and that a closed door blocks passage.project_get_graph_snapshotto confirm the trigger collider and the trigger or action handler landed on the graph.