A behavior is essentially a system in the ECS (entity-component-system) model. It first queries the relevant objects, then does something with it. See the Patchies - Example Behaviors notes for more examples of how behaviors look like.
You can define a behavior as a class in JavaScript. A behavior receives the BehaviorContext
as the constructor, and provides a setup
and cleanup
method. It calls setup
when the canvas is ready, and cleanup
when the canvas is going to be destroyed.
interface BehaviorContext<ObjectData, Options = any> {
options: Options
getObjects(): BaseObject<ObjectData>[]
}
interface Behavior<Context extends BehaviorContext> {
constructor(context: Context)
setup(): void
cleanup(): void
}
Here is a simple "fixed cycle" tick behavior that sends an 'update' message to the recipients.
type FixedCycleContext = BehaviorContext<
{ update: () => void },
{ tickInterval?: number }
>
class FixedCycleBehavior implements Behavior<FixedCycleContext> {
context: FixedCycleContext
constructor(context: FixedCycleContext) {
this.context = context
this.timer = null
this.tickInterval = context.options.tickInterval ?? (1000 / 60)
}
private update() {
// getObjects return the object's class instances.
for (const obj of this.context.getObjects()) {
obj?.update()
}
}
setup() {
this.timer = setInterval(this.update.bind(this), tickInterval)
}
cleanup() {
clearInterval(this.timer)
}
}
export default FixedCycleBehavior
Here's how one might implement a behavior for objects to reply to messages immediately:
type OnMessageContext = BehaviorContext<
{ tags?: string[] },
{ tickInterval?: number }
>
class OnMessageBehavior implements Behavior<OnMessageContext> {
// message queues
mq: Map<string, Message[]> = new Map()
constructor(context: FixedCycleContext) {
this.context = context
this.timer = null
// operations per second
this.controlRate = 1000
}
setup() {
// on ready, we grab list of producers to tick first
const producers = this.context.getObjects()
.filter(o => o.tags?.includes('producer'))
producers.update()
}
cleanup() {
}
}
export default FixedCycleBehavior