Authoring Guide
The small amount of TypeScript—and the handful of Wave ideas—you need to read, adapt, and reason about WaveStudio projects.
On this page
Official public source map
Know what the sources can prove
WaveStudio publishes two TypeScript declaration files for its coding surface. They are machine-readable contracts: they list names, argument types, return types, overloads, enum members, and inheritance. They contain very little explanatory prose, so this handbook adds teaching language without pretending that the teaching language is official specification text.
| Source | What it proves | What it does not prove |
|---|---|---|
| Global declarations | Public classes, types, globals, overloads, and return types | Visual outcome, runtime success, or preferred pedagogy |
| Studio alias declarations | Call-style conveniences such as cube(...) |
Availability outside WaveStudio’s injected authoring host |
| WaveStudio | The public editor and its current interface | A permanent UI contract |
| Wave3D engine overview | Official product framing and engine goals | Individual TypeScript signatures |
| Published agent SDK README | License boundary, public-authoring doctrine, and optional local agent workflow | Permission to recover or document engine implementation details |
Use the evidence labels. “Official API” means an exact public signature or allowed value. “Declaration-checked example” means the code fits those declarations; it does not mean the scene was Clean-Run. “Tutorial guidance” is a recommendation. “Observed editor UI” may change.
Public-authoring boundary. The published SDK describes Wave Engine as free-to-use proprietary software—not open source or source available. This handbook teaches the documented public authoring surface; it does not describe or attempt to recover engine internals.
Tutorial guidance
The TypeScript you need
You do not need to master TypeScript before making a scene. Start with five reading patterns: a constant stores an object, new constructs an entity, parentheses hold arguments, braces describe data or a callback body, and a dot calls the next method.
const sculpture = new waveSphere(1.5, 24)
.setName("LearningSphere")
.setColor(PALETTE.CYAN)
.placeAt(0, 2, 0);
myScene.director.whenPress(Keyboard.Space, () => {
sculpture.turnRight(30);
});
| Code | Read it as |
|---|---|
const sculpture = | Keep the created entity under the name sculpture. |
new waveSphere(1.5, 24) | Construct a sphere with radius 1.5 and 24 segments. |
.setName("LearningSphere") | Call a method with one string argument. |
() => { ... } | Give WaveStudio a callback to run later. |
; | Finish the statement. It is conventional and keeps examples unambiguous. |
Objects and positional arguments
An object literal labels its values, as in { x: 0, z: 0 }. Constructor arguments are positional: changing the order changes their meaning. For example, waveCylinder accepts height, top diameter, bottom diameter, tessellation, then height segments.
// waveCube
constructor(
width?: number,
height?: number,
depth?: number,
widthSegments?: number,
heightSegments?: number,
depthSegments?: number
);
// waveSphere
constructor(radius?: number, segments?: number);
// waveCylinder
constructor(
height?: number,
diameterTop?: number,
diameterBottom?: number,
tessellation?: number,
heightSegments?: number
);
Official API, explained
The Wave authoring model
The public declarations expose a vocabulary of globals, entities, facades, builders, and terminal operations. Recognizing which one you are holding makes a long chain much easier to read.
| Idea | Role | Example |
|---|---|---|
| Global | A value WaveStudio makes available to authored code. | myScene, PALETTE, Keyboard, Seconds |
| Scene | The root authoring context. It exposes systems and keeps track of entities. | myScene is declared as WaveScene. |
| Entity | An object with identity, name, lifecycle, and behavior. | waveCube ultimately inherits WaveEntity. |
| Facade | A focused doorway from a larger object to one subsystem. | myScene.terrain.runtime |
| Builder | An object that collects configuration across several calls. | .noise().radius(640).amount(6) |
| Terminal | The call that completes or commits the builder operation. | .apply() for a terrain brush; .do(...) for a delayed action |
“Builder” and “terminal” are reading tools, not universal naming rules. The declaration return type tells you what the next call can be. Some methods directly change an entity and return this; others return a new specialized builder.
Official return types
Fluent chains: follow the return value
Many common entity methods return this. That lets the next line keep talking to the same object. A builder chain is different: each call configures the builder until a terminal method returns the owning object or a result.
const block = new waveCube(2, 2, 2)
.setName("ChainBlock")
.setColor(PALETTE.ORANGE)
.placeAt(0, 1, 0)
.turnRight(25);
myScene.terrain.runtime
.noise()
.at({ x: 0, z: 0 })
.radius(640)
.amount(6)
.frequency(0.015)
.octaves(3)
.falloff("smooth")
.apply();
Read the second chain from left to right: enter the scene’s terrain facade, enter its runtime-brush facade, make a noise brush, configure it, then apply it.
Tutorial guidance using official transform methods
Space and transforms
Use x, y, and z as your working 3D map: y is height, while x and z span the ground plane. A transform changes position, rotation, or scale.
| Intent | Core methods | Question to ask |
|---|---|---|
| Place | placeAt(x, y, z), moveTo(target) | Where should it be? |
| Move | moveUp, moveDown, moveLeft, moveRight, moveForward, moveBackward, moveBy | How far should it travel? |
| Turn | turnLeft, turnRight, turnTo, turnToward | Which way should it face? |
| Scale | scaleBy, scaleTo, setScale | Is this a factor, a target, or an explicit scale? |
const marker = new waveCube(1, 1, 1)
.placeAt(0, 1, 0)
.moveRight(3)
.moveUp(1)
.turnLeft(45)
.scaleTo(1.5);
Avoid imagined generic verbs. The beginner surface does not declare generic methods named move(), turn(), or scale(). Choose one of the specific methods above and check the reference signatures.
Official API distinction
Time values: unit, point, and span
The word “seconds” appears in several related types. Keeping them separate prevents one of the easiest beginner errors.
| Expression | Declared meaning | Use |
|---|---|---|
Seconds | A WaveTimeUnit-shaped callable value whose kind is typed as WaveTimeUnitKind | Pass as the unit to overloads such as after(2, Seconds). |
Seconds(2) | A WaveTimePoint | Point/rule APIs—not the one-argument entity delay overload. |
WaveTime.span(2, Seconds) | A WaveTimeSpan | Pass to an overload that explicitly accepts a span. |
const orb = new waveSphere(1, 20)
.setColor(PALETTE.CYAN)
.placeAt(0, 2, 0);
orb.after(2, Seconds).do((target) => {
target.moveUp(1).setColor(PALETTE.ORANGE);
});
The two-argument after(value, unit) overload returns a delayed proxy. Its do(callback) terminal schedules work and returns the entity.
Official Studio-only declaration file
Studio-only aliases versus canonical constructors
WaveStudio supplies convenient call-style aliases in a separate declaration file. For example, cube(2, 2, 2) returns a waveCube. The file itself says these aliases are injected by the editor/runtime host and are intentionally outside the engine package’s public export surface.
// Canonical public class
const portableShape = new waveCube(2, 2, 2);
// WaveStudio-injected call-style alias
const studioShape = cube(2, 2, 2);
This handbook teaches new waveCube(...), new waveSphere(...), and new waveCylinder(...) first. That makes the class being constructed explicit and avoids silently depending on the alias file.
Troubleshooting guide
Troubleshooting by reading the type
| Symptom | Likely cause | First check |
|---|---|---|
| “Cannot find name ‘cube’” | The Studio-only alias declaration is unavailable in that context. | Use new waveCube(...). |
| “Property ‘move’ does not exist” | A generic verb was guessed. | Choose moveBy, moveTo, or a directional move. |
A WaveTimePoint is rejected by after | Seconds(2) created a point. | Write after(2, Seconds) or pass WaveTime.span(...). |
| A builder compiles but its intended operation is unfinished | The terminal call is missing. | Look for apply(), do(...), play(), or the exact return type’s terminal. |
| A cylinder has surprising proportions | Its positional arguments were read in the wrong order. | Check height, top diameter, bottom diameter, tessellation, height segments. |
| A keyboard callback does not respond | The input registration or preview focus may be wrong. | Start from myScene.director.whenPress(Keyboard.Space, ...), then inspect the current preview UI. |
Debug in layers. First fix TypeScript errors. Then confirm the builder reaches a terminal. Then inspect the running scene. A declaration match is necessary evidence, but it cannot guarantee a particular visual result.
Handbook glossary
Glossary
| Term | Meaning in this handbook |
|---|---|
| Authoring host | The environment that injects globals and runs authored scene code; here, WaveStudio. |
| Callback | A function saved for later, such as what to do when Space is pressed. |
| Canonical constructor | The public class form, such as new waveCube(...), rather than a Studio-only call alias. |
| Declaration corpus | The published .d.ts files that describe the TypeScript surface. |
| Entity | A Wave object with identity and lifecycle inherited from WaveEntity. |
| Facade | A grouped doorway to one subsystem, such as scene terrain or runtime brushes. |
| Fluent chain | Several method calls connected because each return value supports the next call. |
| Global | A name supplied by WaveStudio without a local import, such as myScene. |
| Terminal | The call that completes a configured operation, such as apply() or do(...). |
| Transform | An object’s position, rotation, and scale. |