Scripting and Gameplay
This guide covers the code you write around scenes, prefabs, and input.
Where Gameplay Code Lives
Gameplay code usually lives in generated or hand-written PHP classes under:
Assets/ScriptsAssets/Events
Most gameplay scripts extend Sendama\Engine\Core\Behaviours\Behaviour.
A Typical Behaviour
Behaviours are components attached to a GameObject. They are the main unit of gameplay logic.
Common reasons to create a behaviour:
- move an actor
- listen for input
- update a UI label
- control enemy spawning
- manage a weapon or bullet pool
- respond to collisions
Example:
<?php
namespace MyGame\Scripts\Player;
use Sendama\Engine\Core\Behaviours\Behaviour;
use Sendama\Engine\Core\Vector2;
use Sendama\Engine\IO\Input;
final class PlayerController extends Behaviour
{
public function onUpdate(): void
{
$motion = new Vector2();
if (Input::isKeyPressed('a')) {
$motion->setX(-1);
}
if (Input::isKeyPressed('d')) {
$motion->setX(1);
}
$this->getTransform()->translate($motion);
}
}
Useful Behaviour Context
From a behaviour or component you can access:
getGameObject()getTransform()getRenderer()activeScenescene
That gives you enough context to:
- move the current object
- read or change its renderer
- find other objects in the active scene
- coordinate scene-wide systems
Lifecycle Hooks
The main lifecycle surface comes from Component and Behaviour.
Common hooks include:
awake()onStart()onUpdate()onFixedUpdate()onStop()onResume()onSuspend()
Collision-oriented hooks on Behaviour include:
onCollisionEnter()onCollisionStay()onCollisionExit()onTriggerEnter()onTriggerStay()onTriggerExit()
Use onUpdate() for frame-to-frame gameplay logic and onFixedUpdate() for logic that should stay aligned with the physics step.
Serialized Component Data
Scene and prefab files can assign values to component fields.
The runtime can hydrate:
- public properties
- non-public properties marked with
#[SerializeField]
In editor-authored files, the values are usually stored under a component data key.
This is ideal for values such as:
- movement speed
- fire rate
- prefab references
- pool sizes
- bounds
- booleans for behavior toggles
Use serialized fields when you want designers to tune behavior without editing PHP every time.
Working With Vector2
Vector2 is the basic 2D value type used throughout the engine for:
- position
- rotation
- scale
- sprite offsets and sizes
- serialized gameplay values such as bounds and directions
In the editor, Vector2 fields appear as paired x and y controls. In scene and prefab data they are stored as arrays:
'minBound' => [
'x' => 1,
'y' => 1,
],
Loading And Spawning Prefabs
Prefabs are the best way to spawn project-authored objects.
Typical pattern:
- author a prefab in
Assets/Prefabs - expose a prefab reference in a component
- assign the prefab through the inspector
- instantiate or pool it at runtime
The runtime can automatically hydrate a serialized GameObject-typed property from a prefab path string.
Pooling
Object pooling is a good fit for bullets, enemies, pickups, and other short-lived objects.
Important behavior to remember:
GameObject::pool($template, $size)clones a template but does not add the clones to the scene for youGameObject::instantiate(...)creates a live instance and adds it to the active scene- inactive pooled objects are ignored by collision checks, so deactivated bullets do not keep blocking gameplay
A practical pool loop looks like this:
- create or load a bullet template from a prefab
- build a fixed set of clones
- add them to the scene
- keep them deactivated until needed
- activate, reposition, and reuse them instead of destroying and recreating them constantly
Input
The Sendama\Engine\IO\Input facade exposes the most common input checks:
Input::getAxis(...)Input::isKeyPressed(...)Input::isKeyDown(...)Input::isKeyUp(...)Input::isAnyKeyPressed(...)Input::areAllKeysPressed(...)Input::isButtonDown(...)
Use the simplest method that matches the behavior you want.
Good Gameplay Authoring Pattern
For most features, this sequence works well:
- create a prefab for the gameplay object
- attach a behaviour script
- expose only the fields that need tuning
- set those values in the editor
- keep scene files declarative and PHP scripts behavioral
When the feature is ready to exercise, move on to Playtesting and Debugging.