Custom Component Record & Array Properties
One of the most requested features has finally landed: record and array property types for custom TypeScript and JavaScript components.
We can’t wait to see the amazing experiences that will come out using them!
Record
Properties can now be grouped into a JavaScript class using the record
property:
1import {Component, Property} from '@wonderlandengine/api';
2
3class PlayerSettings {
4 static Properties = {
5 speed: Property.float(10.0),
6 name: Property.string('Hero')
7 };
8}
9
10export class PlayerManager extends Component {
11 static TypeName = 'player-manager';
12
13 static Properties = {
14 settings: Property.record(PlayerSettings)
15 };
16
17 start() {
18 console.log(this.settings); // Prints Player(10.0, 'Hero')
19 console.log(this.settings instanceof PlayerSettings); // true
20 }
21}

Note the style used to define the PlayerSettings
class. Properties are declared in the same way for records and components.
Array
It’s now also possible to create lists of properties using the array
property:
1import {Component, Property} from '@wonderlandengine/api';
2
3export class Downloader extends Component {
4 static TypeName = 'downloader';
5
6 static Properties = {
7 urls: Property.array(Property.string())
8 };
9
10 start() {
11 for(const url of this.urls) {
12 // Download the file pointed by `url`.
13 }
14 }
15}
Property.string()
represents the type of the array elements. Arrays can only hold elements of a single type at once.
Mixed with the record
property, complex types are now achievable:
1import {Component, Property} from '@wonderlandengine/api';
2
3class Zombie {
4 static Properties = {
5 name: Property.string(),
6 maxHealth: Property.float(100.0),
7 mesh: Property.mesh(),
8 };
9}
10
11export class ZombieSpawner extends Component {
12 static TypeName = 'zombie-spawner';
13
14 static Properties = {
15 enemies: Property.array(Property.record(Zombie))
16 };
17
18 start() {
19 for(const zombie of this.enemies) {
20 const name = zombie.name;
21 const health = zombie.maxHealth;
22 // Spawn this mean zombie!
23 }
24 }
25}

The API also supports nested array properties (arrays of arrays):
1import {Component, Property} from '@wonderlandengine/api';
2
3export class LevelGenerator extends Component {
4 static TypeName = 'level-generator';
5
6 static Properties = {
7 mapPiecesPerLevel: Property.array(Property.array(Property.string())),
8 };
9
10 start() {
11 // Prints something like:
12 // [
13 // ['level_1_forest.map', 'level_1_mountains.map'],
14 // ['level_2_beach.map', 'level_2_ocean.map', 'level_2_desert.map'],
15 // ['level_3_underwater.map'],
16 // ]
17 console.log(this.mapPiecesPerLevel);
18 }
19}
TypeScript
For TypeScript users, the new record
and array
property decorators make declaring
complex component properties highly compact and intuitive:
1import {Component, property, Property} from '@wonderlandengine/api';
2
3class Zombie {
4 @property.string()
5 name!: string;
6
7 @property.float(100)
8 maxHealth!: number;
9
10 @property.float(10)
11 damage!: number;
12}
13
14export class ZombieManager extends Component {
15 static TypeName = 'zombie-manager';
16
17 @property.array(Property.record(Zombie))
18 zombies!: Zombie[];
19}