at_rot_target |
onAtRotTarget |
(integer tnum, rotation targetrot, rotation ourrot) |
|
Fires when the object reaches a registered rotation target (within tolerance). Provides the target handle and both target and actual rotations.
TypeScript
onAtRotTarget(tnum: number, targetRot: Rotation, ourRot: Rotation) {
this.say(0, "Rotation aligned!");
this.removeRotTarget(tnum);
}
|
at_target |
onAtTarget |
(integer tnum, vector targetpos, vector ourpos) |
|
Fires when the object reaches a registered position target (within tolerance). Provides the target handle and both target and actual positions.
TypeScript
onAtTarget(tnum: number, targetPos: Vector3, ourPos: Vector3) {
this.say(0, "Reached destination!");
this.removeTarget(tnum);
this.setTimer(0.0);
}
|
attach |
onAttach |
(key id) |
|
Fires when the object is attached to or detached from an avatar. The id is the avatar key on attach, or NULL_KEY on detach.
TypeScript
onAttach(id: string) {
if (id !== NULL_KEY) {
this.say(0, "HUD attached. Type /1 help for commands.");
this.listen(1, "", id, "");
} else {
this.say(0, "HUD detached. Goodbye!");
}
}
|
changed |
onChanged |
(integer change) |
|
Fires when something about the object changes, such as inventory, shape, color, owner, region, or link status. Check the change flags to determine what changed.
TypeScript
onChanged(change: number) {
if (change & CHANGED_OWNER) {
this.say(0, "New owner detected. Resetting.");
this.resetScript();
}
}
|
collision |
onCollision |
(integer num_detected) |
detected |
Fires continuously while another object or avatar is colliding with this object.
TypeScript
onCollision(detected: DetectedInfo[]) {
const vel = detected[0].velocity;
const speed = Math.sqrt(vel.x ** 2 + vel.y ** 2 + vel.z ** 2);
this.say(0, `Collision force: ${speed.toFixed(2)}`);
}
|
collision_end |
onCollisionEnd |
(integer num_detected) |
detected |
Fires when a collision with another object or avatar ends.
TypeScript
onCollisionEnd(detected: DetectedInfo[]) {
this.object.setColor({ x: 1, y: 1, z: 1 }, -1);
this.say(0, "Collision ended.");
}
|
collision_start |
onCollisionStart |
(integer num_detected) |
detected |
Fires when another object or avatar first collides with this object. The detected list contains collision info.
TypeScript
onCollisionStart(detected: DetectedInfo[]) {
const who = detected[0].name;
this.say(0, `Ouch! ${who} bumped into me.`);
this.object.setColor({ x: 1, y: 0, z: 0 }, -1);
}
|
control |
onControl |
(key id, integer level, integer edge) |
|
Fires when movement/control keys change state after permissions are granted. Provides held keys (level) and newly pressed/released keys (edge).
TypeScript
onControl(id: string, level: number, edge: number) {
if ((edge & CONTROL_FWD) && (level & CONTROL_FWD)) {
this.say(0, "Forward key pressed — boosting!");
this.object.applyImpulse({ x: 0, y: 5, z: 0 });
}
}
|
dataserver |
onDataserver |
(key queryid, string data) |
|
Fires when an asynchronous data request completes, such as notecard reads, landmark lookups, or name queries. Match the query ID to correlate with requests.
TypeScript
onDataserver(queryId: string, data: string) {
if (queryId === this.noteQuery) {
if (data !== EOF) {
this.say(0, `Config: ${data}`);
this.noteLine++;
this.noteQuery = this.getNotecardLine("config", this.noteLine);
}
}
}
|
email |
— |
(string time, string address, string subj, string message, integer num_left) |
deprecated |
DEPRECATED — In-world email is not supported in poqpoq. Use onHttpRequest for external messaging, or this.listen() for in-world communication.
|
experience_permissions |
— |
(key agent_id) |
deprecated |
DEPRECATED — SL Experiences system is not supported in poqpoq. Use standard run_time_permissions for permission requests.
|
experience_permissions_denied |
— |
(key agent_id, integer reason) |
deprecated |
DEPRECATED — SL Experiences system is not supported in poqpoq. Use standard run_time_permissions for permission requests.
|
http_request |
onHttpRequest |
(key id, string method, string body) |
|
Fires when this object's URL receives an incoming HTTP request. Provides the method (GET/POST) and request body.
TypeScript
onHttpRequest(id: string, method: string, body: string) {
if (method === "GET") {
this.httpResponse(id, 200, "text/plain", "Status: OK");
} else {
this.say(0, `Received POST: ${body}`);
this.httpResponse(id, 200, "text/plain", "Accepted");
}
}
|
http_response |
onHttpResponse |
(key request_id, integer status, list metadata, string body) |
|
Fires when an outgoing HTTP request receives a response. Contains the status code, response headers, and body.
TypeScript
onHttpResponse(requestId: string, status: number, metadata: string[], body: string) {
if (status === 200) {
this.say(0, `API response: ${body}`);
} else {
this.say(0, `HTTP error: ${status}`);
}
}
|
land_collision |
onLandCollision |
(vector pos) |
|
Fires continuously while the object is colliding with the terrain surface.
TypeScript
onLandCollision(pos: Vector3) {
this.object.setColor({ x: 0.5, y: 0.3, z: 0 }, -1);
}
|
land_collision_end |
onLandCollisionEnd |
(vector pos) |
|
Fires when the object stops colliding with the terrain surface.
TypeScript
onLandCollisionEnd(pos: Vector3) {
this.object.setColor({ x: 1, y: 1, z: 1 }, -1);
this.say(0, "Left the ground.");
}
|
land_collision_start |
onLandCollisionStart |
(vector pos) |
|
Fires when the object first collides with the terrain surface. Provides the collision position.
TypeScript
onLandCollisionStart(pos: Vector3) {
this.say(0, `Hit ground at height ${pos.z.toFixed(1)}`);
this.object.applyImpulse({ x: 0, y: 0, z: 3 });
}
|
link_message |
onLinkMessage |
(integer sender_num, integer num, string str, key id) |
|
Fires when a linked prim sends a message via linkMessage(). Used for inter-prim communication within a linkset.
TypeScript
onLinkMessage(senderNum: number, num: number, str: string, id: string) {
if (str === "sync") {
this.object.setColor({ x: 1, y: 0, z: 0 }, -1);
this.linkMessage(-1, 0, "ack", "");
}
}
|
listen |
onListen |
(integer channel, string name, key id, string message) |
|
Fires when a message is received on a channel the script is listening on. Set up with this.listen().
TypeScript
onListen(channel: number, name: string, id: string, message: string) {
if (message === "open") {
this.say(0, `${name} said the magic word!`);
this.object.setScale({ x: 0.01, y: 3.0, z: 3.0 });
}
}
|
money |
onMoney |
(key id, integer amount) |
|
Fires when an avatar pays the object using the Pay dialog. Provides the payer's ID and the amount paid.
TypeScript
onMoney(id: string, amount: number) {
if (amount >= 10) {
this.say(0, "Thank you for your purchase!");
this.giveInventory(id, "Product Box");
} else {
this.say(0, `Need L$10, you paid L$${amount}. Refunding.`);
this.giveMoney(id, amount);
}
}
|
moving_end |
onMovingEnd |
() |
|
Fires when the object stops moving and comes to rest.
TypeScript
onMovingEnd() {
this.say(0, "Object stopped.");
this.object.setAlpha(1.0, -1);
}
|
moving_start |
onMovingStart |
() |
|
Fires when the object starts moving due to physics or position changes.
TypeScript
onMovingStart() {
this.say(0, "Object is moving!");
this.object.setAlpha(0.5, -1);
}
|
no_sensor |
onNoSensor |
() |
|
Fires when a sensor sweep completes without detecting anything. Use it to handle the "nothing found" case.
TypeScript
onNoSensor() {
this.say(0, "Area is clear, no one detected.");
this.setTimer(0.0);
}
|
not_at_rot_target |
onNotAtRotTarget |
() |
|
Fires each frame while the object has a registered rotation target it hasn't reached yet.
TypeScript
onNotAtRotTarget() {
this.say(0, "Still rotating toward target...");
}
|
not_at_target |
onNotAtTarget |
() |
|
Fires each frame while the object has a registered position target it hasn't reached yet.
TypeScript
onNotAtTarget() {
const target = { x: 128, y: 128, z: 30 };
const pos = this.object.getPosition();
const dx = target.x - pos.x;
const dy = target.y - pos.y;
this.object.setPosition({ x: pos.x + dx * 0.1, y: pos.y + dy * 0.1, z: pos.z });
}
|
object_rez |
onObjectRez |
(key id) |
|
Fires in the rezzing object when a child object is successfully rezzed by this script. Provides the new object's key.
TypeScript
onObjectRez(id: string) {
this.say(0, `Child object rezzed: ${id}`);
await this.delay(1.0);
this.say(0, "Ready for next rez.");
}
|
on_rez |
onRez |
(integer start_param) |
|
Fires when the object is rezzed from inventory or by another script. The start parameter can pass data from the rezzing script.
TypeScript
onRez(startParam: number) {
if (startParam === 0) {
this.say(0, "Rezzed from inventory.");
} else {
this.say(0, `Rezzed by script with param: ${startParam}`);
}
}
|
path_update |
onPathUpdate |
(integer type, list reserved) |
|
Fires during path-following navigation to report progress, completion, or errors. Useful for NPC patrols, camera flyovers, and guided tours along waypoint paths.
TypeScript
onPathUpdate(type: number, reserved: string[]) {
if (type === PU_GOAL_REACHED) {
this.say(0, "NPC reached its destination.");
} else if (type === PU_FAILURE_UNREACHABLE) {
this.say(0, "Path blocked! Rerouting...");
}
}
|
remote_data |
— |
(integer event_type, key channel, key message_id, string sender, integer idata, string sdata) |
deprecated |
DEPRECATED — XML-RPC is obsolete. Use onHttpRequest/onHttpResponse for all external communication.
|
run_time_permissions |
onPermissions |
(integer perm) |
|
Fires when the avatar grants or denies a permission request (e.g., animation, camera control, attach). Check the granted permissions bitmask.
TypeScript
onPermissions(perm: number) {
if (perm & PERMISSION_TRIGGER_ANIMATION) {
this.startAnimation("sit");
}
}
|
sensor |
onSensor |
(integer num_detected) |
detected |
Fires when a sensor sweep detects one or more agents or objects matching the filter criteria.
TypeScript
onSensor(detected: DetectedInfo[]) {
const nearest = detected[0];
this.say(0, `Detected ${detected.length} agents. Nearest: ${nearest.name}`);
this.object.lookAt(nearest.position);
}
|
state_entry |
onStateEntry |
() |
|
Fires when the script enters a new state, including the default state on script start. Use it to initialize variables, start timers, and set up listeners.
TypeScript
onStateEntry() {
this.say(0, "Hello! Touch me to begin.");
this.listen(0, "", "", "");
this.setTimer(10.0);
}
|
state_exit |
onStateExit |
() |
|
Fires when the script is about to leave the current state. Use it to clean up timers, listeners, or other resources before transitioning.
TypeScript
onStateExit() {
this.setTimer(0.0);
this.say(0, "Shutting down...");
}
|
timer |
onTimer |
() |
|
Fires at the interval set by setTimer(). Use it for periodic tasks like animations, polling, or timed state changes.
TypeScript
onTimer() {
const pos = this.object.getPosition();
const newZ = pos.z + Math.sin(Date.now() / 1000) * 0.1;
this.object.setPosition({ x: pos.x, y: pos.y, z: newZ });
}
|
touch |
onTouch |
(integer num_detected) |
detected |
Fires continuously while an avatar holds the mouse button on the object. Useful for drag-style interactions.
TypeScript
onTouch(detected: DetectedInfo[]) {
const touchUV = detected[0].touchUV;
this.say(0, `Dragging at UV: ${touchUV.x}, ${touchUV.y}`);
}
|
touch_end |
onTouchEnd |
(integer num_detected) |
detected |
Fires when an avatar releases the mouse button after touching the object.
TypeScript
onTouchEnd(detected: DetectedInfo[]) {
this.say(0, "Released! Closing door.");
this.object.setRotation({ x: 0, y: 0, z: 0, s: 1 });
}
|
touch_start |
onTouchStart |
(integer num_detected) |
detected |
Fires when an avatar begins touching (clicking) the object. The detected list contains info about who touched it.
TypeScript
onTouchStart(detected: DetectedInfo[]) {
const who = detected[0].name;
this.say(0, `Welcome, ${who}! Opening door...`);
this.object.setRotation({ x: 0, y: 0, z: 0.707, s: 0.707 });
}
|
transaction_result |
onTransactionResult |
(key id, integer success, string data) |
|
Fires when a money transfer initiated by the script completes. Reports success or failure with a descriptive message.
TypeScript
onTransactionResult(id: string, success: number, data: string) {
if (success) {
this.say(0, `Payment sent successfully: ${data}`);
} else {
this.say(0, `Payment failed: ${data}`);
}
}
|