Legacy Scripting Reference
This documentation is for the legacy scripting approach. New projects should use the modern decorator-based system. See Migrating from Legacy Scripting for upgrade instructions.
This page documents the older JSDoc annotation-based scripting approach for reference.
Legacy Behaviors
Section titled “Legacy Behaviors”Behaviors in the legacy system use JSDoc annotations and manual event registration:
import { Behavior, ContextManager, useOnBeforeRender } from "@zcomponent/core";import { Box } from "@zcomponent/three/lib/components/meshes/Box";import { default as Scene } from "./Scene.zcomp";
interface ConstructionProps { // Constructor props here}
/** @zbehavior */export class MyBehavior extends Behavior<Box> {
protected zcomponent = this.getZComponentInstance(Scene);
constructor( contextManager: ContextManager, instance: Box, protected constructorProps: ConstructionProps ) { super(contextManager, instance);
// Register event handlers this.register(this.instance.onClick, evt => { console.log('Clicked!'); });
// Frame loop this.register(useOnBeforeRender(contextManager), dt => { // Called every frame }); }
dispose() { return super.dispose(); }}
// Run at design timeregisterBehaviorRunAtDesignTime(MyBehavior);Legacy Components
Section titled “Legacy Components”Components in the legacy system use JSDoc annotations:
import { ContextManager, registerLoadable } from "@zcomponent/core";import { Group } from "@zcomponent/three/lib/components/Group";import * as THREE from "three";
interface ConstructorProps {}
/** * @zcomponent * @zicon favorite */export class CustomComponent extends Group {
constructor(contextManager: ContextManager, constructorProps: ConstructorProps) { super(contextManager, constructorProps); registerLoadable(contextManager, this._load()); }
private async _load() { const mesh = new THREE.Mesh( new THREE.SphereGeometry(), new THREE.MeshBasicMaterial() ); this.element.add(mesh); }}Legacy Contexts
Section titled “Legacy Contexts”Contexts share state across components and behaviors:
import { Context, ContextManager, Observable } from "@zcomponent/core";
interface ConstructionProps {}
/** @zcontext */export class ScoreContext extends Context<ConstructionProps> {
public currentScore = new Observable<number>(0);
constructor(contextManager: ContextManager, constructorProps: ConstructionProps) { super(contextManager, constructorProps); }}
// Hook for accessing the scoreexport function useCurrentScore(contextManager: ContextManager) { return contextManager.get(ScoreContext).currentScore;}Legacy Properties
Section titled “Legacy Properties”Properties were defined using JSDoc annotations:
/** * @zcomponent */export class MyComponent extends Group { /** * @zui * @zdefault 0 * @zgroup Appearance * @ztype proportion */ public metalness = new Observable(0);
constructor(contextManager: ContextManager, constructorProps: ConstructorProps) { super(contextManager, constructorProps);
this.register(this.metalness, value => { // React to changes }); }}Legacy Property Annotations
Section titled “Legacy Property Annotations”| Annotation | Description |
|---|---|
@zui |
Expose property in editor |
@zdefault value |
Default value |
@zgroup Name |
Group in properties panel |
@ztype proportion |
Slider 0-1 |
@ztype angle-degrees |
Angle input |
@ztype color-norm-rgb |
Color picker |
@zvalues files *.png |
File picker |
Legacy Frame Loop
Section titled “Legacy Frame Loop”The frame loop in the legacy system used useOnBeforeRender:
import { useOnBeforeRender } from "@zcomponent/core";
/** @zbehavior */export class RotateBehavior extends Behavior<Box> { constructor(contextManager: ContextManager, instance: Box, constructorProps: ConstructionProps) { super(contextManager, instance);
this.register(useOnBeforeRender(contextManager), dt => { this.instance.element.rotation.y += 0.01 * dt; }); }}Upgrading
Section titled “Upgrading”The modern decorator-based system offers several advantages:
- Cleaner syntax - Decorators are more readable than JSDoc comments
- Better type safety - TypeScript 5 decorators provide improved type inference
- Less boilerplate - No need for manual
register()calls - Better tooling - Enhanced autocomplete and error detection
See Migrating from Legacy Scripting for step-by-step upgrade instructions.