@crowdedkingdoms/crowdyjs 18.10.0 → 18.12.0-dev.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/MIGRATION.md +69 -0
- package/README.md +91 -30
- package/dist/crowdy-client.d.ts +11 -3
- package/dist/crowdy-client.d.ts.map +1 -1
- package/dist/crowdy-client.js +25 -4
- package/dist/default-origin.d.ts +6 -6
- package/dist/default-origin.d.ts.map +1 -1
- package/dist/default-origin.js +6 -6
- package/dist/domains/exec.d.ts +6 -0
- package/dist/domains/exec.d.ts.map +1 -1
- package/dist/domains/exec.js +28 -2
- package/dist/generated/graphql-schema.d.ts +1 -1
- package/dist/generated/graphql-schema.d.ts.map +1 -1
- package/dist/index.d.ts +3 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -3
- package/dist/kit/index.d.ts +22 -2
- package/dist/kit/index.d.ts.map +1 -1
- package/dist/kit/index.js +22 -2
- package/dist/kit/kit.d.ts +141 -7
- package/dist/kit/kit.d.ts.map +1 -1
- package/dist/kit/kit.js +138 -4
- package/dist/kit/mirror.d.ts +111 -0
- package/dist/kit/mirror.d.ts.map +1 -0
- package/dist/kit/mirror.js +295 -0
- package/dist/kit/modules/arenas.d.ts +87 -0
- package/dist/kit/modules/arenas.d.ts.map +1 -0
- package/dist/kit/modules/arenas.js +66 -0
- package/dist/kit/modules/encounters.d.ts +75 -0
- package/dist/kit/modules/encounters.d.ts.map +1 -0
- package/dist/kit/modules/encounters.js +57 -0
- package/dist/kit/modules/instances.d.ts +78 -0
- package/dist/kit/modules/instances.d.ts.map +1 -0
- package/dist/kit/modules/instances.js +72 -0
- package/dist/kit/modules/leaderboards.d.ts +79 -0
- package/dist/kit/modules/leaderboards.d.ts.map +1 -0
- package/dist/kit/modules/leaderboards.js +69 -0
- package/dist/kit/modules/matchmaking.d.ts +107 -0
- package/dist/kit/modules/matchmaking.d.ts.map +1 -0
- package/dist/kit/modules/matchmaking.js +109 -0
- package/dist/kit/modules/minigames.d.ts +59 -0
- package/dist/kit/modules/minigames.d.ts.map +1 -0
- package/dist/kit/modules/minigames.js +55 -0
- package/dist/kit/modules/npcs.d.ts +80 -0
- package/dist/kit/modules/npcs.d.ts.map +1 -0
- package/dist/kit/modules/npcs.js +102 -0
- package/dist/kit/modules/presence.d.ts +81 -0
- package/dist/kit/modules/presence.d.ts.map +1 -0
- package/dist/kit/modules/presence.js +99 -0
- package/dist/kit/modules/racing.d.ts +131 -0
- package/dist/kit/modules/racing.d.ts.map +1 -0
- package/dist/kit/modules/racing.js +113 -0
- package/dist/kit/modules/sessions.d.ts +91 -0
- package/dist/kit/modules/sessions.d.ts.map +1 -0
- package/dist/kit/modules/sessions.js +84 -0
- package/dist/kit/modules/tables.d.ts +76 -0
- package/dist/kit/modules/tables.d.ts.map +1 -0
- package/dist/kit/modules/tables.js +73 -0
- package/dist/kit/modules/tactics.d.ts +79 -0
- package/dist/kit/modules/tactics.d.ts.map +1 -0
- package/dist/kit/modules/tactics.js +67 -0
- package/dist/kit/modules/territory.d.ts +92 -0
- package/dist/kit/modules/territory.d.ts.map +1 -0
- package/dist/kit/modules/territory.js +84 -0
- package/dist/kit/modules/world.d.ts +69 -0
- package/dist/kit/modules/world.d.ts.map +1 -0
- package/dist/kit/modules/world.js +35 -0
- package/dist/kit/protocol.d.ts +128 -0
- package/dist/kit/protocol.d.ts.map +1 -0
- package/dist/kit/protocol.js +171 -0
- package/dist/kit/realtime.d.ts +72 -0
- package/dist/kit/realtime.d.ts.map +1 -0
- package/dist/kit/realtime.js +108 -0
- package/dist/kit/runtime.d.ts +90 -0
- package/dist/kit/runtime.d.ts.map +1 -0
- package/dist/kit/runtime.js +194 -0
- package/dist/kit/store.d.ts +20 -0
- package/dist/kit/store.d.ts.map +1 -0
- package/dist/kit/store.js +25 -0
- package/dist/kit/topology.d.ts +69 -0
- package/dist/kit/topology.d.ts.map +1 -0
- package/dist/kit/topology.js +156 -0
- package/dist/kit/wire.d.ts +45 -5
- package/dist/kit/wire.d.ts.map +1 -1
- package/dist/kit/wire.js +51 -5
- package/dist/live-coding/assets/browser-authoring-index.json +1 -1
- package/dist/live-coding/assets/manifest.json +1 -1
- package/dist/live-coding/browser-authoring-index.generated.d.ts.map +1 -1
- package/dist/live-coding/browser-authoring-index.generated.js +5092 -45
- package/package.json +1 -1
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { HubState } from '../mirror.js';
|
|
2
|
+
/** Two-player duels of hidden throws (the `minigame` starter): {@link duel} by table. */
|
|
3
|
+
export class MinigamesKit {
|
|
4
|
+
constructor(runtime, nodeType = 'minigame') {
|
|
5
|
+
this.runtime = runtime;
|
|
6
|
+
this.nodeType = nodeType;
|
|
7
|
+
this.duels = new Map();
|
|
8
|
+
}
|
|
9
|
+
duel(key) {
|
|
10
|
+
let d = this.duels.get(key);
|
|
11
|
+
if (!d) {
|
|
12
|
+
d = new Duel(this.runtime, this.nodeType, key);
|
|
13
|
+
this.duels.set(key, d);
|
|
14
|
+
}
|
|
15
|
+
return d;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* One duel: the hub keeps each round's throws until both are in (or the round's time runs out),
|
|
20
|
+
* then reveals them; the first to win a majority of `best_of` rounds wins. The starter's game is
|
|
21
|
+
* rock, paper, scissors.
|
|
22
|
+
*/
|
|
23
|
+
export class Duel {
|
|
24
|
+
constructor(runtime, nodeType, key) {
|
|
25
|
+
this.runtime = runtime;
|
|
26
|
+
this.nodeType = nodeType;
|
|
27
|
+
this.key = key;
|
|
28
|
+
this.view = new HubState(runtime, nodeType, key, 'duel');
|
|
29
|
+
}
|
|
30
|
+
watch() {
|
|
31
|
+
return this.view.start();
|
|
32
|
+
}
|
|
33
|
+
unwatch() {
|
|
34
|
+
return this.view.stop();
|
|
35
|
+
}
|
|
36
|
+
/** Takes a seat; resolves with whether this seat started the first round. @throws {KitError} `full`. */
|
|
37
|
+
join() {
|
|
38
|
+
return this.runtime.call(this.nodeType, this.key, 'join', null, { action: true });
|
|
39
|
+
}
|
|
40
|
+
/** Before the duel starts. @throws {KitError} `started`. */
|
|
41
|
+
leave() {
|
|
42
|
+
return this.runtime.call(this.nodeType, this.key, 'leave', null, { action: true });
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* The caller's hidden throw this round; resolves with whether it completed the round.
|
|
46
|
+
* @throws {KitError} `conflict` (already in, or no round open), `bad_request` (not a hand), `not_member`.
|
|
47
|
+
*/
|
|
48
|
+
throw(hand) {
|
|
49
|
+
return this.runtime.call(this.nodeType, this.key, 'throw', { hand }, { action: true });
|
|
50
|
+
}
|
|
51
|
+
/** Once it is over: play again. @throws {KitError} `conflict`, `not_member`. */
|
|
52
|
+
rematch() {
|
|
53
|
+
return this.runtime.call(this.nodeType, this.key, 'rematch', null, { action: true });
|
|
54
|
+
}
|
|
55
|
+
}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { CollectionMirror } from '../mirror.js';
|
|
2
|
+
import { type KitContainer } from '../protocol.js';
|
|
3
|
+
import type { KitRuntime } from '../runtime.js';
|
|
4
|
+
/** A pet as its owner reads it: the public view and its bond. */
|
|
5
|
+
export interface KitPetView {
|
|
6
|
+
id: number;
|
|
7
|
+
species: string;
|
|
8
|
+
name: string;
|
|
9
|
+
x: number;
|
|
10
|
+
z: number;
|
|
11
|
+
/** `follow` while summoned, else `stay`. */
|
|
12
|
+
mode: string;
|
|
13
|
+
bond: number;
|
|
14
|
+
}
|
|
15
|
+
/** Where the area hubs are: type `npcs`, keyed by area centre chunk, in the starter pack. */
|
|
16
|
+
export interface NpcsKitOptions {
|
|
17
|
+
nodeType?: string;
|
|
18
|
+
/** An area's size in chunks, for {@link NpcsKit.areaAt}. Default 8. */
|
|
19
|
+
areaSize?: number;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* The world's areas of mobs, NPCs and pets (the `npc-mobs` starter): one hub per area,
|
|
23
|
+
* keyed by its centre chunk, so a client finds the hub for where it stands
|
|
24
|
+
* ({@link areaAt}) without asking.
|
|
25
|
+
*/
|
|
26
|
+
export declare class NpcsKit {
|
|
27
|
+
private readonly runtime;
|
|
28
|
+
private readonly areas;
|
|
29
|
+
private readonly nodeType;
|
|
30
|
+
private readonly size;
|
|
31
|
+
constructor(runtime: KitRuntime, options?: NpcsKitOptions);
|
|
32
|
+
/** The key of the area holding chunk `(chunkX, chunkZ)`. */
|
|
33
|
+
keyAt(chunkX: number, chunkZ: number): string;
|
|
34
|
+
/** The area holding chunk `(chunkX, chunkZ)`. */
|
|
35
|
+
areaAt(chunkX: number, chunkZ: number): NpcArea;
|
|
36
|
+
/** The area with key `key` (`"<x>,<z>"`, its centre chunk). */
|
|
37
|
+
area(key: string): NpcArea;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* One area: its mobs, NPCs and pets mirrored from the `area` topic ({@link members}), hits
|
|
41
|
+
* on mobs (the hub decides reach, cooldown and damage), NPC talk, and the player's pets.
|
|
42
|
+
* The hub also shows its actors through the realtime tier (`kitActorCodec`).
|
|
43
|
+
*/
|
|
44
|
+
export declare class NpcArea {
|
|
45
|
+
private readonly runtime;
|
|
46
|
+
readonly nodeType: string;
|
|
47
|
+
readonly key: string;
|
|
48
|
+
/** The `area` topic: every member's public properties, by id. */
|
|
49
|
+
readonly members: CollectionMirror;
|
|
50
|
+
constructor(runtime: KitRuntime, nodeType: string, key: string);
|
|
51
|
+
/** Mirrors the area. */
|
|
52
|
+
watch(): Promise<void>;
|
|
53
|
+
unwatch(): Promise<void>;
|
|
54
|
+
mobs(): KitContainer[];
|
|
55
|
+
npcs(): KitContainer[];
|
|
56
|
+
pets(): KitContainer[];
|
|
57
|
+
/**
|
|
58
|
+
* Hits mob `mob`; resolves with its hp after the hit.
|
|
59
|
+
* @throws {KitError} `not_in_area`, `out_of_reach`, `cooldown`, `down`, `not_found`.
|
|
60
|
+
*/
|
|
61
|
+
attack(mob: number): Promise<number>;
|
|
62
|
+
/** What NPC `npc` says, with its public properties. */
|
|
63
|
+
talk(npc: number): Promise<Record<string, unknown>>;
|
|
64
|
+
/**
|
|
65
|
+
* Adopts a pet where the player stands; resolves with its id.
|
|
66
|
+
* @throws {KitError} `not_in_area`, `limit` (pets a player), `full`, `bad_request`.
|
|
67
|
+
*/
|
|
68
|
+
adopt(species: string, name: string): Promise<number>;
|
|
69
|
+
rename(pet: number, name: string): Promise<boolean>;
|
|
70
|
+
/** The pet follows its owner (and its bond grows). */
|
|
71
|
+
summon(pet: number): Promise<boolean>;
|
|
72
|
+
/** The pet stays where it is. */
|
|
73
|
+
dismiss(pet: number): Promise<boolean>;
|
|
74
|
+
/** The pet is gone. */
|
|
75
|
+
release(pet: number): Promise<boolean>;
|
|
76
|
+
/** The player's pets in this area, with their bond. */
|
|
77
|
+
myPets(): Promise<KitPetView[]>;
|
|
78
|
+
private pet;
|
|
79
|
+
}
|
|
80
|
+
//# sourceMappingURL=npcs.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"npcs.d.ts","sourceRoot":"","sources":["../../../src/kit/modules/npcs.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAChD,OAAO,EAAY,KAAK,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC7D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAEhD,iEAAiE;AACjE,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,4CAA4C;IAC5C,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CACd;AAED,6FAA6F;AAC7F,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,uEAAuE;IACvE,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;;;GAIG;AACH,qBAAa,OAAO;IAMhB,OAAO,CAAC,QAAQ,CAAC,OAAO;IAL1B,OAAO,CAAC,QAAQ,CAAC,KAAK,CAA8B;IACpD,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;IAClC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAS;gBAGX,OAAO,EAAE,UAAU,EACpC,OAAO,GAAE,cAAmB;IAM9B,4DAA4D;IAC5D,KAAK,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM;IAI7C,iDAAiD;IACjD,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO;IAI/C,+DAA+D;IAC/D,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO;CAQ3B;AAED;;;;GAIG;AACH,qBAAa,OAAO;IAKhB,OAAO,CAAC,QAAQ,CAAC,OAAO;IACxB,QAAQ,CAAC,QAAQ,EAAE,MAAM;IACzB,QAAQ,CAAC,GAAG,EAAE,MAAM;IANtB,iEAAiE;IACjE,QAAQ,CAAC,OAAO,EAAE,gBAAgB,CAAC;gBAGhB,OAAO,EAAE,UAAU,EAC3B,QAAQ,EAAE,MAAM,EAChB,GAAG,EAAE,MAAM;IAKtB,wBAAwB;IAClB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAI5B,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAIxB,IAAI,IAAI,YAAY,EAAE;IAItB,IAAI,IAAI,YAAY,EAAE;IAItB,IAAI,IAAI,YAAY,EAAE;IAItB;;;OAGG;IACH,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAIpC,uDAAuD;IACvD,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAInD;;;OAGG;IACH,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAIrD,MAAM,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAInD,sDAAsD;IACtD,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAIrC,iCAAiC;IACjC,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAItC,uBAAuB;IACvB,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAItC,uDAAuD;IACvD,MAAM,IAAI,OAAO,CAAC,UAAU,EAAE,CAAC;IAI/B,OAAO,CAAC,GAAG;CAIZ"}
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import { CollectionMirror } from '../mirror.js';
|
|
2
|
+
import { shardKey } from '../protocol.js';
|
|
3
|
+
/**
|
|
4
|
+
* The world's areas of mobs, NPCs and pets (the `npc-mobs` starter): one hub per area,
|
|
5
|
+
* keyed by its centre chunk, so a client finds the hub for where it stands
|
|
6
|
+
* ({@link areaAt}) without asking.
|
|
7
|
+
*/
|
|
8
|
+
export class NpcsKit {
|
|
9
|
+
constructor(runtime, options = {}) {
|
|
10
|
+
this.runtime = runtime;
|
|
11
|
+
this.areas = new Map();
|
|
12
|
+
this.nodeType = options.nodeType ?? 'npcs';
|
|
13
|
+
this.size = Math.max(1, options.areaSize ?? 8);
|
|
14
|
+
}
|
|
15
|
+
/** The key of the area holding chunk `(chunkX, chunkZ)`. */
|
|
16
|
+
keyAt(chunkX, chunkZ) {
|
|
17
|
+
return shardKey(chunkX, chunkZ, this.size);
|
|
18
|
+
}
|
|
19
|
+
/** The area holding chunk `(chunkX, chunkZ)`. */
|
|
20
|
+
areaAt(chunkX, chunkZ) {
|
|
21
|
+
return this.area(this.keyAt(chunkX, chunkZ));
|
|
22
|
+
}
|
|
23
|
+
/** The area with key `key` (`"<x>,<z>"`, its centre chunk). */
|
|
24
|
+
area(key) {
|
|
25
|
+
let a = this.areas.get(key);
|
|
26
|
+
if (!a) {
|
|
27
|
+
a = new NpcArea(this.runtime, this.nodeType, key);
|
|
28
|
+
this.areas.set(key, a);
|
|
29
|
+
}
|
|
30
|
+
return a;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* One area: its mobs, NPCs and pets mirrored from the `area` topic ({@link members}), hits
|
|
35
|
+
* on mobs (the hub decides reach, cooldown and damage), NPC talk, and the player's pets.
|
|
36
|
+
* The hub also shows its actors through the realtime tier (`kitActorCodec`).
|
|
37
|
+
*/
|
|
38
|
+
export class NpcArea {
|
|
39
|
+
constructor(runtime, nodeType, key) {
|
|
40
|
+
this.runtime = runtime;
|
|
41
|
+
this.nodeType = nodeType;
|
|
42
|
+
this.key = key;
|
|
43
|
+
this.members = new CollectionMirror(runtime, nodeType, key, 'area');
|
|
44
|
+
}
|
|
45
|
+
/** Mirrors the area. */
|
|
46
|
+
async watch() {
|
|
47
|
+
await this.members.start();
|
|
48
|
+
}
|
|
49
|
+
unwatch() {
|
|
50
|
+
return this.members.stop();
|
|
51
|
+
}
|
|
52
|
+
mobs() {
|
|
53
|
+
return this.members.list('Mob');
|
|
54
|
+
}
|
|
55
|
+
npcs() {
|
|
56
|
+
return this.members.list('Npc');
|
|
57
|
+
}
|
|
58
|
+
pets() {
|
|
59
|
+
return this.members.list('Pet');
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Hits mob `mob`; resolves with its hp after the hit.
|
|
63
|
+
* @throws {KitError} `not_in_area`, `out_of_reach`, `cooldown`, `down`, `not_found`.
|
|
64
|
+
*/
|
|
65
|
+
attack(mob) {
|
|
66
|
+
return this.runtime.call(this.nodeType, this.key, 'attack', { mob }, { action: true });
|
|
67
|
+
}
|
|
68
|
+
/** What NPC `npc` says, with its public properties. */
|
|
69
|
+
talk(npc) {
|
|
70
|
+
return this.runtime.call(this.nodeType, this.key, 'talk', { npc });
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Adopts a pet where the player stands; resolves with its id.
|
|
74
|
+
* @throws {KitError} `not_in_area`, `limit` (pets a player), `full`, `bad_request`.
|
|
75
|
+
*/
|
|
76
|
+
adopt(species, name) {
|
|
77
|
+
return this.runtime.call(this.nodeType, this.key, 'adopt', { species, name }, { action: true });
|
|
78
|
+
}
|
|
79
|
+
rename(pet, name) {
|
|
80
|
+
return this.pet('rename', pet, name);
|
|
81
|
+
}
|
|
82
|
+
/** The pet follows its owner (and its bond grows). */
|
|
83
|
+
summon(pet) {
|
|
84
|
+
return this.pet('summon', pet);
|
|
85
|
+
}
|
|
86
|
+
/** The pet stays where it is. */
|
|
87
|
+
dismiss(pet) {
|
|
88
|
+
return this.pet('dismiss', pet);
|
|
89
|
+
}
|
|
90
|
+
/** The pet is gone. */
|
|
91
|
+
release(pet) {
|
|
92
|
+
return this.pet('release', pet);
|
|
93
|
+
}
|
|
94
|
+
/** The player's pets in this area, with their bond. */
|
|
95
|
+
myPets() {
|
|
96
|
+
return this.runtime.call(this.nodeType, this.key, 'pets');
|
|
97
|
+
}
|
|
98
|
+
pet(method, pet, name) {
|
|
99
|
+
const args = name === undefined ? { pet } : { pet, name };
|
|
100
|
+
return this.runtime.call(this.nodeType, this.key, method, args, { action: true });
|
|
101
|
+
}
|
|
102
|
+
}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import type { UdpAPI } from '../../domains/udp.js';
|
|
2
|
+
import { type EmoteEvent } from '../wire.js';
|
|
3
|
+
/** A chunk, in chunk coordinates. */
|
|
4
|
+
export interface KitChunk {
|
|
5
|
+
x: number;
|
|
6
|
+
y: number;
|
|
7
|
+
z: number;
|
|
8
|
+
}
|
|
9
|
+
/** How a spectator stays where the world's messages reach them. */
|
|
10
|
+
export interface SpectateOptions {
|
|
11
|
+
/** The spectator's actor uuid (32 characters), as with `udp.sendActorUpdate`. */
|
|
12
|
+
uuid: string;
|
|
13
|
+
/** Where to watch from: a chunk inside the app's world grid. */
|
|
14
|
+
chunk: KitChunk;
|
|
15
|
+
/** How often to say so, in milliseconds. Default 2 000. */
|
|
16
|
+
intervalMs?: number;
|
|
17
|
+
/** The actor state to send (base64); empty by default, which registers without a body. */
|
|
18
|
+
state?: string;
|
|
19
|
+
/** Replication distance, 0-8. Default 8. */
|
|
20
|
+
distance?: number;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Spectating: the realtime tier delivers what happens near an actor only while that actor is
|
|
24
|
+
* live, so a viewer with no avatar of its own (a spectator, a kill-cam, a second screen) sends
|
|
25
|
+
* a small actor update every couple of seconds from a chunk inside the app's world grid.
|
|
26
|
+
* Outside the grid the update is refused and delivery stops.
|
|
27
|
+
*/
|
|
28
|
+
export declare class SpectateKit {
|
|
29
|
+
private readonly appId;
|
|
30
|
+
private readonly udp;
|
|
31
|
+
constructor(appId: string, udp: UdpAPI | undefined);
|
|
32
|
+
/** Starts the heartbeat; returns the handle that moves or stops it. */
|
|
33
|
+
observe(options: SpectateOptions): SpectatorHeartbeat;
|
|
34
|
+
}
|
|
35
|
+
/** A running spectator heartbeat. */
|
|
36
|
+
export declare class SpectatorHeartbeat {
|
|
37
|
+
private readonly appId;
|
|
38
|
+
private readonly udp;
|
|
39
|
+
private readonly options;
|
|
40
|
+
private chunk;
|
|
41
|
+
private timer;
|
|
42
|
+
private lastError;
|
|
43
|
+
constructor(appId: string, udp: UdpAPI, options: SpectateOptions);
|
|
44
|
+
private beat;
|
|
45
|
+
/** Watches from another chunk from the next beat on (sent at once). */
|
|
46
|
+
moveTo(chunk: KitChunk): void;
|
|
47
|
+
/** The last send's error, or null when it went out. */
|
|
48
|
+
get error(): unknown;
|
|
49
|
+
stop(): void;
|
|
50
|
+
}
|
|
51
|
+
/** One emote to send. */
|
|
52
|
+
export interface EmoteSend {
|
|
53
|
+
/** The sending actor's uuid (32 characters). */
|
|
54
|
+
uuid: string;
|
|
55
|
+
/** The chunk the sender stands in. */
|
|
56
|
+
chunk: KitChunk;
|
|
57
|
+
/** The emote's name, as the game knows it: `wave`, `cheer`, ... */
|
|
58
|
+
emote: string;
|
|
59
|
+
/** The actor it is aimed at, if any. */
|
|
60
|
+
targetUuid?: string;
|
|
61
|
+
/** Replication distance, 0-8. Default 2. */
|
|
62
|
+
distance?: number;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Emotes: a client event (type {@link EVENT_EMOTE}) with a JSON body `{ emote, targetUuid }`,
|
|
66
|
+
* replicated to the players near the sender. A kit convention, so players on CrowdyJS,
|
|
67
|
+
* CrowdyCPP and CrowdyPy see each other's; no hub is involved.
|
|
68
|
+
*/
|
|
69
|
+
export declare class EmotesKit {
|
|
70
|
+
private readonly appId;
|
|
71
|
+
private readonly udp;
|
|
72
|
+
constructor(appId: string, udp: UdpAPI | undefined);
|
|
73
|
+
/** Sends an emote; `true` when it was accepted for sending. */
|
|
74
|
+
send(emote: EmoteSend): Promise<boolean>;
|
|
75
|
+
/** An emote from a `clientEvent` notification, or null when it is another event. */
|
|
76
|
+
parse(notification: {
|
|
77
|
+
eventType: number;
|
|
78
|
+
state: string;
|
|
79
|
+
}): EmoteEvent | null;
|
|
80
|
+
}
|
|
81
|
+
//# sourceMappingURL=presence.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"presence.d.ts","sourceRoot":"","sources":["../../../src/kit/modules/presence.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AAEnD,OAAO,EAAgC,KAAK,UAAU,EAAE,MAAM,YAAY,CAAC;AAE3E,qCAAqC;AACrC,MAAM,WAAW,QAAQ;IACvB,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;CACX;AAID,mEAAmE;AACnE,MAAM,WAAW,eAAe;IAC9B,iFAAiF;IACjF,IAAI,EAAE,MAAM,CAAC;IACb,gEAAgE;IAChE,KAAK,EAAE,QAAQ,CAAC;IAChB,2DAA2D;IAC3D,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,0FAA0F;IAC1F,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,4CAA4C;IAC5C,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;;;;GAKG;AACH,qBAAa,WAAW;IAEpB,OAAO,CAAC,QAAQ,CAAC,KAAK;IACtB,OAAO,CAAC,QAAQ,CAAC,GAAG;gBADH,KAAK,EAAE,MAAM,EACb,GAAG,EAAE,MAAM,GAAG,SAAS;IAG1C,uEAAuE;IACvE,OAAO,CAAC,OAAO,EAAE,eAAe,GAAG,kBAAkB;CAItD;AAED,qCAAqC;AACrC,qBAAa,kBAAkB;IAM3B,OAAO,CAAC,QAAQ,CAAC,KAAK;IACtB,OAAO,CAAC,QAAQ,CAAC,GAAG;IACpB,OAAO,CAAC,QAAQ,CAAC,OAAO;IAP1B,OAAO,CAAC,KAAK,CAAW;IACxB,OAAO,CAAC,KAAK,CAAwC;IACrD,OAAO,CAAC,SAAS,CAAiB;gBAGf,KAAK,EAAE,MAAM,EACb,GAAG,EAAE,MAAM,EACX,OAAO,EAAE,eAAe;IAO3C,OAAO,CAAC,IAAI;IAiBZ,uEAAuE;IACvE,MAAM,CAAC,KAAK,EAAE,QAAQ,GAAG,IAAI;IAK7B,uDAAuD;IACvD,IAAI,KAAK,IAAI,OAAO,CAEnB;IAED,IAAI,IAAI,IAAI;CAIb;AAED,yBAAyB;AACzB,MAAM,WAAW,SAAS;IACxB,gDAAgD;IAChD,IAAI,EAAE,MAAM,CAAC;IACb,sCAAsC;IACtC,KAAK,EAAE,QAAQ,CAAC;IAChB,mEAAmE;IACnE,KAAK,EAAE,MAAM,CAAC;IACd,wCAAwC;IACxC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,4CAA4C;IAC5C,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;;;GAIG;AACH,qBAAa,SAAS;IAElB,OAAO,CAAC,QAAQ,CAAC,KAAK;IACtB,OAAO,CAAC,QAAQ,CAAC,GAAG;gBADH,KAAK,EAAE,MAAM,EACb,GAAG,EAAE,MAAM,GAAG,SAAS;IAG1C,+DAA+D;IAC/D,IAAI,CAAC,KAAK,EAAE,SAAS,GAAG,OAAO,CAAC,OAAO,CAAC;IAaxC,oFAAoF;IACpF,KAAK,CAAC,YAAY,EAAE;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,GAAG,UAAU,GAAG,IAAI;CAS7E"}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import { decodeBase64, encodeBase64 } from '../../utils.js';
|
|
2
|
+
import { EVENT_EMOTE, parseEmoteEvent } from '../wire.js';
|
|
3
|
+
const chunkInput = (c) => ({ x: String(Math.trunc(c.x)), y: String(Math.trunc(c.y)), z: String(Math.trunc(c.z)) });
|
|
4
|
+
/**
|
|
5
|
+
* Spectating: the realtime tier delivers what happens near an actor only while that actor is
|
|
6
|
+
* live, so a viewer with no avatar of its own (a spectator, a kill-cam, a second screen) sends
|
|
7
|
+
* a small actor update every couple of seconds from a chunk inside the app's world grid.
|
|
8
|
+
* Outside the grid the update is refused and delivery stops.
|
|
9
|
+
*/
|
|
10
|
+
export class SpectateKit {
|
|
11
|
+
constructor(appId, udp) {
|
|
12
|
+
this.appId = appId;
|
|
13
|
+
this.udp = udp;
|
|
14
|
+
}
|
|
15
|
+
/** Starts the heartbeat; returns the handle that moves or stops it. */
|
|
16
|
+
observe(options) {
|
|
17
|
+
if (!this.udp)
|
|
18
|
+
throw new Error('the kit has no udp client to spectate with');
|
|
19
|
+
return new SpectatorHeartbeat(this.appId, this.udp, options);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
/** A running spectator heartbeat. */
|
|
23
|
+
export class SpectatorHeartbeat {
|
|
24
|
+
constructor(appId, udp, options) {
|
|
25
|
+
this.appId = appId;
|
|
26
|
+
this.udp = udp;
|
|
27
|
+
this.options = options;
|
|
28
|
+
this.lastError = null;
|
|
29
|
+
this.chunk = options.chunk;
|
|
30
|
+
this.beat();
|
|
31
|
+
this.timer = setInterval(() => this.beat(), Math.max(250, options.intervalMs ?? 2000));
|
|
32
|
+
}
|
|
33
|
+
beat() {
|
|
34
|
+
this.udp
|
|
35
|
+
.sendActorUpdate({
|
|
36
|
+
appId: this.appId,
|
|
37
|
+
uuid: this.options.uuid,
|
|
38
|
+
chunk: chunkInput(this.chunk),
|
|
39
|
+
state: this.options.state ?? '',
|
|
40
|
+
distance: this.options.distance ?? 8,
|
|
41
|
+
})
|
|
42
|
+
.then(() => {
|
|
43
|
+
this.lastError = null;
|
|
44
|
+
})
|
|
45
|
+
.catch((e) => {
|
|
46
|
+
this.lastError = e;
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
/** Watches from another chunk from the next beat on (sent at once). */
|
|
50
|
+
moveTo(chunk) {
|
|
51
|
+
this.chunk = chunk;
|
|
52
|
+
this.beat();
|
|
53
|
+
}
|
|
54
|
+
/** The last send's error, or null when it went out. */
|
|
55
|
+
get error() {
|
|
56
|
+
return this.lastError;
|
|
57
|
+
}
|
|
58
|
+
stop() {
|
|
59
|
+
if (this.timer)
|
|
60
|
+
clearInterval(this.timer);
|
|
61
|
+
this.timer = null;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Emotes: a client event (type {@link EVENT_EMOTE}) with a JSON body `{ emote, targetUuid }`,
|
|
66
|
+
* replicated to the players near the sender. A kit convention, so players on CrowdyJS,
|
|
67
|
+
* CrowdyCPP and CrowdyPy see each other's; no hub is involved.
|
|
68
|
+
*/
|
|
69
|
+
export class EmotesKit {
|
|
70
|
+
constructor(appId, udp) {
|
|
71
|
+
this.appId = appId;
|
|
72
|
+
this.udp = udp;
|
|
73
|
+
}
|
|
74
|
+
/** Sends an emote; `true` when it was accepted for sending. */
|
|
75
|
+
send(emote) {
|
|
76
|
+
if (!this.udp)
|
|
77
|
+
return Promise.reject(new Error('the kit has no udp client to send emotes with'));
|
|
78
|
+
const body = JSON.stringify({ emote: emote.emote, targetUuid: emote.targetUuid ?? null });
|
|
79
|
+
return this.udp.sendClientEvent({
|
|
80
|
+
appId: this.appId,
|
|
81
|
+
uuid: emote.uuid,
|
|
82
|
+
chunk: chunkInput(emote.chunk),
|
|
83
|
+
eventType: EVENT_EMOTE,
|
|
84
|
+
state: encodeBase64(new TextEncoder().encode(body)),
|
|
85
|
+
distance: emote.distance ?? 2,
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
/** An emote from a `clientEvent` notification, or null when it is another event. */
|
|
89
|
+
parse(notification) {
|
|
90
|
+
if (notification.eventType !== EVENT_EMOTE)
|
|
91
|
+
return null;
|
|
92
|
+
const state = decodeBase64(notification.state);
|
|
93
|
+
const bytes = new Uint8Array(2 + state.length);
|
|
94
|
+
bytes[0] = EVENT_EMOTE & 0xff;
|
|
95
|
+
bytes[1] = EVENT_EMOTE >> 8;
|
|
96
|
+
bytes.set(state, 2);
|
|
97
|
+
return parseEmoteEvent(bytes);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
import { HubState } from '../mirror.js';
|
|
2
|
+
import type { KitRuntime } from '../runtime.js';
|
|
3
|
+
export interface RaceGate {
|
|
4
|
+
x: number;
|
|
5
|
+
z: number;
|
|
6
|
+
radius: number;
|
|
7
|
+
}
|
|
8
|
+
export interface RaceRacer {
|
|
9
|
+
player: number;
|
|
10
|
+
x: number;
|
|
11
|
+
z: number;
|
|
12
|
+
lap: number;
|
|
13
|
+
/** The gate the racer must pass next. */
|
|
14
|
+
next_gate: number;
|
|
15
|
+
best_lap_ms: number | null;
|
|
16
|
+
place: number | null;
|
|
17
|
+
total_ms: number | null;
|
|
18
|
+
did_not_finish: boolean;
|
|
19
|
+
}
|
|
20
|
+
/** What the `race` topic carries. */
|
|
21
|
+
export interface RaceView {
|
|
22
|
+
phase: 'lobby' | 'countdown' | 'racing' | 'finished';
|
|
23
|
+
course_id: string;
|
|
24
|
+
gates: RaceGate[];
|
|
25
|
+
laps: number;
|
|
26
|
+
/** When the race starts (Unix ms), once counting down. */
|
|
27
|
+
go_at: number | null;
|
|
28
|
+
/** When the rest's time is up, once the winner is in. */
|
|
29
|
+
closes_at: number | null;
|
|
30
|
+
racers: RaceRacer[];
|
|
31
|
+
}
|
|
32
|
+
/** The winner's run: `[ms from the start, x, y, z, yaw]` frames to race against. */
|
|
33
|
+
export interface RaceGhost {
|
|
34
|
+
player: number;
|
|
35
|
+
total_ms: number;
|
|
36
|
+
frames: Array<[number, number, number, number, number]>;
|
|
37
|
+
}
|
|
38
|
+
export interface BallPlayer {
|
|
39
|
+
player: number;
|
|
40
|
+
team: 'red' | 'blue';
|
|
41
|
+
x: number;
|
|
42
|
+
z: number;
|
|
43
|
+
}
|
|
44
|
+
export interface BallState {
|
|
45
|
+
x: number;
|
|
46
|
+
z: number;
|
|
47
|
+
vx: number;
|
|
48
|
+
vz: number;
|
|
49
|
+
holder: number | null;
|
|
50
|
+
held_since: number;
|
|
51
|
+
last_touch: number | null;
|
|
52
|
+
}
|
|
53
|
+
/** What the `ball` topic carries. */
|
|
54
|
+
export interface BallView {
|
|
55
|
+
phase: 'lobby' | 'playing' | 'finished';
|
|
56
|
+
width: number;
|
|
57
|
+
depth: number;
|
|
58
|
+
goal_width: number;
|
|
59
|
+
ball: BallState;
|
|
60
|
+
players: BallPlayer[];
|
|
61
|
+
/** Red's, then blue's. */
|
|
62
|
+
score: [number, number];
|
|
63
|
+
ends_at: number | null;
|
|
64
|
+
winner: 'red' | 'blue' | null;
|
|
65
|
+
}
|
|
66
|
+
/** Races and ball games (the `racing` starter, types `race` and `ball`). */
|
|
67
|
+
export declare class RacingKit {
|
|
68
|
+
private readonly runtime;
|
|
69
|
+
private readonly raceType;
|
|
70
|
+
private readonly ballType;
|
|
71
|
+
private readonly races;
|
|
72
|
+
private readonly matches;
|
|
73
|
+
constructor(runtime: KitRuntime, raceType?: string, ballType?: string);
|
|
74
|
+
/** The race with key `key`. */
|
|
75
|
+
race(key: string): Race;
|
|
76
|
+
/** The ball game with key `key`. */
|
|
77
|
+
ball(key: string): BallMatch;
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* One race: a course of gates passed in order, a countdown, laps and splits, places in finishing
|
|
81
|
+
* order, and a ghost of the winner's run. A client reports where its racer is ({@link pos}, a few
|
|
82
|
+
* times a second) and the hub times the positions its movement warden kept. `view.onEvent` hears
|
|
83
|
+
* `go`, `timing` (with its `stage`: `started`, `checkpoint`, `lap`, `finished`), `violation` and
|
|
84
|
+
* `finished`.
|
|
85
|
+
*/
|
|
86
|
+
export declare class Race {
|
|
87
|
+
private readonly runtime;
|
|
88
|
+
readonly nodeType: string;
|
|
89
|
+
readonly key: string;
|
|
90
|
+
readonly view: HubState<RaceView>;
|
|
91
|
+
constructor(runtime: KitRuntime, nodeType: string, key: string);
|
|
92
|
+
watch(): Promise<RaceView>;
|
|
93
|
+
unwatch(): Promise<void>;
|
|
94
|
+
/** @throws {KitError} `started`, `full`. */
|
|
95
|
+
join(): Promise<boolean>;
|
|
96
|
+
leave(): Promise<boolean>;
|
|
97
|
+
/** Starts the countdown (the first to join, or a developer). @throws {KitError} `forbidden`, `started`. */
|
|
98
|
+
start(): Promise<boolean>;
|
|
99
|
+
/** Reports where the racer is; resolves with the position the hub kept. */
|
|
100
|
+
pos(x: number, z: number): Promise<[number, number]>;
|
|
101
|
+
/** The winner's run, once there is one. */
|
|
102
|
+
ghost(): Promise<RaceGhost | null>;
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* One ball game: two teams, a ball the hub moves (passes, shots, friction, the side walls),
|
|
106
|
+
* possession (claim a loose ball near it, or take it from an opponent whose protection is over), a
|
|
107
|
+
* goal in each end wall. `view.onEvent` hears `claimed`, `passed`, `shot`, `goal`, `violation` and
|
|
108
|
+
* `finished`.
|
|
109
|
+
*/
|
|
110
|
+
export declare class BallMatch {
|
|
111
|
+
private readonly runtime;
|
|
112
|
+
readonly nodeType: string;
|
|
113
|
+
readonly key: string;
|
|
114
|
+
readonly view: HubState<BallView>;
|
|
115
|
+
constructor(runtime: KitRuntime, nodeType: string, key: string);
|
|
116
|
+
watch(): Promise<BallView>;
|
|
117
|
+
unwatch(): Promise<void>;
|
|
118
|
+
/** @throws {KitError} `bad_request` (red or blue), `full`, `started`. */
|
|
119
|
+
join(team: 'red' | 'blue'): Promise<boolean>;
|
|
120
|
+
/** @throws {KitError} `forbidden`, `not_ready` (each team needs a player), `started`. */
|
|
121
|
+
start(): Promise<boolean>;
|
|
122
|
+
/** Reports where the player is; resolves with the position the hub kept. */
|
|
123
|
+
pos(x: number, z: number): Promise<[number, number]>;
|
|
124
|
+
/** Claims the ball. @throws {KitError} `out_of_reach`, `cooldown` (too soon, or its holder's protection), `conflict` (a teammate has it). */
|
|
125
|
+
claim(): Promise<boolean>;
|
|
126
|
+
/** Passes to a teammate. @throws {KitError} `conflict` (not the holder), `bad_request` (not a teammate). */
|
|
127
|
+
pass(to: number | string): Promise<boolean>;
|
|
128
|
+
/** Shoots toward `(x, z)`. @throws {KitError} `conflict` (not the holder). */
|
|
129
|
+
shoot(x: number, z: number): Promise<boolean>;
|
|
130
|
+
}
|
|
131
|
+
//# sourceMappingURL=racing.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"racing.d.ts","sourceRoot":"","sources":["../../../src/kit/modules/racing.ts"],"names":[],"mappings":"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"}
|