flow: to synchronized

This commit is contained in:
cha0s 2019-09-22 18:45:52 -05:00
parent b018e8ccf5
commit ed556a34b3
27 changed files with 184 additions and 103 deletions

1
.gitignore vendored
View File

@ -2,3 +2,4 @@ dist
node_modules
.vscode
/isolate-0x*-v8-*.log
# /resource/*.*.json

View File

@ -7,15 +7,14 @@ import {Stage} from '@avocado/graphics';
import {ActionRegistry, InputPacket} from '@avocado/input';
import {Vector} from '@avocado/math';
import {SocketClient} from '@avocado/net/client/socket';
import {BundlePacket, SocketIoParser} from '@avocado/net';
import {Synchronizer} from '@avocado/state';
import {BundlePacket, ClientSynchronizer, SocketIoParser} from '@avocado/net';
import {clearAnimation, setAnimation} from '@avocado/timing';
import {World} from '@avocado/physics/matter/world';
import {Room, RoomView} from '@avocado/topdown';
// 1st party.
import {augmentParserWithThroughput} from '../common/parser-throughput';
import {SelfEntityPacket} from '../common/packets/self-entity.packet';
import {WorldTime} from '../common/world-time';
import {WorldTime} from '../common/world-time.synchronized';
import {CycleTracker} from './cycle-tracker';
import {showMessage} from './overlay';
@ -102,10 +101,8 @@ export class App extends decorate(class {}) {
this.room.world.stepTime = config.simulationFrequency;
// State synchronization.
this.state = undefined;
this.synchronizer = new Synchronizer([
this.room,
this.worldTime,
]);
this.synchronizer = new ClientSynchronizer();
this.synchronizer.addSynchronized(this.worldTime);
}
applyLighting() {
@ -275,14 +272,12 @@ export class App extends decorate(class {}) {
this.hasReceivedState = true;
}
if (packet instanceof BundlePacket) {
for (let i = 0; i < packet.data.length; i++) {
this.onPacket(packet.data[i]);
}
return this.synchronizer.acceptPackets(packet.data);
}
if (packet instanceof SelfEntityPacket) {
this.selfEntityUuid = packet.data;
}
this.synchronizer.acceptPacket(packet);
this.synchronizer.acceptPackets([packet]);
}
onPointerDown(event) {

View File

@ -35,7 +35,7 @@ const decorate = compose(
`),
);
const InventoryComponent = ({worldTime}) => {
const InventoryComponent = () => {
const bagSlots = [];
for (let i = 0; i < 40; ++i) {
bagSlots.push(<ItemSlot key={i} />);

View File

@ -4,7 +4,7 @@ import React, {useEffect, useState} from 'react';
import {compose} from '@avocado/core';
import contempo from 'contempo';
// 1st party.
import {WorldTime} from '../../../common/world-time';
import {WorldTime} from '../../../common/world-time.synchronized';
const decorate = compose(
contempo(`

View File

@ -1,11 +1,15 @@
import {Packet} from '@avocado/net';
import {SynchronizedUpdatePacket} from '@avocado/net';
export class WorldTimePacket extends Packet {
export class WorldTimePacket extends SynchronizedUpdatePacket {
static get schema() {
const superSchema = super.schema;
return {
...super.schema,
data: 'uint16',
...superSchema,
data: {
...superSchema.data,
hour: 'uint16',
},
};
}

View File

@ -1,5 +1,5 @@
import {compose} from '@avocado/core';
import {Synchronized} from '@avocado/state';
import {SynchronizedMixin} from '@avocado/net';
import {Ticker} from '@avocado/timing';
import {WorldTimePacket} from './world-time.packet';
@ -7,12 +7,12 @@ import {WorldTimePacket} from './world-time.packet';
const MAGIC_TO_FIT_HOUR_INTO_USHORT = 2730;
const decorate = compose(
Synchronized,
SynchronizedMixin,
);
export class WorldTime extends decorate(class {}) {
constructor() {
constructor(json) {
super();
this._hour = 0;
this._isUpdateReady = true;
@ -21,14 +21,22 @@ export class WorldTime extends decorate(class {}) {
this.ticker.on('tick', () => {
this._isUpdateReady = true;
});
if ('undefined' !== typeof json) {
this.fromJSON(json);
}
}
acceptPacket(packet) {
if (packet instanceof WorldTimePacket) {
this._hour = packet.data / MAGIC_TO_FIT_HOUR_INTO_USHORT;
this.fromNetwork(packet.data.hour);
}
}
cleanPackets() {
super.cleanPackets();
this._isUpdateReady = false;
}
static format(time) {
const rawHour = (time + 12) % 12;
const hour = Math.floor(0 === Math.floor(rawHour) ? 12 : rawHour);
@ -41,6 +49,16 @@ export class WorldTime extends decorate(class {}) {
}
}
fromJSON(json) {
if (json.hour) {
this._hour = this.fromNetwork(json.hour);
}
}
fromNetwork(hour) {
this._hour = hour / MAGIC_TO_FIT_HOUR_INTO_USHORT;
}
get hour() {
return this._hour;
}
@ -49,17 +67,13 @@ export class WorldTime extends decorate(class {}) {
this._hour = hour;
}
packetsForUpdate(force) {
const updates = [];
if (force || this._isUpdateReady) {
updates.push(new WorldTimePacket(
(this._hour * MAGIC_TO_FIT_HOUR_INTO_USHORT) >> 0
));
packets(informed) {
if (!this._isUpdateReady) {
return;
}
if (!force) {
this._isUpdateReady = false;
}
return updates;
return new WorldTimePacket({
hour: this.toNetwork(),
});
}
secondsPerHour() {
@ -72,4 +86,14 @@ export class WorldTime extends decorate(class {}) {
this.ticker.tick(elapsed);
}
toNetwork() {
return (this._hour * MAGIC_TO_FIT_HOUR_INTO_USHORT) >> 0;
}
toJSON() {
return {
hour: this.toNetwork(),
}
}
}

View File

@ -39,7 +39,6 @@
"@avocado/physics": "1.x",
"@avocado/resource": "1.x",
"@avocado/sound": "1.x",
"@avocado/state": "1.x",
"@avocado/timing": "1.x",
"@avocado/topdown": "1.x",
"classnames": "2.2.6",

View File

View File

@ -1 +0,0 @@
{"traits": {"existent": {"state": {"isTicking": false, "name": "Base"}}}}

View File

@ -1 +0,0 @@
{"base": "/base-test.entity.json", "traits": {"existent": {"state": {"name": "Extension"}}}}

1
resource/hoe.entity.json Normal file
View File

@ -0,0 +1 @@
{"traits":{"existent":{},"item":{"params":{"itemActions":{"type":"actions","traversals":[{"type":"traversal","steps":[{"type":"key","key":"item"},{"type":"key","key":"useTool"},{"type":"invoke","args":[]}]}]},"slotImages":{"default":"/hoe.png"}}},"tool":{"params":{"condition":{"type":"condition","operator":"contains","operands":[{"type":"literal","value":[1,2,3,4]},{"type":"traversal","steps":[{"type":"key","key":"wielder"},{"type":"key","key":"layer"},{"type":"key","key":"tileAt"},{"type":"invoke","args":[{"type":"traversal","steps":[{"type":"key","key":"target"}]}]}]}]},"actions":{"type":"actions","traversals":[{"type":"traversal","steps":[{"type":"key","key":"wielder"},{"type":"key","key":"layer"},{"type":"key","key":"setTileAt"},{"type":"invoke","args":[{"type":"traversal","steps":[{"type":"key","key":"target"}]},{"type":"literal","value":6}]}]}]},"target":{"type":"projection","distance":1,"length":1,"width":1}}}}}

View File

@ -1 +1 @@
{"size":[384,384],"layers":[{"entities":[{"uri":"/flower-barrel.entity.json","traits":{"positioned":{"state":{"x":352,"y":908}}}},{"uri":"/flower-barrel.entity.json","traits":{"positioned":{"state":{"x":1204,"y":240}}}},{"uri":"/flower-barrel.entity.json","traits":{"positioned":{"state":{"x":320,"y":444}}}},{"uri":"/flower-barrel.entity.json","traits":{"positioned":{"state":{"x":732,"y":856}}}},{"uri":"/flower-barrel.entity.json","traits":{"positioned":{"state":{"x":900,"y":516}}}},{"uri":"/flower-barrel.entity.json","traits":{"positioned":{"state":{"x":532,"y":1272}}}},{"uri":"/flower-barrel.entity.json","traits":{"positioned":{"state":{"x":368,"y":840}}}},{"uri":"/flower-barrel.entity.json","traits":{"positioned":{"state":{"x":512,"y":1328}}}},{"uri":"/flower-barrel.entity.json","traits":{"positioned":{"state":{"x":1288,"y":220}}}},{"uri":"/flower-barrel.entity.json","traits":{"positioned":{"state":{"x":544,"y":976}}}},{"uri":"/flower-barrel.entity.json","traits":{"positioned":{"state":{"x":420,"y":1072}}}},{"uri":"/flower-barrel.entity.json","traits":{"positioned":{"state":{"x":412,"y":388}}}},{"uri":"/flower-barrel.entity.json","traits":{"positioned":{"state":{"x":1008,"y":1124}}}},{"uri":"/flower-barrel.entity.json","traits":{"positioned":{"state":{"x":512,"y":1188}}}},{"uri":"/flower-barrel.entity.json","traits":{"positioned":{"state":{"x":736,"y":1316}}}},{"uri":"/flower-barrel.entity.json","traits":{"positioned":{"state":{"x":248,"y":636}}}},{"uri":"/flower-barrel.entity.json","traits":{"positioned":{"state":{"x":1068,"y":1180}}}},{"uri":"/flower-barrel.entity.json","traits":{"positioned":{"state":{"x":1076,"y":812}}}},{"uri":"/flower-barrel.entity.json","traits":{"positioned":{"state":{"x":984,"y":1228}}}},{"uri":"/flower-barrel.entity.json","traits":{"positioned":{"state":{"x":1116,"y":376}}}},{"uri":"/mama-kitty-spawner.entity.json","traits":{"positioned":{"state":{"x":968,"y":1152}}}},{"uri":"/mama-kitty-spawner.entity.json","traits":{"positioned":{"state":{"x":404,"y":948}}}},{"uri":"/mama-kitty-spawner.entity.json","traits":{"positioned":{"state":{"x":672,"y":1116}}}},{"uri":"/fire.entity.json","traits":{"positioned":{"state":{"x":712,"y":320}}}},{"uri":"/fire.entity.json","traits":{"positioned":{"state":{"x":712,"y":1096}}}},{"uri":"/fire.entity.json","traits":{"positioned":{"state":{"x":1144,"y":704}}}},{"uri":"/fire.entity.json","traits":{"positioned":{"state":{"x":416,"y":212}}}},{"uri":"/fire.entity.json","traits":{"positioned":{"state":{"x":528,"y":780}}}},{"uri":"/blue-fire.entity.json","traits":{"positioned":{"state":{"x":436,"y":992}}}}],"tiles":{"size":[24,24],"data":[1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4]},"tilesetUri":"/tileset.json"}]}
{"size":[384,384],"layers":[{"entities":[{"uri":"/mama-kitty-spawner.entity.json","traits":{"positioned":{"state":{"x":980,"y":1164}}}},{"uri":"/mama-kitty-spawner.entity.json","traits":{"positioned":{"state":{"x":1028,"y":1112}}}},{"uri":"/mama-kitty-spawner.entity.json","traits":{"positioned":{"state":{"x":208,"y":1312}}}},{"uri":"/fire.entity.json","traits":{"positioned":{"state":{"x":312,"y":376}}}},{"uri":"/fire.entity.json","traits":{"positioned":{"state":{"x":592,"y":1248}}}},{"uri":"/fire.entity.json","traits":{"positioned":{"state":{"x":572,"y":780}}}},{"uri":"/fire.entity.json","traits":{"positioned":{"state":{"x":352,"y":1328}}}},{"uri":"/fire.entity.json","traits":{"positioned":{"state":{"x":1204,"y":1176}}}}],"tiles":{"size":[24,24],"data":[6,5,1,3,3,2,2,4,4,1,2,3,1,3,6,4,5,1,2,5,4,1,4,2,4,4,2,4,4,3,5,3,1,1,5,2,2,5,2,3,2,1,3,2,4,4,3,3,4,4,4,3,4,6,2,4,6,1,5,2,6,5,4,6,3,3,2,2,2,2,3,6,6,1,3,1,1,4,6,5,3,1,1,4,2,4,4,5,3,6,5,5,5,4,5,1,3,1,4,4,5,3,3,5,3,3,3,3,2,4,4,4,3,6,2,2,5,4,3,6,5,5,5,4,3,2,4,1,4,3,3,4,6,6,3,6,2,3,5,6,3,2,3,5,6,4,3,2,3,6,6,3,1,4,4,3,2,3,1,1,2,3,1,3,3,6,1,3,5,4,4,4,1,3,1,3,2,6,1,1,3,2,4,2,2,2,6,5,2,4,1,1,1,6,1,1,4,1,6,6,1,2,3,6,3,6,3,2,4,2,3,5,3,2,5,4,4,2,5,6,2,1,2,3,2,2,3,1,3,2,2,1,5,2,6,1,5,3,2,4,1,6,1,4,1,1,2,6,1,4,1,2,3,5,1,3,2,3,2,3,5,2,6,1,4,3,4,6,1,5,2,2,5,5,3,3,4,2,5,5,6,4,3,2,4,2,5,1,2,4,1,5,4,2,2,5,4,2,4,2,1,5,2,2,2,1,2,3,4,5,2,6,1,3,6,5,4,3,1,1,2,2,2,2,2,3,3,1,3,6,4,2,5,1,4,1,3,1,6,4,4,6,2,3,3,3,5,3,4,2,1,6,6,3,1,6,6,4,5,1,2,5,2,3,3,5,6,2,1,6,5,6,3,3,3,5,5,4,5,1,2,2,1,3,2,1,3,6,1,2,3,4,2,3,3,2,4,5,2,4,4,2,5,3,6,6,4,3,1,2,3,4,2,2,5,3,4,6,1,1,3,6,3,3,2,3,1,3,3,2,5,1,6,4,4,4,6,3,5,5,5,4,2,3,6,4,3,6,4,3,6,1,4,6,2,4,2,6,6,5,6,2,2,1,4,4,4,3,5,2,3,4,6,5,3,2,6,6,5,1,3,2,5,4,1,1,5,3,4,6,1,6,3,2,2,1,1,3,5,1,1,5,1,4,5,1,4,2,3,1,5,2,3,6,4,6,3,3,4,4,6,1,4,5,5,2,2,4,5,2,1,4,3,1,1,4,4,4,1,1,3,2,1,6,1,4,3,3,2,3,2,2,2,4,5,5,1,3,2,1,3,4,4,2,2,1,2,4,5,2,2,2,2,4,5,3]},"tilesetUri":"/tileset.json"}]}

View File

@ -1 +1 @@
{"traits":{"alive":{},"animated":{"params":{"animations":{"idle":{"offset":[0,-3],"uri":"/kitty.animation.json"}}}},"audible":{"params":{"sounds":{"deathSound":{"uri":"/ded.sound.json"}}}},"behaved":{"params":{"routines":{"type":"routines","routines":{"initial":{"type":"routine","routine":{"type":"actions","traversals":[{"type":"traversal","steps":[{"type":"key","key":"entity"},{"type":"key","key":"moveFor"},{"type":"invoke","args":[{"type":"traversal","steps":[{"type":"key","key":"global"},{"type":"key","key":"randomNumber"},{"type":"invoke","args":[{"type":"literal","value":0.25},{"type":"literal","value":2.5},{"type":"literal","value":false}]}]}]}]},{"type":"traversal","steps":[{"type":"key","key":"entity"},{"type":"key","key":"isAnimating"}],"value":{"type":"literal","value":false}},{"type":"traversal","steps":[{"type":"key","key":"global"},{"type":"key","key":"wait"},{"type":"invoke","args":[{"type":"traversal","steps":[{"type":"key","key":"global"},{"type":"key","key":"randomNumber"},{"type":"invoke","args":[{"type":"literal","value":1},{"type":"literal","value":4},{"type":"literal","value":false}]}]}]}]},{"type":"traversal","steps":[{"type":"key","key":"entity"},{"type":"key","key":"direction"}],"value":{"type":"traversal","steps":[{"type":"key","key":"global"},{"type":"key","key":"randomNumber"},{"type":"invoke","args":[{"type":"literal","value":0},{"type":"literal","value":3}]}]}},{"type":"traversal","steps":[{"type":"key","key":"global"},{"type":"key","key":"wait"},{"type":"invoke","args":[{"type":"traversal","steps":[{"type":"key","key":"global"},{"type":"key","key":"randomNumber"},{"type":"invoke","args":[{"type":"literal","value":0.5},{"type":"literal","value":3},{"type":"literal","value":false}]}]}]}]},{"type":"traversal","steps":[{"type":"key","key":"entity"},{"type":"key","key":"isAnimating"}],"value":{"type":"literal","value":true}}]}}}}}},"collider":{},"directional":{"params":{"directionCount":4},"state":{"direction":2}},"emitter":{},"existent":{"state":{"name":"Kitty"}},"visible":{"state":{"visibleScale":[1,1]}},"layered":{},"listed":{},"mobile":{"state":{"speed":40}},"physical":{},"positioned":{},"roomed":{},"shaped":{"params":{"shape":{"type":"rectangle","position":[0,0],"size":[8,4]}}},"vulnerable":{}}}
{"traits":{"alive":{},"animated":{"params":{"animations":{"idle":{"offset":[0,-3],"uri":"/kitty.animation.json"}}}},"audible":{"params":{"sounds":{"deathSound":{"uri":"/ded.sound.json"}}}},"behaved":{"params":{"routines":{"type":"routines","routines":{"initial":{"type":"routine","routine":{"type":"actions","traversals":[{"type":"traversal","steps":[{"type":"key","key":"entity"},{"type":"key","key":"direction"}],"value":{"type":"traversal","steps":[{"type":"key","key":"Math"},{"type":"key","key":"randomNumber"},{"type":"invoke","args":[{"type":"literal","value":0},{"type":"literal","value":3}]}]}},{"type":"traversal","steps":[{"type":"key","key":"entity"},{"type":"key","key":"moveFor"},{"type":"invoke","args":[{"type":"traversal","steps":[{"type":"key","key":"Math"},{"type":"key","key":"Vector"},{"type":"key","key":"fromDirection"},{"type":"invoke","args":[{"type":"traversal","steps":[{"type":"key","key":"entity"},{"type":"key","key":"direction"}]}]}]},{"type":"traversal","steps":[{"type":"key","key":"Math"},{"type":"key","key":"randomNumber"},{"type":"invoke","args":[{"type":"literal","value":0.25},{"type":"literal","value":2.5},{"type":"literal","value":false}]}]}]}]},{"type":"traversal","steps":[{"type":"key","key":"entity"},{"type":"key","key":"isAnimating"}],"value":{"type":"literal","value":false}},{"type":"traversal","steps":[{"type":"key","key":"Timing"},{"type":"key","key":"wait"},{"type":"invoke","args":[{"type":"traversal","steps":[{"type":"key","key":"Math"},{"type":"key","key":"randomNumber"},{"type":"invoke","args":[{"type":"literal","value":1},{"type":"literal","value":4},{"type":"literal","value":false}]}]}]}]},{"type":"traversal","steps":[{"type":"key","key":"entity"},{"type":"key","key":"direction"}],"value":{"type":"traversal","steps":[{"type":"key","key":"Math"},{"type":"key","key":"randomNumber"},{"type":"invoke","args":[{"type":"literal","value":0},{"type":"literal","value":3}]}]}},{"type":"traversal","steps":[{"type":"key","key":"Timing"},{"type":"key","key":"wait"},{"type":"invoke","args":[{"type":"traversal","steps":[{"type":"key","key":"Math"},{"type":"key","key":"randomNumber"},{"type":"invoke","args":[{"type":"literal","value":0.5},{"type":"literal","value":3},{"type":"literal","value":false}]}]}]}]},{"type":"traversal","steps":[{"type":"key","key":"entity"},{"type":"key","key":"isAnimating"}],"value":{"type":"literal","value":true}}]}}}}}},"collider":{},"directional":{"params":{"directionCount":4},"state":{"direction":2}},"emitter":{},"existent":{"state":{"name":"Kitty"}},"visible":{"state":{"visibleScale":[1,1]}},"layered":{},"listed":{},"mobile":{"state":{"speed":40}},"physical":{},"positioned":{},"roomed":{},"shaped":{"params":{"shape":{"type":"rectangle","position":[0,0],"size":[8,4]}}},"vulnerable":{}}}

View File

@ -1 +1 @@
{"traits":{"behaved":{"params":{"routines":{"type":"routines","routines":{"initial":{"type":"routine","routine":{"type":"actions","traversals":[{"type":"traversal","steps":[{"type":"key","key":"context"},{"type":"key","key":"json"}],"value":{"type":"literal","value":{"traits":{"positioned":{"state":{}}}}}},{"type":"traversal","steps":[{"type":"key","key":"context"},{"type":"key","key":"json"},{"type":"key","key":"traits"},{"type":"key","key":"positioned"},{"type":"key","key":"state"},{"type":"key","key":"x"}],"value":{"type":"traversal","steps":[{"type":"key","key":"global"},{"type":"key","key":"multiply"},{"type":"invoke","args":[{"type":"traversal","steps":[{"type":"key","key":"global"},{"type":"key","key":"randomNumber"},{"type":"invoke","args":[{"type":"literal","value":100},{"type":"traversal","steps":[{"type":"key","key":"global"},{"type":"key","key":"sub"},{"type":"invoke","args":[{"type":"traversal","steps":[{"type":"key","key":"entity"},{"type":"key","key":"room"},{"type":"key","key":"width"}]},{"type":"literal","value":100}]}]}]}]},{"type":"literal","value":4}]}]}},{"type":"traversal","steps":[{"type":"key","key":"context"},{"type":"key","key":"json"},{"type":"key","key":"traits"},{"type":"key","key":"positioned"},{"type":"key","key":"state"},{"type":"key","key":"y"}],"value":{"type":"traversal","steps":[{"type":"key","key":"global"},{"type":"key","key":"multiply"},{"type":"invoke","args":[{"type":"traversal","steps":[{"type":"key","key":"global"},{"type":"key","key":"randomNumber"},{"type":"invoke","args":[{"type":"literal","value":100},{"type":"traversal","steps":[{"type":"key","key":"global"},{"type":"key","key":"sub"},{"type":"invoke","args":[{"type":"traversal","steps":[{"type":"key","key":"entity"},{"type":"key","key":"room"},{"type":"key","key":"height"}]},{"type":"literal","value":100}]}]}]}]},{"type":"literal","value":4}]}]}},{"type":"traversal","steps":[{"type":"key","key":"entity"},{"type":"key","key":"spawn"},{"type":"invoke","args":[{"type":"literal","value":"mama"},{"type":"traversal","steps":[{"type":"key","key":"context"},{"type":"key","key":"json"}]}]}]}]}}}}}},"existent":{"state":{"name":"Mama spawner"}},"layered":{},"listed":{},"roomed":{},"spawner":{"params":{"spawns":{"mama":{"uri":"/mama-kitty.entity.json"}}},"state":{"maxSpawns":2}}}}
{"traits":{"behaved":{"params":{"routines":{"type":"routines","routines":{"initial":{"type":"routine","routine":{"type":"actions","traversals":[{"type":"traversal","steps":[{"type":"key","key":"entity"},{"type":"key","key":"spawnAt"},{"type":"invoke","args":[{"type":"literal","value":"mama"},{"type":"traversal","steps":[{"type":"key","key":"Utility"},{"type":"key","key":"makeArray"},{"type":"invoke","args":[{"type":"traversal","steps":[{"type":"key","key":"Math"},{"type":"key","key":"randomNumber"},{"type":"invoke","args":[{"type":"literal","value":100},{"type":"traversal","steps":[{"type":"key","key":"Math"},{"type":"key","key":"sub"},{"type":"invoke","args":[{"type":"traversal","steps":[{"type":"key","key":"entity"},{"type":"key","key":"room"},{"type":"key","key":"width"}]},{"type":"literal","value":100}]}]}]}]},{"type":"traversal","steps":[{"type":"key","key":"Math"},{"type":"key","key":"randomNumber"},{"type":"invoke","args":[{"type":"literal","value":100},{"type":"traversal","steps":[{"type":"key","key":"Math"},{"type":"key","key":"sub"},{"type":"invoke","args":[{"type":"traversal","steps":[{"type":"key","key":"entity"},{"type":"key","key":"room"},{"type":"key","key":"height"}]},{"type":"literal","value":100}]}]}]}]}]}]},{"type":"traversal","steps":[{"type":"key","key":"context"},{"type":"key","key":"json"}]}]}]}]}}}}}},"existent":{"state":{"name":"Mama spawner"}},"layered":{},"listed":{},"roomed":{},"spawner":{"params":{"spawns":{"mama":{"uri":"/mama-kitty.entity.json"}}},"state":{"maxSpawns":2}}}}

View File

@ -1 +1 @@
{"traits":{"alive":{"params":{"deathActions":{"type":"actions","traversals":[{"type":"traversal","steps":[{"type":"key","key":"entity"},{"type":"key","key":"playSound"},{"type":"invoke","args":[{"type":"traversal","steps":[{"type":"key","key":"entity"},{"type":"key","key":"deathSound"}]}]}]},{"type":"traversal","steps":[{"type":"key","key":"entity"},{"type":"key","key":"killAllChildren"},{"type":"invoke","args":[]}]},{"type":"traversal","steps":[{"type":"key","key":"entity"},{"type":"key","key":"transition"},{"type":"invoke","args":[{"type":"literal","value":{"opacity":0,"visibleScaleX":0.3,"visibleScaleY":3}},{"type":"literal","value":0.2}]}]}]}},"state":{"life":500,"maxLife":500}},"animated":{"params":{"animations":{"idle":{"offset":[0,-8],"uri":"/kitty.animation.json"}}}},"audible":{"params":{"sounds":{"deathSound":{"uri":"/ded.sound.json"}}}},"behaved":{"params":{"routines":{"type":"routines","routines":{"initial":{"type":"routine","routine":{"type":"actions","traversals":[{"type":"traversal","steps":[{"type":"key","key":"entity"},{"type":"key","key":"moveFor"},{"type":"invoke","args":[{"type":"traversal","steps":[{"type":"key","key":"global"},{"type":"key","key":"randomNumber"},{"type":"invoke","args":[{"type":"literal","value":0.25},{"type":"literal","value":2.5},{"type":"literal","value":false}]}]}]}]},{"type":"traversal","steps":[{"type":"key","key":"entity"},{"type":"key","key":"isAnimating"}],"value":{"type":"literal","value":false}},{"type":"traversal","steps":[{"type":"key","key":"global"},{"type":"key","key":"wait"},{"type":"invoke","args":[{"type":"traversal","steps":[{"type":"key","key":"global"},{"type":"key","key":"randomNumber"},{"type":"invoke","args":[{"type":"literal","value":1},{"type":"literal","value":4},{"type":"literal","value":false}]}]}]}]},{"type":"traversal","steps":[{"type":"key","key":"entity"},{"type":"key","key":"direction"}],"value":{"type":"traversal","steps":[{"type":"key","key":"global"},{"type":"key","key":"randomNumber"},{"type":"invoke","args":[{"type":"literal","value":0},{"type":"literal","value":3}]}]}},{"type":"traversal","steps":[{"type":"key","key":"global"},{"type":"key","key":"wait"},{"type":"invoke","args":[{"type":"traversal","steps":[{"type":"key","key":"global"},{"type":"key","key":"randomNumber"},{"type":"invoke","args":[{"type":"literal","value":0.5},{"type":"literal","value":3},{"type":"literal","value":false}]}]}]}]},{"type":"traversal","steps":[{"type":"key","key":"entity"},{"type":"key","key":"isAnimating"}],"value":{"type":"literal","value":true}},{"type":"traversal","steps":[{"type":"key","key":"context"},{"type":"key","key":"json"}],"value":{"type":"literal","value":{"traits":{"positioned":{"state":{}}}}}},{"type":"traversal","steps":[{"type":"key","key":"context"},{"type":"key","key":"json"},{"type":"key","key":"traits"},{"type":"key","key":"positioned"},{"type":"key","key":"state"},{"type":"key","key":"x"}],"value":{"type":"traversal","steps":[{"type":"key","key":"global"},{"type":"key","key":"multiply"},{"type":"invoke","args":[{"type":"traversal","steps":[{"type":"key","key":"entity"},{"type":"key","key":"x"}]},{"type":"literal","value":4}]}]}},{"type":"traversal","steps":[{"type":"key","key":"context"},{"type":"key","key":"json"},{"type":"key","key":"traits"},{"type":"key","key":"positioned"},{"type":"key","key":"state"},{"type":"key","key":"y"}],"value":{"type":"traversal","steps":[{"type":"key","key":"global"},{"type":"key","key":"multiply"},{"type":"invoke","args":[{"type":"traversal","steps":[{"type":"key","key":"entity"},{"type":"key","key":"y"}]},{"type":"literal","value":4}]}]}},{"type":"traversal","steps":[{"type":"key","key":"entity"},{"type":"key","key":"spawn"},{"type":"invoke","args":[{"type":"literal","value":"kitteh"},{"type":"traversal","steps":[{"type":"key","key":"context"},{"type":"key","key":"json"}]}]}]}]}}}}}},"collider":{},"directional":{"params":{"directionCount":4},"state":{"direction":2}},"emitter":{},"existent":{"state":{"name":"Mama Kitty"}},"visible":{"state":{"visibleScale":[2,2]}},"layered":{},"listed":{},"mobile":{"state":{"speed":40}},"physical":{},"positioned":{},"roomed":{},"shaped":{"params":{"shape":{"type":"rectangle","position":[0,0],"size":[16,8]}}},"vulnerable":{},"spawner":{"params":{"spawns":{"kitteh":{"uri":"/kitty.entity.json"}}},"state":{"maxSpawns":10}}}}
{"traits":{"alive":{"params":{"deathActions":{"type":"actions","traversals":[{"type":"traversal","steps":[{"type":"key","key":"entity"},{"type":"key","key":"playSound"},{"type":"invoke","args":[{"type":"traversal","steps":[{"type":"key","key":"entity"},{"type":"key","key":"deathSound"}]}]}]},{"type":"traversal","steps":[{"type":"key","key":"entity"},{"type":"key","key":"killAllChildren"},{"type":"invoke","args":[]}]},{"type":"traversal","steps":[{"type":"key","key":"entity"},{"type":"key","key":"transition"},{"type":"invoke","args":[{"type":"literal","value":{"opacity":0,"visibleScaleX":0.3,"visibleScaleY":3}},{"type":"literal","value":0.2}]}]}]}},"state":{"life":500,"maxLife":500}},"animated":{"params":{"animations":{"idle":{"offset":[0,-8],"uri":"/kitty.animation.json"}}}},"audible":{"params":{"sounds":{"deathSound":{"uri":"/ded.sound.json"}}}},"behaved":{"params":{"routines":{"type":"routines","routines":{"initial":{"type":"routine","routine":{"type":"actions","traversals":[{"type":"traversal","steps":[{"type":"key","key":"entity"},{"type":"key","key":"direction"}],"value":{"type":"traversal","steps":[{"type":"key","key":"Math"},{"type":"key","key":"randomNumber"},{"type":"invoke","args":[{"type":"literal","value":0},{"type":"literal","value":3}]}]}},{"type":"traversal","steps":[{"type":"key","key":"entity"},{"type":"key","key":"moveFor"},{"type":"invoke","args":[{"type":"traversal","steps":[{"type":"key","key":"Math"},{"type":"key","key":"Vector"},{"type":"key","key":"fromDirection"},{"type":"invoke","args":[{"type":"traversal","steps":[{"type":"key","key":"entity"},{"type":"key","key":"direction"}]}]}]},{"type":"traversal","steps":[{"type":"key","key":"Math"},{"type":"key","key":"randomNumber"},{"type":"invoke","args":[{"type":"literal","value":0.25},{"type":"literal","value":2.5},{"type":"literal","value":false}]}]}]}]},{"type":"traversal","steps":[{"type":"key","key":"entity"},{"type":"key","key":"isAnimating"}],"value":{"type":"literal","value":false}},{"type":"traversal","steps":[{"type":"key","key":"Timing"},{"type":"key","key":"wait"},{"type":"invoke","args":[{"type":"traversal","steps":[{"type":"key","key":"Math"},{"type":"key","key":"randomNumber"},{"type":"invoke","args":[{"type":"literal","value":1},{"type":"literal","value":4},{"type":"literal","value":false}]}]}]}]},{"type":"traversal","steps":[{"type":"key","key":"entity"},{"type":"key","key":"direction"}],"value":{"type":"traversal","steps":[{"type":"key","key":"Math"},{"type":"key","key":"randomNumber"},{"type":"invoke","args":[{"type":"literal","value":0},{"type":"literal","value":3}]}]}},{"type":"traversal","steps":[{"type":"key","key":"Timing"},{"type":"key","key":"wait"},{"type":"invoke","args":[{"type":"traversal","steps":[{"type":"key","key":"Math"},{"type":"key","key":"randomNumber"},{"type":"invoke","args":[{"type":"literal","value":0.5},{"type":"literal","value":3},{"type":"literal","value":false}]}]}]}]},{"type":"traversal","steps":[{"type":"key","key":"entity"},{"type":"key","key":"isAnimating"}],"value":{"type":"literal","value":true}},{"type":"traversal","steps":[{"type":"key","key":"entity"},{"type":"key","key":"spawnAt"},{"type":"invoke","args":[{"type":"literal","value":"kitteh"},{"type":"traversal","steps":[{"type":"key","key":"Utility"},{"type":"key","key":"makeArray"},{"type":"invoke","args":[{"type":"traversal","steps":[{"type":"key","key":"entity"},{"type":"key","key":"x"}]},{"type":"traversal","steps":[{"type":"key","key":"entity"},{"type":"key","key":"y"}]}]}]},{"type":"traversal","steps":[{"type":"key","key":"context"},{"type":"key","key":"json"}]}]}]}]}}}}}},"collider":{},"directional":{"params":{"directionCount":4},"state":{"direction":2}},"emitter":{},"existent":{"state":{"name":"Mama Kitty"}},"visible":{"state":{"visibleScale":[2,2]}},"layered":{},"listed":{},"mobile":{"state":{"speed":40}},"physical":{},"positioned":{},"roomed":{},"shaped":{"params":{"shape":{"type":"rectangle","position":[0,0],"size":[16,8]}}},"vulnerable":{},"spawner":{"params":{"spawns":{"kitteh":{"uri":"/kitty.entity.json"}}},"state":{"maxSpawns":10}}}}

View File

@ -1 +1 @@
{"traits":{"damaging":{"params":{"damageSpecs":[{"affinity":0,"lock":0,"power":-50,"variance":0.1}]}},"existent":{},"item":{"params":{"itemActions":{"type":"actions","traversals":[{"type":"traversal","steps":[{"type":"key","key":"user"},{"type":"key","key":"takeDamageFrom"},{"type":"invoke","args":[{"type":"traversal","steps":[{"type":"key","key":"item"}]}]}]},{"type":"traversal","steps":[{"type":"key","key":"item"},{"type":"key","key":"decrementQuantity"},{"type":"invoke","args":[]}]},{"type":"traversal","steps":[{"type":"key","key":"global"},{"type":"key","key":"wait"},{"type":"invoke","args":[{"type":"literal","value":0.5}]}]}]},"slotImages":{"default":"/potion.png"}}}}}
{"traits":{"damaging":{"params":{"damageSpecs":[{"affinity":0,"lock":0,"power":-50,"variance":0.1}]}},"existent":{},"item":{"params":{"cooldown":0.5,"itemActions":{"type":"actions","traversals":[{"type":"traversal","steps":[{"type":"key","key":"wielder"},{"type":"key","key":"takeDamageFrom"},{"type":"invoke","args":[{"type":"traversal","steps":[{"type":"key","key":"item"}]}]}]},{"type":"traversal","steps":[{"type":"key","key":"item"},{"type":"key","key":"decrementQuantity"},{"type":"invoke","args":[{"type":"literal","value":1}]}]}]},"slotImages":{"default":"/potion.png"}}}}}

View File

@ -0,0 +1 @@
{"traits":{"behaved":{"params":{"routines":{"type":"routines","routines":{"initial":{"type":"routine","routine":{"type":"actions","traversals":[{"type":"traversal","steps":[{"type":"key","key":"entity"},{"type":"key","key":"setDoesNotCollideWith"},{"type":"invoke","args":[{"type":"traversal","steps":[{"type":"key","key":"wielder"}]}]}]},{"type":"traversal","steps":[{"type":"key","key":"entity"},{"type":"key","key":"setPosition"},{"type":"invoke","args":[{"type":"traversal","steps":[{"type":"key","key":"wielder"},{"type":"key","key":"position"}]}]}]},{"type":"traversal","steps":[{"type":"key","key":"entity"},{"type":"key","key":"isVisible"}],"value":{"type":"literal","value":true}},{"type":"traversal","steps":[{"type":"key","key":"entity"},{"type":"key","key":"direction"}],"value":{"type":"traversal","steps":[{"type":"key","key":"wielder"},{"type":"key","key":"direction"}]}},{"type":"traversal","steps":[{"type":"key","key":"entity"},{"type":"key","key":"moveFor"},{"type":"invoke","args":[{"type":"traversal","steps":[{"type":"key","key":"Math"},{"type":"key","key":"Vector"},{"type":"key","key":"fromDirection"},{"type":"invoke","args":[{"type":"traversal","steps":[{"type":"key","key":"entity"},{"type":"key","key":"direction"}]}]}]},{"type":"literal","value":0.5}]}]},{"type":"traversal","steps":[{"type":"key","key":"entity"},{"type":"key","key":"destroy"},{"type":"invoke","args":[]}]}]}},"reflect":{"type":"routine","routine":{"type":"actions","traversals":[{"type":"traversal","steps":[{"type":"key","key":"entity"},{"type":"key","key":"isColliding"}],"value":{"type":"literal","value":false}},{"type":"traversal","steps":[{"type":"key","key":"entity"},{"type":"key","key":"isDamaging"}],"value":{"type":"literal","value":false}},{"type":"traversal","steps":[{"type":"key","key":"Flow"},{"type":"key","key":"parallel"},{"type":"invoke","args":[{"type":"actions","traversals":[{"type":"traversal","steps":[{"type":"key","key":"entity"},{"type":"key","key":"transition"},{"type":"invoke","args":[{"type":"literal","value":{"opacity":0,"speed":0}},{"type":"literal","value":0.2}]}]},{"type":"traversal","steps":[{"type":"key","key":"entity"},{"type":"key","key":"moveFor"},{"type":"invoke","args":[{"type":"traversal","steps":[{"type":"key","key":"Math"},{"type":"key","key":"Vector"},{"type":"key","key":"sub"},{"type":"invoke","args":[{"type":"traversal","steps":[{"type":"key","key":"entity"},{"type":"key","key":"position"}]},{"type":"traversal","steps":[{"type":"key","key":"obstacle"},{"type":"key","key":"position"}]}]}]},{"type":"literal","value":0.2}]}]}]}]}]},{"type":"traversal","steps":[{"type":"key","key":"entity"},{"type":"key","key":"destroy"},{"type":"invoke","args":[]}]}]}}}}},"state":{"isBehaving":false}},"collider":{"params":{"collisionStartActions":{"type":"actions","traversals":[{"type":"traversal","steps":[{"type":"key","key":"entity"},{"type":"key","key":"context"},{"type":"key","key":"add"},{"type":"invoke","args":[{"type":"literal","value":"obstacle"},{"type":"traversal","steps":[{"type":"key","key":"other"}]}]}]},{"type":"traversal","steps":[{"type":"key","key":"entity"},{"type":"key","key":"currentRoutine"}],"value":{"type":"literal","value":"reflect"}}]},"isSensor":true}},"damaging":{"params":{"damageSpecs":[{"affinity":0,"knockback":500,"lock":1,"power":50,"variance":0.1}]}},"directional":{"params":{"directionCount":4}},"existent":{"state":{"name":"Rock (projectile)"}},"layered":{},"listed":{},"mobile":{"state":{"speed":200}},"physical":{},"pictured":{"params":{"images":{"initial":{"offset":[0,0],"size":[12,12],"uri":"/rock.png"}}}},"positioned":{},"roomed":{},"shaped":{"params":{"shape":{"type":"rectangle","position":[0,0],"size":[12,12]}}},"visible":{"state":{"isVisible":false}}}}

View File

@ -1 +1 @@
{"traits":{"collider":{"params":{"isSensor":true}},"damaging":{"params":{"damageSpecs":[{"affinity":0,"lock":0.25,"power":50,"variance":0.1}]}},"directional":{"params":{"directionCount":4}},"existent":{"state":{"name":"Rock"}},"item":{"params":{"itemActions":{"type":"actions","traversals":[{"type":"traversal","steps":[{"type":"key","key":"item"},{"type":"key","key":"setDoesNotDamage"},{"type":"invoke","args":[{"type":"traversal","steps":[{"type":"key","key":"user"}]}]}]},{"type":"traversal","steps":[{"type":"key","key":"user"},{"type":"key","key":"list"},{"type":"key","key":"addEntity"},{"type":"invoke","args":[{"type":"traversal","steps":[{"type":"key","key":"item"}]}]}]},{"type":"traversal","steps":[{"type":"key","key":"item"},{"type":"key","key":"setPosition"},{"type":"invoke","args":[{"type":"traversal","steps":[{"type":"key","key":"user"},{"type":"key","key":"position"}]}]}]},{"type":"traversal","steps":[{"type":"key","key":"item"},{"type":"key","key":"direction"}],"value":{"type":"traversal","steps":[{"type":"key","key":"user"},{"type":"key","key":"direction"}]}},{"type":"traversal","steps":[{"type":"key","key":"item"},{"type":"key","key":"moveFor"},{"type":"invoke","args":[{"type":"literal","value":0.5}]}]},{"type":"traversal","steps":[{"type":"key","key":"user"},{"type":"key","key":"list"},{"type":"key","key":"removeEntity"},{"type":"invoke","args":[{"type":"traversal","steps":[{"type":"key","key":"item"}]}]}]}]},"slotImages":{"default":"/rock.png"}}},"layered":{},"listed":{},"mobile":{"state":{"speed":200}},"physical":{},"pictured":{"params":{"images":{"initial":{"offset":[0,0],"size":[12,12],"uri":"/rock.png"}}}},"positioned":{},"roomed":{},"shaped":{"params":{"shape":{"type":"rectangle","position":[0,0],"size":[12,12]}}},"visible":{}}}
{"traits":{"collider":{"params":{"isSensor":true}},"existent":{"state":{"name":"Rock"}},"item":{"params":{"cooldown":0.33,"itemActions":{"type":"actions","traversals":[{"type":"traversal","steps":[{"type":"key","key":"context"},{"type":"key","key":"add"},{"type":"invoke","args":[{"type":"literal","value":"projectile"},{"type":"traversal","steps":[{"type":"key","key":"item"},{"type":"key","key":"spawn"},{"type":"invoke","args":[{"type":"literal","value":"rock"}]}]}]}]},{"type":"traversal","steps":[{"type":"key","key":"projectile"},{"type":"key","key":"context"},{"type":"key","key":"add"},{"type":"invoke","args":[{"type":"literal","value":"wielder"},{"type":"traversal","steps":[{"type":"key","key":"wielder"}]}]}]},{"type":"traversal","steps":[{"type":"key","key":"projectile"},{"type":"key","key":"isBehaving"}],"value":{"type":"literal","value":true}}]},"slotImages":{"default":"/rock.png"}}},"layered":{},"listed":{},"magnetic":{},"mobile":{},"physical":{},"pictured":{"params":{"images":{"initial":{"offset":[0,0],"size":[12,12],"uri":"/rock.png"}}}},"positioned":{},"roomed":{},"shaped":{"params":{"shape":{"type":"rectangle","position":[0,0],"size":[12,12]}}},"spawner":{"params":{"spawns":{"rock":{"uri":"/rock-projectile.entity.json"}}}},"visible":{}}}

View File

@ -0,0 +1 @@
{"traits":{"existent":{"state":{"name":"Tomato plant"}},"layered":{},"listed":{},"pictured":{"params":{"images":{"initial":{"offset":[0,0],"size":[16,16],"uri":"/tomato-stage-0.png"},"stage-1":{"offset":[0,3],"size":[16,16],"uri":"/tomato-stage-1.png"},"stage-2":{"offset":[0,3],"size":[16,16],"uri":"/tomato-stage-2.png"},"stage-3":{"offset":[0,3],"size":[16,16],"uri":"/tomato-stage-3.png"},"stage-4":{"offset":[0,3],"size":[16,16],"uri":"/tomato-stage-4.png"}}}},"plant":{"params":{"stageSpecs":{"0":{"growAt":2,"image":"initial"},"1":{"growAt":4,"image":"stage-1"},"2":{"growAt":6,"image":"stage-2"},"3":{"growAt":8,"image":"stage-3"},"4":{"image":"stage-4"}}}},"positioned":{},"roomed":{},"tile-entity":{},"visible":{}}}

View File

@ -0,0 +1 @@
{"traits":{"existent":{},"item":{"params":{"itemActions":{"type":"actions","traversals":[{"type":"traversal","steps":[{"type":"key","key":"item"},{"type":"key","key":"useTool"},{"type":"invoke","args":[]}]}]},"slotImages":{"default":"/seeds.png"}}},"spawner":{"params":{"spawns":{"tomato-plant":{"uri":"/tomato-plant.entity.json"}}}},"tool":{"params":{"condition":{"type":"condition","operator":"and","operands":[{"type":"condition","operator":"is","operands":[{"type":"literal","value":7},{"type":"traversal","steps":[{"type":"key","key":"wielder"},{"type":"key","key":"layer"},{"type":"key","key":"tileAt"},{"type":"invoke","args":[{"type":"traversal","steps":[{"type":"key","key":"target"}]}]}]}]},{"type":"condition","operator":"is","operands":[{"type":"literal","value":false},{"type":"traversal","steps":[{"type":"key","key":"wielder"},{"type":"key","key":"layer"},{"type":"key","key":"hasTileEntityWithUriAt"},{"type":"invoke","args":[{"type":"traversal","steps":[{"type":"key","key":"target"}]},{"type":"literal","value":"/tomato-plant.entity.json"}]}]}]}]},"actions":{"type":"actions","traversals":[{"type":"traversal","steps":[{"type":"key","key":"item"},{"type":"key","key":"spawnAt"},{"type":"invoke","args":[{"type":"literal","value":"tomato-plant"},{"type":"traversal","steps":[{"type":"key","key":"Math"},{"type":"key","key":"Vector"},{"type":"key","key":"add"},{"type":"invoke","args":[{"type":"traversal","steps":[{"type":"key","key":"Math"},{"type":"key","key":"Vector"},{"type":"key","key":"mul"},{"type":"invoke","args":[{"type":"traversal","steps":[{"type":"key","key":"target"}]},{"type":"traversal","steps":[{"type":"key","key":"wielder"},{"type":"key","key":"layer"},{"type":"key","key":"tileset"},{"type":"key","key":"tileSize"}]}]}]},{"type":"traversal","steps":[{"type":"key","key":"Math"},{"type":"key","key":"Vector"},{"type":"key","key":"scale"},{"type":"invoke","args":[{"type":"traversal","steps":[{"type":"key","key":"wielder"},{"type":"key","key":"layer"},{"type":"key","key":"tileset"},{"type":"key","key":"tileSize"}]},{"type":"literal","value":0.5}]}]}]}]}]}]}]},"target":{"type":"projection","distance":-1,"length":3,"width":3}}}}}

View File

@ -0,0 +1 @@
{"traits":{"existent":{},"item":{"params":{"itemActions":{"type":"actions","traversals":[{"type":"traversal","steps":[{"type":"key","key":"item"},{"type":"key","key":"useTool"},{"type":"invoke","args":[]}]}]},"slotImages":{"default":"/watering-can.png"}}},"tool":{"params":{"condition":{"type":"condition","operator":"is","operands":[{"type":"literal","value":6},{"type":"traversal","steps":[{"type":"key","key":"wielder"},{"type":"key","key":"layer"},{"type":"key","key":"tileAt"},{"type":"invoke","args":[{"type":"traversal","steps":[{"type":"key","key":"target"}]}]}]}]},"actions":{"type":"actions","traversals":[{"type":"traversal","steps":[{"type":"key","key":"wielder"},{"type":"key","key":"layer"},{"type":"key","key":"setTileAt"},{"type":"invoke","args":[{"type":"traversal","steps":[{"type":"key","key":"target"}]},{"type":"literal","value":7}]}]}]},"target":{"type":"projection","distance":1,"length":1,"width":1}}}}}

View File

@ -61,20 +61,20 @@ export function kittyFireJSON() {
roomJSON.layers[0].entities.push(positionedEntityJSON(uri, position));
}
for (let i = 0; i < 20; ++i) {
addEntityWithRandomPosition('/rock.entity.json');
}
for (let i = 0; i < 20; ++i) {
addEntityWithRandomPosition('/flower-barrel.entity.json');
}
// for (let i = 0; i < 20; ++i) {
// addEntityWithRandomPosition('/rock.entity.json');
// }
// for (let i = 0; i < 20; ++i) {
// addEntityWithRandomPosition('/flower-barrel.entity.json');
// }
for (let i = 0; i < 3; ++i) {
addEntityWithRandomPosition('/mama-kitty-spawner.entity.json');
}
for (let i = 0; i < 5; ++i) {
addEntityWithRandomPosition('/fire.entity.json');
}
for (let i = 0; i < 1; ++i) {
addEntityWithRandomPosition('/blue-fire.entity.json');
}
// for (let i = 0; i < 1; ++i) {
// addEntityWithRandomPosition('/blue-fire.entity.json');
// }
return roomJSON;
}

View File

@ -5,12 +5,11 @@ import {performance} from 'perf_hooks';
// 2nd party.
import {InputPacket} from '@avocado/input';
import {World} from '@avocado/physics/matter/world';
import {Synchronizer} from '@avocado/state';
import {Ticker} from '@avocado/timing';
import {Room} from '@avocado/topdown';
// 1st party.
import {SelfEntityPacket} from '../common/packets/self-entity.packet';
import {WorldTime} from '../common/world-time';
import {WorldTime} from '../common/world-time.synchronized';
import {createEntityForConnection} from './create-entity-for-connection';
// Create game.
export default class Game {
@ -22,7 +21,6 @@ export default class Game {
Room.load('/kitty-fire.room.json').then((room) => {
room.world = new World();
room.world.stepTime = config.simulationInterval;
this.synchronizer.addChild(room);
this.room = room;
});
// World time. Start at 10 am for testing.
@ -31,9 +29,6 @@ export default class Game {
// Entity tracking.
this.informables = [];
// State synchronization.
this.synchronizer = new Synchronizer([
this.worldTime,
]);
this.informTicker = new Ticker(config.informInterval);
this.informTicker.on('tick', this.inform, this);
// Simulation.
@ -62,14 +57,14 @@ export default class Game {
this.informables.splice(index, 1);
}
});
// Sync world time.
entity.addSynchronized(this.worldTime);
// Add entity to room.
if (this.room) {
this.room.addEntityToLayer(entity, 0);
}
// Initial information.
const packets = this.synchronizer.packetsForUpdate(true);
packets.unshift(new SelfEntityPacket(entity.numericUid));
entity.inform(packets);
entity.inform();
// Listen for events.
socket.on('packet', this.createPacketListener(socket));
socket.on('disconnect', this.createDisconnectionListener(socket));
@ -110,12 +105,12 @@ export default class Game {
}
inform() {
const packets = this.synchronizer.packetsForUpdate();
// Inform entities of the new state.
for (let i = 0; i < this.informables.length; ++i) {
const entity = this.informables[i];
entity.inform(packets);
this.informables[i].inform();
}
// Clean packets.
this.worldTime.cleanPackets();
}
readConfig() {

View File

@ -6,8 +6,7 @@ import immutablediff from 'immutablediff';
import {compose} from '@avocado/core';
import {EntityCreatePacket, EntityPacket, EntityRemovePacket, Trait} from '@avocado/entity';
import {Rectangle, Vector} from '@avocado/math';
import {BundlePacket} from '@avocado/net';
import {Synchronizer} from '@avocado/state';
import {BundlePacket, ServerSynchronizer} from '@avocado/net';
const decorate = compose(
);
@ -22,6 +21,7 @@ export class Informed extends decorate(Trait) {
super(entity, params, state);
this.seenEntities = [];
this._socket = undefined;
this._synchronizer = new ServerSynchronizer();
}
destroy() {
@ -29,6 +29,7 @@ export class Informed extends decorate(Trait) {
delete this._socket.entity;
delete this._socket;
}
this._synchronizer.destroy();
}
get areaToInform() {
@ -62,6 +63,44 @@ export class Informed extends decorate(Trait) {
});
}
filter(packets) {
packets = packets.filter((packet) => {
return !(packet instanceof EntityPacket);
});
// // Filter invisible entities.
// packets = this.filterInvisibleEntityPackets(packets);
// // Reduce entities by range.
// const [
// inRangeEntities,
// outOfRangeEntities,
// visibleEntities,
// ] = this.reducePacketEntitiesByRange(packets);
// // TODO? Upgrade seen entity packets that are out of range to entity
// // remembers.
// // Filter the out of range entity updates.
// packets = this.filterOutOfRangeEntityPackets(
// packets,
// outOfRangeEntities
// );
// // Deduplicate entity creates.
// packets = this.deduplicateEntityCreatePackets(packets);
// // Filter known creates.
// packets = this.filterKnownEntityCreatePackets(packets);
// // Inject create packets.
// packets = this.injectEntityCreatePackets(packets, visibleEntities);
// // Inject removes for any previously seen entity that isn't visible
// // anymore.
// packets = this.injectEntityRemovePackets(packets, visibleEntities);
// // "See" entities.
// this.markEntitiesSeen(visibleEntities);
// // Unsee any removed entities.
// this.markEntitiesUnseen(packets);
return packets;
}
filterInvisibleEntityPackets(packets) {
return packets.filter((packet) => {
const entity = packet.entity;
@ -262,46 +301,34 @@ export class Informed extends decorate(Trait) {
methods() {
return {
inform: (packets) => {
if (0 === packets.length) {
inform: () => {
const payload = this._synchronizer.packetsFor(this.entity);
// const payload = [];
// for (let i = 0; i < this._willWatch.length; i++) {
// const packets = this._willWatch[i].packets(this.entity);
// for (let j = 0; j < packets.length; j++) {
// payload.push(packets[j]);
// }
// }
// for (let i = 0; i < this._watching.length; i++) {
// const packets = this._watching[i].packets(this.entity);
// for (let j = 0; j < packets.length; j++) {
// payload.push(packets[j]);
// }
// }
// for (let i = 0; i < this._willWatch.length; i++) {
// this._watching.push(this._willWatch[i]);
// }
// this._willWatch = [];
// // Clean all packets.
// for (let i = 0; i < this._watching.length; i++) {
// this._watching[i].cleanPackets();
// }
if (0 === payload.length) {
return;
}
// TODO: filter packets that are only delivered to self entity.
// Filter invisible entities.
packets = this.filterInvisibleEntityPackets(packets);
// Reduce entities by range.
const [
inRangeEntities,
outOfRangeEntities,
visibleEntities,
] = this.reducePacketEntitiesByRange(packets);
// TODO? Upgrade seen entity packets that are out of range to entity
// remembers.
// Filter the out of range entity updates.
packets = this.filterOutOfRangeEntityPackets(
packets,
outOfRangeEntities
);
// Deduplicate entity creates.
packets = this.deduplicateEntityCreatePackets(packets);
// Filter known creates.
packets = this.filterKnownEntityCreatePackets(packets);
// Inject create packets.
packets = this.injectEntityCreatePackets(packets, visibleEntities);
// Inject removes for any previously seen entity that isn't visible
// anymore.
packets = this.injectEntityRemovePackets(packets, visibleEntities);
// "See" entities.
this.markEntitiesSeen(visibleEntities);
// Unsee any removed entities.
this.markEntitiesUnseen(packets);
// Ship it!
if (this._socket) {
this._socket.send(new BundlePacket(packets));
this._socket.send(new BundlePacket(payload));
}
},
@ -310,7 +337,15 @@ export class Informed extends decorate(Trait) {
this.entity.areaToInform,
entity.visibleAabb
);
}
},
addSynchronized: (synchronized) => {
this._synchronizer.addSynchronized(synchronized);
},
removeSynchronized: (synchronized) => {
this._synchronizer.removeSynchronized(synchronized);
},
};
}

View File

@ -9,6 +9,7 @@ config.entry = {
client: [
'@babel/polyfill',
'register-packets',
'register-synchronizeds',
'register-traits',
'@avocado/behavior/item/initialize',
path.join(__dirname, 'client', 'index.js'),
@ -46,6 +47,9 @@ config.module.rules[1].use.options.paths.push(
config.module.rules[2].use.options.paths.push(
path.resolve(__dirname, 'client'),
);
config.module.rules[3].use.options.paths.push(
path.resolve(__dirname, 'client'),
);
config.node = {
fs: 'empty',
path: 'empty',

View File

@ -37,6 +37,22 @@ const config = {
},
},
},
{
test: /register-synchronizeds\.js$/,
use: {
loader: './defgen',
options: {
paths: [
path.resolve(__dirname, 'common'),
],
registrar: {
function: 'registerSynchronized',
module: '@avocado/net',
},
type: 'synchronized',
},
},
},
{
test: /register-traits\.js$/,
use: {
@ -64,8 +80,9 @@ const config = {
plugins: [],
resolve: {
alias: {
'register-packets': path.resolve(__dirname, 'register-packets'),
'register-traits': path.resolve(__dirname, 'register-traits'),
'register-packets': path.join(__dirname, 'register-packets'),
'register-synchronizeds': path.join(__dirname, 'register-synchronizeds'),
'register-traits': path.join(__dirname, 'register-traits'),
},
modules: [path.resolve(__dirname, 'node_modules')],
},

View File

@ -12,6 +12,7 @@ config.entry = {
'source-map-support/register',
'@babel/polyfill',
path.join(__dirname, 'register-packets.js'),
path.join(__dirname, 'register-synchronizeds.js'),
'@avocado/behavior/item/initialize',
path.join(__dirname, 'server', 'index.js'),
],
@ -34,6 +35,9 @@ config.module.rules[1].use.options.paths.push(
config.module.rules[2].use.options.paths.push(
path.resolve(__dirname, 'server'),
);
config.module.rules[3].use.options.paths.push(
path.resolve(__dirname, 'server'),
);
const nodeArgs = ['--preserve-symlinks'];
if (process.argv.find((arg) => '--prof' === arg)) {
nodeArgs.push('--prof');