Loading...
Loading...
Writing .ts script files for the Creator Hub Script component — self-contained classes attached to individual entities. Use when the user wants to create a custom smart item, a reusable scripted entity, or write code that runs on a Creator Hub Script component. Do NOT use for regular scene index.ts code or global systems (see scene-runtime, add-interactivity).
npx skill4agent add decentraland/sdk-skills script-components.tsxassets/assets/scripts/assets/scripts/MyScript.tsscripts/tsconfig.jsonsrc/**/*assets/**/*"include": ["src/**/*.ts", "src/**/*.tsx", "assets/**/*.ts", "assets/**/*.tsx"]scripts/path"path": "assets/scripts/SitChair.ts"start()update(dt: number)public src: stringpublic entity: Entityimport { engine, Entity, Transform } from '@dcl/sdk/ecs'
export class MyScript {
constructor(
public src: string,
public entity: Entity,
public speed: number = 1
) {}
start() {
console.log('Script started on entity:', this.entity)
}
update(dt: number) {
const transform = Transform.getMutable(this.entity)
transform.rotation.y += this.speed * dt
}
}prioritypriority00@dcl/sdk-commandspriorityengine.addSystem(updateLoop, Number(priority))1000001000000priorityupdate()update()priority1000000update(dt)Highernumber = earlier execution — the OPPOSITE of the "priority 1 = first" assumption. See thepriorityskill's "System Execution Order & Priority" section for the underlying engine rule.scene-runtime
stringnumberbooleanEntitypublicprivatethis.<paramName>constructor(
public src: string,
public entity: Entity,
public radius: number = 5,
public label: string = 'Hello',
public enabled: boolean = true,
) {}?constructor(
public src: string,
public entity: Entity,
public targetEntity?: Entity,
public message?: string,
) {}@param/**
* @param startDate - The start date of the campaign in YYYY-MM-DD format
* @param endDate - The end date of the campaign in YYYY-MM-DD format
* @param wearableYOffset - How many meters above the ground the wearable should be displayed
*/
constructor(
public src: string,
public entity: Entity,
public startDate?: string,
public endDate?: string,
public wearableYOffset: number = 0.5,
) {}this.srcthis.srcimport { AudioSource } from '@dcl/sdk/ecs'
start() {
AudioSource.create(this.entity, {
audioClipUrl: this.src + '/sounds/click.mp3',
playing: false
})
}EntityName.startsWith(...).includes(...)"Sit Spot""Sit Spot 2""Sit Spot 3"name.includes('Sit Spot')stringEntity.startsWith('Needle')import { engine, Entity, Transform, Name } from '@dcl/sdk/ecs'
export class ClapMeter {
private needleEntities: Entity[] = []
constructor(
public src: string,
public entity: Entity,
) {}
start() {
for (const [childEntity, transform] of engine.getEntitiesWith(Transform)) {
if (transform.parent === this.entity) {
const nameComponent = Name.getOrNull(childEntity)
if (nameComponent && nameComponent.value.startsWith('Needle')) {
this.needleEntities.push(childEntity)
}
}
}
}
}@action/** ... */@action@action@action()@actionimport { engine, Entity } from '@dcl/sdk/ecs'
export class TreasureChest {
private isOpen = false
constructor(
public src: string,
public entity: Entity,
) {}
/**
* Opens the chest
* @action
*/
open() {
if (this.isOpen) return
this.isOpen = true
console.log('Chest opened!')
}
/**
* Closes the chest
* @action
*/
close() {
if (!this.isOpen) return
this.isOpen = false
console.log('Chest closed!')
}
}@actionopencloseActionCallback~sdk/script-utilsimport { Entity } from '@dcl/sdk/ecs'
import type { ActionCallback } from '~sdk/script-utils'
export class Padlock {
constructor(
public src: string,
public entity: Entity,
public onUnlock: ActionCallback,
) {}
/**
* @action
*/
solve() {
this.onUnlock()
}
}~sdk/script-utilsimport {
callScriptMethod,
getScriptInstance,
getAllScriptInstances,
getScriptInstancesByPath
} from '~sdk/script-utils'
callScriptMethod(entity, 'assets/scripts/Padlock.ts', 'solve', 123)
const instance = getScriptInstance(entity, 'assets/scripts/Padlock.ts')
const allOnEntity = getAllScriptInstances(entity)
const allByPath = getScriptInstancesByPath('assets/scripts/Padlock.ts')