@crowdedkingdoms/crowdyjs 17.14.0-dev.1 → 18.0.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.
Files changed (271) hide show
  1. package/MIGRATION.md +92 -1
  2. package/README.md +93 -162
  3. package/dist/crowdy-client.d.ts +12 -31
  4. package/dist/crowdy-client.d.ts.map +1 -1
  5. package/dist/crowdy-client.js +15 -37
  6. package/dist/crowdy-dsh/bridge.d.ts.map +1 -1
  7. package/dist/crowdy-dsh/bridge.js +3 -6
  8. package/dist/crowdy-studio/controller.d.ts +34 -59
  9. package/dist/crowdy-studio/controller.d.ts.map +1 -1
  10. package/dist/crowdy-studio/controller.js +96 -225
  11. package/dist/crowdy-studio/diagnostics.d.ts +3 -12
  12. package/dist/crowdy-studio/diagnostics.d.ts.map +1 -1
  13. package/dist/crowdy-studio/dom-shell.d.ts +2 -4
  14. package/dist/crowdy-studio/dom-shell.d.ts.map +1 -1
  15. package/dist/crowdy-studio/dom-shell.js +16 -49
  16. package/dist/crowdy-studio/embed/hud-layer.d.ts +1 -2
  17. package/dist/crowdy-studio/embed/hud-layer.d.ts.map +1 -1
  18. package/dist/crowdy-studio/embed/panel.d.ts +3 -13
  19. package/dist/crowdy-studio/embed/panel.d.ts.map +1 -1
  20. package/dist/crowdy-studio/embed/panel.js +3 -6
  21. package/dist/crowdy-studio/index.d.ts +1 -3
  22. package/dist/crowdy-studio/index.d.ts.map +1 -1
  23. package/dist/crowdy-studio/index.js +0 -2
  24. package/dist/crowdy-studio/models.d.ts +3 -4
  25. package/dist/crowdy-studio/models.d.ts.map +1 -1
  26. package/dist/crowdy-studio/starter-projects.d.ts +8 -12
  27. package/dist/crowdy-studio/starter-projects.d.ts.map +1 -1
  28. package/dist/crowdy-studio/starter-projects.js +12 -103
  29. package/dist/domains/appAccess.d.ts +14 -1
  30. package/dist/domains/appAccess.d.ts.map +1 -1
  31. package/dist/domains/appAccess.js +37 -1
  32. package/dist/domains/host.d.ts +3 -3
  33. package/dist/domains/host.js +3 -3
  34. package/dist/domains/marketplace.d.ts +9 -70
  35. package/dist/domains/marketplace.d.ts.map +1 -1
  36. package/dist/domains/marketplace.js +9 -120
  37. package/dist/domains/playerWallet.d.ts +6 -12
  38. package/dist/domains/playerWallet.d.ts.map +1 -1
  39. package/dist/domains/playerWallet.js +6 -21
  40. package/dist/errors.d.ts +7 -13
  41. package/dist/errors.d.ts.map +1 -1
  42. package/dist/errors.js +6 -10
  43. package/dist/generated/graphql.d.ts +141 -7083
  44. package/dist/generated/graphql.d.ts.map +1 -1
  45. package/dist/generated/graphql.js +5 -313
  46. package/dist/grid-mods/exec-client-halves.d.ts +19 -3
  47. package/dist/grid-mods/exec-client-halves.d.ts.map +1 -1
  48. package/dist/grid-mods/exec-client-halves.js +17 -2
  49. package/dist/grid-mods/grid-host-calls.d.ts +29 -17
  50. package/dist/grid-mods/grid-host-calls.d.ts.map +1 -1
  51. package/dist/grid-mods/grid-host-calls.js +40 -46
  52. package/dist/grid-mods/mod-runtime.d.ts +18 -11
  53. package/dist/grid-mods/mod-runtime.d.ts.map +1 -1
  54. package/dist/grid-mods/mod-runtime.js +4 -2
  55. package/dist/grid-scope.d.ts +0 -189
  56. package/dist/grid-scope.d.ts.map +1 -1
  57. package/dist/grid-scope.js +0 -70
  58. package/dist/index.d.ts +11 -17
  59. package/dist/index.d.ts.map +1 -1
  60. package/dist/index.js +10 -16
  61. package/dist/kit/actions.d.ts +5 -9
  62. package/dist/kit/actions.d.ts.map +1 -1
  63. package/dist/kit/actions.js +5 -9
  64. package/dist/kit/index.d.ts +2 -33
  65. package/dist/kit/index.d.ts.map +1 -1
  66. package/dist/kit/index.js +1 -32
  67. package/dist/kit/kit.d.ts +8 -208
  68. package/dist/kit/kit.d.ts.map +1 -1
  69. package/dist/kit/kit.js +5 -163
  70. package/dist/kit/social.d.ts +1 -3
  71. package/dist/kit/social.d.ts.map +1 -1
  72. package/dist/kit/social.js +1 -3
  73. package/dist/kit/wire.d.ts +16 -5
  74. package/dist/kit/wire.d.ts.map +1 -1
  75. package/dist/kit/wire.js +19 -5
  76. package/dist/live-coding/assets/browser-authoring-index.json +1 -1
  77. package/dist/live-coding/assets/manifest.json +1 -1
  78. package/dist/live-coding/browser-authoring-index.generated.d.ts.map +1 -1
  79. package/dist/live-coding/browser-authoring-index.generated.js +1496 -4386
  80. package/dist/live-coding/rust-analysis.d.ts.map +1 -1
  81. package/dist/live-coding/rust-analysis.js +30 -34
  82. package/dist/player-runtime/client-host-calls.d.ts +8 -0
  83. package/dist/player-runtime/client-host-calls.d.ts.map +1 -0
  84. package/dist/player-runtime/client-host-calls.js +28 -0
  85. package/dist/player-runtime/glue-runtime.d.ts +24 -20
  86. package/dist/player-runtime/glue-runtime.d.ts.map +1 -1
  87. package/dist/player-runtime/glue-runtime.js +26 -55
  88. package/dist/player-runtime/glue-sab.d.ts +2 -2
  89. package/dist/player-runtime/glue-sab.js +2 -2
  90. package/dist/player-runtime/player-code-broker.d.ts +70 -43
  91. package/dist/player-runtime/player-code-broker.d.ts.map +1 -1
  92. package/dist/player-runtime/player-code-broker.js +159 -64
  93. package/dist/player-runtime/player-glue-worker.d.ts +8 -9
  94. package/dist/player-runtime/player-glue-worker.d.ts.map +1 -1
  95. package/dist/player-runtime/player-glue-worker.js +26 -11
  96. package/dist/stores/inbox.d.ts +1 -1
  97. package/dist/stores/inbox.d.ts.map +1 -1
  98. package/dist/stores/index.d.ts +0 -11
  99. package/dist/stores/index.d.ts.map +1 -1
  100. package/dist/stores/index.js +0 -4
  101. package/dist/stores/session.d.ts +0 -2
  102. package/dist/stores/session.d.ts.map +1 -1
  103. package/package.json +1 -1
  104. package/dist/crowdy-studio/model-lint-log.d.ts +0 -76
  105. package/dist/crowdy-studio/model-lint-log.d.ts.map +0 -1
  106. package/dist/crowdy-studio/model-lint-log.js +0 -93
  107. package/dist/crowdy-studio/model-lint.d.ts +0 -61
  108. package/dist/crowdy-studio/model-lint.d.ts.map +0 -1
  109. package/dist/crowdy-studio/model-lint.js +0 -45
  110. package/dist/domains/compute.d.ts +0 -208
  111. package/dist/domains/compute.d.ts.map +0 -1
  112. package/dist/domains/compute.js +0 -274
  113. package/dist/domains/controlPlane.d.ts +0 -38
  114. package/dist/domains/controlPlane.d.ts.map +0 -1
  115. package/dist/domains/controlPlane.js +0 -43
  116. package/dist/domains/gameModel.d.ts +0 -1174
  117. package/dist/domains/gameModel.d.ts.map +0 -1
  118. package/dist/domains/gameModel.js +0 -1333
  119. package/dist/domains/playerCompute.d.ts +0 -91
  120. package/dist/domains/playerCompute.d.ts.map +0 -1
  121. package/dist/domains/playerCompute.js +0 -136
  122. package/dist/domains/playerModel.d.ts +0 -20
  123. package/dist/domains/playerModel.d.ts.map +0 -1
  124. package/dist/domains/playerModel.js +0 -54
  125. package/dist/kit/abilities.d.ts +0 -66
  126. package/dist/kit/abilities.d.ts.map +0 -1
  127. package/dist/kit/abilities.js +0 -71
  128. package/dist/kit/blueprints/combat.d.ts +0 -81
  129. package/dist/kit/blueprints/combat.d.ts.map +0 -1
  130. package/dist/kit/blueprints/combat.js +0 -357
  131. package/dist/kit/blueprints/core.d.ts +0 -222
  132. package/dist/kit/blueprints/core.d.ts.map +0 -1
  133. package/dist/kit/blueprints/core.js +0 -185
  134. package/dist/kit/blueprints/decks.d.ts +0 -50
  135. package/dist/kit/blueprints/decks.d.ts.map +0 -1
  136. package/dist/kit/blueprints/decks.js +0 -163
  137. package/dist/kit/blueprints/economy.d.ts +0 -88
  138. package/dist/kit/blueprints/economy.d.ts.map +0 -1
  139. package/dist/kit/blueprints/economy.js +0 -533
  140. package/dist/kit/blueprints/guild.d.ts +0 -51
  141. package/dist/kit/blueprints/guild.d.ts.map +0 -1
  142. package/dist/kit/blueprints/guild.js +0 -50
  143. package/dist/kit/blueprints/index.d.ts +0 -23
  144. package/dist/kit/blueprints/index.d.ts.map +0 -1
  145. package/dist/kit/blueprints/index.js +0 -22
  146. package/dist/kit/blueprints/inventory.d.ts +0 -84
  147. package/dist/kit/blueprints/inventory.d.ts.map +0 -1
  148. package/dist/kit/blueprints/inventory.js +0 -257
  149. package/dist/kit/blueprints/leaderboards.d.ts +0 -49
  150. package/dist/kit/blueprints/leaderboards.d.ts.map +0 -1
  151. package/dist/kit/blueprints/leaderboards.js +0 -126
  152. package/dist/kit/blueprints/liveops.d.ts +0 -42
  153. package/dist/kit/blueprints/liveops.d.ts.map +0 -1
  154. package/dist/kit/blueprints/liveops.js +0 -170
  155. package/dist/kit/blueprints/locks.d.ts +0 -82
  156. package/dist/kit/blueprints/locks.d.ts.map +0 -1
  157. package/dist/kit/blueprints/locks.js +0 -155
  158. package/dist/kit/blueprints/loot.d.ts +0 -90
  159. package/dist/kit/blueprints/loot.d.ts.map +0 -1
  160. package/dist/kit/blueprints/loot.js +0 -229
  161. package/dist/kit/blueprints/matches.d.ts +0 -84
  162. package/dist/kit/blueprints/matches.d.ts.map +0 -1
  163. package/dist/kit/blueprints/matches.js +0 -349
  164. package/dist/kit/blueprints/moderation.d.ts +0 -32
  165. package/dist/kit/blueprints/moderation.d.ts.map +0 -1
  166. package/dist/kit/blueprints/moderation.js +0 -140
  167. package/dist/kit/blueprints/npcs.d.ts +0 -78
  168. package/dist/kit/blueprints/npcs.d.ts.map +0 -1
  169. package/dist/kit/blueprints/npcs.js +0 -125
  170. package/dist/kit/blueprints/plots.d.ts +0 -63
  171. package/dist/kit/blueprints/plots.d.ts.map +0 -1
  172. package/dist/kit/blueprints/plots.js +0 -151
  173. package/dist/kit/blueprints/progression.d.ts +0 -68
  174. package/dist/kit/blueprints/progression.d.ts.map +0 -1
  175. package/dist/kit/blueprints/progression.js +0 -324
  176. package/dist/kit/blueprints/quests.d.ts +0 -72
  177. package/dist/kit/blueprints/quests.d.ts.map +0 -1
  178. package/dist/kit/blueprints/quests.js +0 -285
  179. package/dist/kit/blueprints/worldsim.d.ts +0 -91
  180. package/dist/kit/blueprints/worldsim.d.ts.map +0 -1
  181. package/dist/kit/blueprints/worldsim.js +0 -468
  182. package/dist/kit/combat.d.ts +0 -141
  183. package/dist/kit/combat.d.ts.map +0 -1
  184. package/dist/kit/combat.js +0 -196
  185. package/dist/kit/decks.d.ts +0 -157
  186. package/dist/kit/decks.d.ts.map +0 -1
  187. package/dist/kit/decks.js +0 -186
  188. package/dist/kit/director.d.ts +0 -88
  189. package/dist/kit/director.d.ts.map +0 -1
  190. package/dist/kit/director.js +0 -86
  191. package/dist/kit/economy.d.ts +0 -289
  192. package/dist/kit/economy.d.ts.map +0 -1
  193. package/dist/kit/economy.js +0 -427
  194. package/dist/kit/engine.d.ts +0 -48
  195. package/dist/kit/engine.d.ts.map +0 -1
  196. package/dist/kit/engine.js +0 -113
  197. package/dist/kit/features.d.ts +0 -60
  198. package/dist/kit/features.d.ts.map +0 -1
  199. package/dist/kit/features.js +0 -65
  200. package/dist/kit/instances.d.ts +0 -52
  201. package/dist/kit/instances.d.ts.map +0 -1
  202. package/dist/kit/instances.js +0 -60
  203. package/dist/kit/inventory.d.ts +0 -129
  204. package/dist/kit/inventory.d.ts.map +0 -1
  205. package/dist/kit/inventory.js +0 -200
  206. package/dist/kit/leaderboards.d.ts +0 -86
  207. package/dist/kit/leaderboards.d.ts.map +0 -1
  208. package/dist/kit/leaderboards.js +0 -133
  209. package/dist/kit/liveops.d.ts +0 -112
  210. package/dist/kit/liveops.d.ts.map +0 -1
  211. package/dist/kit/liveops.js +0 -183
  212. package/dist/kit/loot.d.ts +0 -128
  213. package/dist/kit/loot.d.ts.map +0 -1
  214. package/dist/kit/loot.js +0 -160
  215. package/dist/kit/matches.d.ts +0 -301
  216. package/dist/kit/matches.d.ts.map +0 -1
  217. package/dist/kit/matches.js +0 -458
  218. package/dist/kit/matchmaking.d.ts +0 -57
  219. package/dist/kit/matchmaking.d.ts.map +0 -1
  220. package/dist/kit/matchmaking.js +0 -59
  221. package/dist/kit/minigames.d.ts +0 -30
  222. package/dist/kit/minigames.d.ts.map +0 -1
  223. package/dist/kit/minigames.js +0 -38
  224. package/dist/kit/mobs.d.ts +0 -90
  225. package/dist/kit/mobs.d.ts.map +0 -1
  226. package/dist/kit/mobs.js +0 -98
  227. package/dist/kit/moderation.d.ts +0 -73
  228. package/dist/kit/moderation.d.ts.map +0 -1
  229. package/dist/kit/moderation.js +0 -103
  230. package/dist/kit/movement.d.ts +0 -78
  231. package/dist/kit/movement.d.ts.map +0 -1
  232. package/dist/kit/movement.js +0 -103
  233. package/dist/kit/notifications.d.ts +0 -45
  234. package/dist/kit/notifications.d.ts.map +0 -1
  235. package/dist/kit/notifications.js +0 -67
  236. package/dist/kit/npcs.d.ts +0 -226
  237. package/dist/kit/npcs.d.ts.map +0 -1
  238. package/dist/kit/npcs.js +0 -141
  239. package/dist/kit/objects.d.ts +0 -116
  240. package/dist/kit/objects.d.ts.map +0 -1
  241. package/dist/kit/objects.js +0 -119
  242. package/dist/kit/pets.d.ts +0 -85
  243. package/dist/kit/pets.d.ts.map +0 -1
  244. package/dist/kit/pets.js +0 -96
  245. package/dist/kit/plots.d.ts +0 -85
  246. package/dist/kit/plots.d.ts.map +0 -1
  247. package/dist/kit/plots.js +0 -113
  248. package/dist/kit/progression.d.ts +0 -181
  249. package/dist/kit/progression.d.ts.map +0 -1
  250. package/dist/kit/progression.js +0 -265
  251. package/dist/kit/quests.d.ts +0 -171
  252. package/dist/kit/quests.d.ts.map +0 -1
  253. package/dist/kit/quests.js +0 -237
  254. package/dist/kit/racing.d.ts +0 -85
  255. package/dist/kit/racing.d.ts.map +0 -1
  256. package/dist/kit/racing.js +0 -99
  257. package/dist/kit/shared.d.ts +0 -73
  258. package/dist/kit/shared.d.ts.map +0 -1
  259. package/dist/kit/shared.js +0 -101
  260. package/dist/kit/telemetry.d.ts +0 -66
  261. package/dist/kit/telemetry.d.ts.map +0 -1
  262. package/dist/kit/telemetry.js +0 -133
  263. package/dist/kit/territory.d.ts +0 -97
  264. package/dist/kit/territory.d.ts.map +0 -1
  265. package/dist/kit/territory.js +0 -114
  266. package/dist/kit/worldsim.d.ts +0 -263
  267. package/dist/kit/worldsim.d.ts.map +0 -1
  268. package/dist/kit/worldsim.js +0 -268
  269. package/dist/stores/model.d.ts +0 -81
  270. package/dist/stores/model.d.ts.map +0 -1
  271. package/dist/stores/model.js +0 -163
@@ -1,67 +0,0 @@
1
- /**
2
- * Builders for a model function's `notifications`, so the non-staleable shape is the easy
3
- * one to reach for.
4
- *
5
- * WHY THESE EXIST AT ALL, given the input is three lines of JSON. A channel notification
6
- * can name its target two ways, and only one of them survives the app being recreated or
7
- * moved between organizations. Membership is scoped to the app, so a function naming a
8
- * channel that belongs to a DIFFERENT app produces a notification that is built, signed,
9
- * sent to every server and then dropped for want of a recipient -- while the invoke
10
- * succeeds and the run records success, because emission is best-effort and never fails a
11
- * function. The only symptom is silence.
12
- *
13
- * That is not hypothetical: it is what a copied game model does, and the server now reports
14
- * it as the `notification_channel_foreign` lint error. A NAME is resolved per-invocation
15
- * against the app that is running, so it cannot go stale the way an id copied between apps
16
- * does. `sessionChannel` is the shape to prefer.
17
- */
18
- /**
19
- * Notify every client in the app's default session channel.
20
- *
21
- * `$session_channel_name` is injected by the server from the app the function is RUNNING
22
- * in, so this expression is correct in any app that ever holds this definition -- which is
23
- * the whole point. It is also the channel every SDK client joins on connect, so this is
24
- * "tell everyone playing" with nothing to configure and nothing to keep in sync.
25
- */
26
- export function sessionChannelNotification(payloadExpression) {
27
- return {
28
- kind: 'channel',
29
- args: [
30
- { name: 'channel_name', expression: '$session_channel_name' },
31
- { name: 'payload', expression: payloadExpression },
32
- ],
33
- };
34
- }
35
- /**
36
- * Notify a channel named by NAME rather than by id.
37
- *
38
- * Use this when the channel is not the session channel but is still derivable -- a lobby
39
- * per app, say, as `concat("lobby-", $app_id)`. Same property as above: resolved against
40
- * the running app, so a copied model addresses its new home.
41
- */
42
- export function namedChannelNotification(channelNameExpression, payloadExpression) {
43
- return {
44
- kind: 'channel',
45
- args: [
46
- { name: 'channel_name', expression: channelNameExpression },
47
- { name: 'payload', expression: payloadExpression },
48
- ],
49
- };
50
- }
51
- /**
52
- * Notify a channel named by id.
53
- *
54
- * Correct when the id is READ FROM MODEL STATE -- `self.channel_id` on a container that
55
- * owns its own channel is the shape the matches blueprint uses, and it is app-portable
56
- * because the property travels with the row. A LITERAL id is the one to avoid, and the
57
- * server's `notification_channel_foreign` lint error exists to catch it.
58
- */
59
- export function channelIdNotification(channelIdExpression, payloadExpression) {
60
- return {
61
- kind: 'channel',
62
- args: [
63
- { name: 'channel_id', expression: channelIdExpression },
64
- { name: 'payload', expression: payloadExpression },
65
- ],
66
- };
67
- }
@@ -1,226 +0,0 @@
1
- import type { GameModelAPI } from '../domains/gameModel.js';
2
- import type { Scalars, SeedPropertyInput } from '../generated/graphql.js';
3
- import type { EngineDetector } from './engine.js';
4
- import type { EnginePose } from './wire.js';
5
- /** Options for {@link NpcsKit}. Must match the deployed NPC blueprint. */
6
- export interface NpcsKitOptions {
7
- /** The `typeName` the NPC blueprint was deployed with. Defaults to `'Npc'`. */
8
- typeName?: string;
9
- /**
10
- * The compute module driving NPC movement when the app runs an engine
11
- * (smooth FLAG_NPC actor emits instead of property nudges). Defaults to
12
- * `'npc-engine'`.
13
- */
14
- moduleName?: string;
15
- }
16
- /**
17
- * The minimal shape of a live actor entry {@link overlayLivePoses} reads —
18
- * matches the world-session `RemoteActor<EnginePose>` without importing it.
19
- */
20
- export interface LiveNpcPose {
21
- uuid: string;
22
- state: Pick<EnginePose, 'x' | 'y' | 'z'>;
23
- receivedAt: number;
24
- }
25
- /** A parsed view of one live NPC. */
26
- export interface KitNpc {
27
- containerId: string;
28
- displayName: string;
29
- role: string;
30
- x: number;
31
- y: number;
32
- z: number;
33
- behaviorState: string;
34
- health: number;
35
- /** All visible properties, including any extras your blueprint added. */
36
- properties: Record<string, unknown>;
37
- }
38
- /**
39
- * Runtime helpers for the {@link npcBlueprint} conventions: spawn NPC
40
- * instances, read their server-driven state, and manage/monitor the
41
- * automations behind them. Behaviors run in the API server — clients only
42
- * re-read state (or listen for model-driven notifications) and render.
43
- *
44
- * Spawning and the automation management/monitoring calls are studio/admin
45
- * operations (`manage_apps`); reads are player-safe.
46
- *
47
- * Obtained via `client.kit(appId).npcs`.
48
- */
49
- export declare class NpcsKit {
50
- private readonly appId;
51
- private readonly gameModel;
52
- private readonly engines?;
53
- private readonly typeName;
54
- private readonly moduleName;
55
- constructor(appId: Scalars['BigInt']['input'], gameModel: GameModelAPI, options?: NpcsKitOptions, engines?: EngineDetector | undefined);
56
- /**
57
- * Is an NPC compute engine deployed + enabled (cached per session)? When
58
- * true, NPCs stream smooth FLAG_NPC actor poses — overlay them with
59
- * {@link overlayLivePoses}. When false (model-only deployment), the polled
60
- * container positions are all there is, exactly as before.
61
- */
62
- engineAvailable(): Promise<boolean>;
63
- /**
64
- * Overlay live engine-driven poses onto a polled NPC snapshot (the
65
- * generalized BWF `NpcService.withLivePoses` pattern): each NPC whose
66
- * `actor_uuid` has a fresh pose in the npcs actor lane gets its position
67
- * replaced; the rest keep their durable container position, so NPCs stand
68
- * at their last synced spot instead of disappearing.
69
- *
70
- * @param npcs - The polled snapshot (from {@link list}).
71
- * @param lane - The live actors, e.g. `session.actors.lane('npcs').list()`.
72
- */
73
- overlayLivePoses(npcs: KitNpc[], lane: LiveNpcPose[]): KitNpc[];
74
- /** Spawn a live NPC instance (admin — the type is admin-instantiable). */
75
- spawn(input: {
76
- displayName: string;
77
- role?: string;
78
- position?: {
79
- x: number;
80
- y: number;
81
- z: number;
82
- };
83
- properties?: SeedPropertyInput[];
84
- sessionId?: string;
85
- }): Promise<{
86
- __typename?: "GmContainer";
87
- containerId: string;
88
- appId: string;
89
- sessionId: string | null;
90
- typeName: string;
91
- displayName: string;
92
- description: string | null;
93
- ownerUserId: string | null;
94
- metadataJson: string;
95
- }>;
96
- /**
97
- * List live NPCs with parsed state, optionally filtered by `role`. Fetches
98
- * each NPC's visible properties in parallel — fine for the bounded NPC
99
- * populations automations are designed around.
100
- */
101
- list(options?: {
102
- role?: string;
103
- sessionId?: string;
104
- }): Promise<KitNpc[]>;
105
- /** Read one NPC's current server-side state. */
106
- state(npcId: string): Promise<KitNpc>;
107
- /** Run one of the NPC automations immediately (admin; useful for testing). */
108
- runNow(automationName: string): Promise<{
109
- __typename?: "GmAutomationRun";
110
- runId: string;
111
- appId: string;
112
- flowId: string | null;
113
- automationId: string | null;
114
- automationName: string;
115
- triggerSource: string;
116
- triggerId: string | null;
117
- parentRunId: string | null;
118
- cascadeDepth: number;
119
- startedAt: string;
120
- finishedAt: string | null;
121
- durationUs: number;
122
- targets: number;
123
- invocations: number;
124
- mutations: number;
125
- fnCalls: number;
126
- gasUsed: number;
127
- success: boolean;
128
- errorMessage: string | null;
129
- circuitAction: string | null;
130
- computeUnits: number;
131
- }>;
132
- /**
133
- * Pause or resume an NPC automation (admin). Re-enabling also resets a
134
- * tripped failure circuit.
135
- */
136
- setEnabled(automationName: string, enabled: boolean): Promise<{
137
- __typename?: "GmAutomation";
138
- automationId: string;
139
- appId: string;
140
- name: string;
141
- description: string | null;
142
- enabled: boolean;
143
- actionKind: string;
144
- functionName: string | null;
145
- computeModuleName: string | null;
146
- computeExport: string | null;
147
- targetMode: string;
148
- selfContainerId: string | null;
149
- targetTypeName: string | null;
150
- sessionId: string | null;
151
- paramsJson: string;
152
- selectorJson: string | null;
153
- runAsUserId: string | null;
154
- triggerType: string;
155
- scheduleKind: string | null;
156
- intervalMs: number | null;
157
- cronExpr: string | null;
158
- maxTargets: number;
159
- maxFnDepth: number | null;
160
- gasLimit: number | null;
161
- runTimeoutMs: number | null;
162
- maxRunsPerMinute: number;
163
- failureThreshold: number;
164
- cooldownMs: number;
165
- circuitState: string;
166
- consecutiveFailures: number;
167
- pausedUntil: string | null;
168
- lastError: string | null;
169
- lastRunAt: string | null;
170
- nextRunAt: string | null;
171
- }>;
172
- /** Aggregate "what are my NPCs doing" stats over a recent window (admin). */
173
- stats(windowMinutes?: number): Promise<{
174
- __typename?: "GmAutomationStats";
175
- windowMinutes: number;
176
- totalRuns: number;
177
- failedRuns: number;
178
- failureRatePct: number;
179
- runsPerMinute: number;
180
- totalInvocations: number;
181
- totalMutations: number;
182
- totalComputeUnits: number;
183
- avgDurationUs: number;
184
- byAutomation: Array<{
185
- __typename?: "GmAutomationStat";
186
- automationName: string;
187
- runs: number;
188
- failures: number;
189
- invocations: number;
190
- computeUnits: number;
191
- avgDurationUs: number;
192
- circuitState: string;
193
- }>;
194
- }>;
195
- /** Recent automation run history, newest first (admin). */
196
- runs(options?: {
197
- automationName?: string;
198
- success?: boolean;
199
- limit?: number;
200
- }): Promise<{
201
- __typename?: "GmAutomationRun";
202
- runId: string;
203
- appId: string;
204
- flowId: string | null;
205
- automationId: string | null;
206
- automationName: string;
207
- triggerSource: string;
208
- triggerId: string | null;
209
- parentRunId: string | null;
210
- cascadeDepth: number;
211
- startedAt: string;
212
- finishedAt: string | null;
213
- durationUs: number;
214
- targets: number;
215
- invocations: number;
216
- mutations: number;
217
- fnCalls: number;
218
- gasUsed: number;
219
- success: boolean;
220
- errorMessage: string | null;
221
- circuitAction: string | null;
222
- computeUnits: number;
223
- }[]>;
224
- private toNpc;
225
- }
226
- //# sourceMappingURL=npcs.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"npcs.d.ts","sourceRoot":"","sources":["../../src/kit/npcs.ts"],"names":[],"mappings":"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"}
package/dist/kit/npcs.js DELETED
@@ -1,141 +0,0 @@
1
- import { kitContainerProperties } from './shared.js';
2
- /**
3
- * Runtime helpers for the {@link npcBlueprint} conventions: spawn NPC
4
- * instances, read their server-driven state, and manage/monitor the
5
- * automations behind them. Behaviors run in the API server — clients only
6
- * re-read state (or listen for model-driven notifications) and render.
7
- *
8
- * Spawning and the automation management/monitoring calls are studio/admin
9
- * operations (`manage_apps`); reads are player-safe.
10
- *
11
- * Obtained via `client.kit(appId).npcs`.
12
- */
13
- export class NpcsKit {
14
- constructor(appId, gameModel, options = {}, engines) {
15
- this.appId = appId;
16
- this.gameModel = gameModel;
17
- this.engines = engines;
18
- this.typeName = options.typeName ?? 'Npc';
19
- this.moduleName = options.moduleName ?? 'npc-engine';
20
- }
21
- /**
22
- * Is an NPC compute engine deployed + enabled (cached per session)? When
23
- * true, NPCs stream smooth FLAG_NPC actor poses — overlay them with
24
- * {@link overlayLivePoses}. When false (model-only deployment), the polled
25
- * container positions are all there is, exactly as before.
26
- */
27
- engineAvailable() {
28
- if (!this.engines)
29
- return Promise.resolve(false);
30
- return this.engines.has(this.moduleName);
31
- }
32
- /**
33
- * Overlay live engine-driven poses onto a polled NPC snapshot (the
34
- * generalized BWF `NpcService.withLivePoses` pattern): each NPC whose
35
- * `actor_uuid` has a fresh pose in the npcs actor lane gets its position
36
- * replaced; the rest keep their durable container position, so NPCs stand
37
- * at their last synced spot instead of disappearing.
38
- *
39
- * @param npcs - The polled snapshot (from {@link list}).
40
- * @param lane - The live actors, e.g. `session.actors.lane('npcs').list()`.
41
- */
42
- overlayLivePoses(npcs, lane) {
43
- if (lane.length === 0)
44
- return npcs;
45
- const poses = new Map(lane.map((actor) => [actor.uuid, actor]));
46
- return npcs.map((npc) => {
47
- const uuid = String(npc.properties.actor_uuid ?? '');
48
- const live = uuid ? poses.get(uuid) : undefined;
49
- if (!live)
50
- return npc;
51
- return { ...npc, x: live.state.x, y: live.state.y, z: live.state.z };
52
- });
53
- }
54
- /** Spawn a live NPC instance (admin — the type is admin-instantiable). */
55
- async spawn(input) {
56
- const properties = [
57
- ...(input.role !== undefined
58
- ? [{ key: 'role', valueType: 'string', valueJson: JSON.stringify(input.role) }]
59
- : []),
60
- ...(input.position
61
- ? [
62
- { key: 'x', valueType: 'float', valueJson: String(input.position.x) },
63
- { key: 'y', valueType: 'float', valueJson: String(input.position.y) },
64
- { key: 'z', valueType: 'float', valueJson: String(input.position.z) },
65
- ]
66
- : []),
67
- ...(input.properties ?? []),
68
- ];
69
- return this.gameModel.createContainer({
70
- appId: this.appId,
71
- typeName: this.typeName,
72
- displayName: input.displayName,
73
- ...(input.sessionId !== undefined ? { sessionId: input.sessionId } : {}),
74
- ...(properties.length ? { properties } : {}),
75
- });
76
- }
77
- /**
78
- * List live NPCs with parsed state, optionally filtered by `role`. Fetches
79
- * each NPC's visible properties in parallel — fine for the bounded NPC
80
- * populations automations are designed around.
81
- */
82
- async list(options = {}) {
83
- const containers = await this.gameModel.containers({
84
- appId: this.appId,
85
- typeName: this.typeName,
86
- ...(options.sessionId !== undefined ? { sessionId: options.sessionId } : {}),
87
- });
88
- const npcs = await Promise.all(containers.map((c) => this.toNpc(c.containerId, c.displayName)));
89
- return options.role !== undefined
90
- ? npcs.filter((n) => n.role === options.role)
91
- : npcs;
92
- }
93
- /** Read one NPC's current server-side state. */
94
- async state(npcId) {
95
- const container = await this.gameModel.container({
96
- appId: this.appId,
97
- containerId: npcId,
98
- });
99
- return this.toNpc(container.containerId, container.displayName);
100
- }
101
- /** Run one of the NPC automations immediately (admin; useful for testing). */
102
- async runNow(automationName) {
103
- return this.gameModel.runAutomation({ appId: this.appId, name: automationName });
104
- }
105
- /**
106
- * Pause or resume an NPC automation (admin). Re-enabling also resets a
107
- * tripped failure circuit.
108
- */
109
- async setEnabled(automationName, enabled) {
110
- return this.gameModel.setAutomationEnabled({
111
- appId: this.appId,
112
- name: automationName,
113
- enabled,
114
- });
115
- }
116
- /** Aggregate "what are my NPCs doing" stats over a recent window (admin). */
117
- async stats(windowMinutes) {
118
- return this.gameModel.automationStats({
119
- appId: this.appId,
120
- ...(windowMinutes !== undefined ? { windowMinutes } : {}),
121
- });
122
- }
123
- /** Recent automation run history, newest first (admin). */
124
- async runs(options = {}) {
125
- return this.gameModel.automationRuns({ appId: this.appId, ...options });
126
- }
127
- async toNpc(containerId, displayName) {
128
- const props = await kitContainerProperties(this.gameModel, String(this.appId), containerId);
129
- return {
130
- containerId,
131
- displayName,
132
- role: String(props.role ?? ''),
133
- x: Number(props.x ?? 0),
134
- y: Number(props.y ?? 0),
135
- z: Number(props.z ?? 0),
136
- behaviorState: String(props.behavior_state ?? ''),
137
- health: Number(props.health ?? 0),
138
- properties: props,
139
- };
140
- }
141
- }
@@ -1,116 +0,0 @@
1
- import type { GameModelAPI } from '../domains/gameModel.js';
2
- import type { Scalars, SeedPropertyInput } from '../generated/graphql.js';
3
- import { type KitInvokeResult } from './shared.js';
4
- /** Options for {@link ObjectsKit}. Must match the deployed lock blueprint. */
5
- export interface ObjectsKitOptions {
6
- /** The `objectTypeName` the lock blueprint was deployed with. Defaults to `'Lockable'`. */
7
- objectTypeName?: string;
8
- /** The `keyTypeName` the lock blueprint was deployed with. */
9
- keyTypeName?: string;
10
- }
11
- /**
12
- * Runtime helpers for the {@link lockBlueprint} conventions: instantiate
13
- * lockable world objects, grant key items, and operate the objects through
14
- * their authority-gated `open`/`close` functions. Authorization is decided
15
- * entirely server-side; a denied attempt resolves with `success: false`.
16
- *
17
- * Obtained via `client.kit(appId).objects` (or `client.kit(appId)
18
- * .objectsFor('Door')` for a non-default type name).
19
- */
20
- export declare class ObjectsKit {
21
- private readonly appId;
22
- private readonly gameModel;
23
- private readonly names;
24
- constructor(appId: Scalars['BigInt']['input'], gameModel: GameModelAPI, options?: ObjectsKitOptions);
25
- /**
26
- * Instantiate a lockable object (admin/studio call — the type is
27
- * admin-instantiable). For key-gated objects set `requiredKeyId` to the key
28
- * id that opens it; for owner-gated objects set `ownerUserId`; for
29
- * chunk-permission-gated objects set `chunk` to where the object stands
30
- * (feeds the `has_chunk_permission` policy).
31
- */
32
- create(input: {
33
- displayName: string;
34
- requiredKeyId?: string;
35
- ownerUserId?: Scalars['BigInt']['input'];
36
- /** The chunk the object occupies (chunkPermission authority). */
37
- chunk?: {
38
- x: number;
39
- y: number;
40
- z: number;
41
- };
42
- properties?: SeedPropertyInput[];
43
- sessionId?: string;
44
- }): Promise<{
45
- __typename?: "GmContainer";
46
- containerId: string;
47
- appId: string;
48
- sessionId: string | null;
49
- typeName: string;
50
- displayName: string;
51
- description: string | null;
52
- ownerUserId: string | null;
53
- metadataJson: string;
54
- }>;
55
- /**
56
- * Grant a player a key item (admin/studio call). Creates a key container
57
- * owned by the player, with the owner mirrored into the `owner_user_id`
58
- * property that the key condition policy reads.
59
- */
60
- grantKey(input: {
61
- keyId: string;
62
- toUserId: Scalars['BigInt']['input'];
63
- displayName?: string;
64
- }): Promise<{
65
- __typename?: "GmContainer";
66
- containerId: string;
67
- appId: string;
68
- sessionId: string | null;
69
- typeName: string;
70
- displayName: string;
71
- description: string | null;
72
- ownerUserId: string | null;
73
- metadataJson: string;
74
- }>;
75
- /** List the key items a player holds. */
76
- keysOf(userId: Scalars['BigInt']['input']): Promise<{
77
- __typename?: "GmContainer";
78
- containerId: string;
79
- appId: string;
80
- sessionId: string | null;
81
- typeName: string;
82
- displayName: string;
83
- description: string | null;
84
- ownerUserId: string | null;
85
- metadataJson: string;
86
- }[]>;
87
- /**
88
- * Try to open an object. Pass `keyId` (the **container id** of a key the
89
- * caller holds) when the object is key-gated; owner/grid/group authorities
90
- * need no params. A denial is not an exception — check `success`.
91
- */
92
- open(objectId: string, options?: {
93
- keyId?: string;
94
- }): Promise<KitInvokeResult<boolean>>;
95
- /** Try to close an object; same authority as {@link open}. */
96
- close(objectId: string, options?: {
97
- keyId?: string;
98
- }): Promise<KitInvokeResult<boolean>>;
99
- /** Read whether an object is currently open. */
100
- isOpen(objectId: string): Promise<boolean>;
101
- /** List all objects of this lockable type. */
102
- list(options?: {
103
- sessionId?: string;
104
- }): Promise<{
105
- __typename?: "GmContainer";
106
- containerId: string;
107
- appId: string;
108
- sessionId: string | null;
109
- typeName: string;
110
- displayName: string;
111
- description: string | null;
112
- ownerUserId: string | null;
113
- metadataJson: string;
114
- }[]>;
115
- }
116
- //# sourceMappingURL=objects.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"objects.d.ts","sourceRoot":"","sources":["../../src/kit/objects.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAC5D,OAAO,KAAK,EAAE,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAE1E,OAAO,EAGL,KAAK,eAAe,EACrB,MAAM,aAAa,CAAC;AAErB,8EAA8E;AAC9E,MAAM,WAAW,iBAAiB;IAChC,2FAA2F;IAC3F,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,8DAA8D;IAC9D,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED;;;;;;;;GAQG;AACH,qBAAa,UAAU;IAInB,OAAO,CAAC,QAAQ,CAAC,KAAK;IACtB,OAAO,CAAC,QAAQ,CAAC,SAAS;IAJ5B,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAY;gBAGf,KAAK,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC,OAAO,CAAC,EACjC,SAAS,EAAE,YAAY,EACxC,OAAO,GAAE,iBAAsB;IAKjC;;;;;;OAMG;IACG,MAAM,CAAC,KAAK,EAAE;QAClB,WAAW,EAAE,MAAM,CAAC;QACpB,aAAa,CAAC,EAAE,MAAM,CAAC;QACvB,WAAW,CAAC,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC,OAAO,CAAC,CAAC;QACzC,iEAAiE;QACjE,KAAK,CAAC,EAAE;YAAE,CAAC,EAAE,MAAM,CAAC;YAAC,CAAC,EAAE,MAAM,CAAC;YAAC,CAAC,EAAE,MAAM,CAAA;SAAE,CAAC;QAC5C,UAAU,CAAC,EAAE,iBAAiB,EAAE,CAAC;QACjC,SAAS,CAAC,EAAE,MAAM,CAAC;KACpB;;;;;;;;;;;IA+BD;;;;OAIG;IACG,QAAQ,CAAC,KAAK,EAAE;QACpB,KAAK,EAAE,MAAM,CAAC;QACd,QAAQ,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC,OAAO,CAAC,CAAC;QACrC,WAAW,CAAC,EAAE,MAAM,CAAC;KACtB;;;;;;;;;;;IAiBD,yCAAyC;IACnC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC,OAAO,CAAC;;;;;;;;;;;IAU/C;;;;OAIG;IACG,IAAI,CACR,QAAQ,EAAE,MAAM,EAChB,OAAO,GAAE;QAAE,KAAK,CAAC,EAAE,MAAM,CAAA;KAAO,GAC/B,OAAO,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC;IASpC,8DAA8D;IACxD,KAAK,CACT,QAAQ,EAAE,MAAM,EAChB,OAAO,GAAE;QAAE,KAAK,CAAC,EAAE,MAAM,CAAA;KAAO,GAC/B,OAAO,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC;IASpC,gDAAgD;IAC1C,MAAM,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAShD,8CAA8C;IACxC,IAAI,CAAC,OAAO,GAAE;QAAE,SAAS,CAAC,EAAE,MAAM,CAAA;KAAO;;;;;;;;;;;CAOhD"}
@@ -1,119 +0,0 @@
1
- import { lockNames } from './blueprints/index.js';
2
- import { kitContainerProperties, kitInvoke, } from './shared.js';
3
- /**
4
- * Runtime helpers for the {@link lockBlueprint} conventions: instantiate
5
- * lockable world objects, grant key items, and operate the objects through
6
- * their authority-gated `open`/`close` functions. Authorization is decided
7
- * entirely server-side; a denied attempt resolves with `success: false`.
8
- *
9
- * Obtained via `client.kit(appId).objects` (or `client.kit(appId)
10
- * .objectsFor('Door')` for a non-default type name).
11
- */
12
- export class ObjectsKit {
13
- constructor(appId, gameModel, options = {}) {
14
- this.appId = appId;
15
- this.gameModel = gameModel;
16
- this.names = lockNames(options.objectTypeName, options.keyTypeName);
17
- }
18
- /**
19
- * Instantiate a lockable object (admin/studio call — the type is
20
- * admin-instantiable). For key-gated objects set `requiredKeyId` to the key
21
- * id that opens it; for owner-gated objects set `ownerUserId`; for
22
- * chunk-permission-gated objects set `chunk` to where the object stands
23
- * (feeds the `has_chunk_permission` policy).
24
- */
25
- async create(input) {
26
- const properties = [
27
- { key: 'is_open', valueType: 'bool', valueJson: 'false' },
28
- ...(input.requiredKeyId !== undefined
29
- ? [
30
- {
31
- key: 'required_key_id',
32
- valueType: 'string',
33
- valueJson: JSON.stringify(input.requiredKeyId),
34
- },
35
- ]
36
- : []),
37
- ...(input.chunk
38
- ? [
39
- { key: 'cx', valueType: 'int', valueJson: String(input.chunk.x) },
40
- { key: 'cy', valueType: 'int', valueJson: String(input.chunk.y) },
41
- { key: 'cz', valueType: 'int', valueJson: String(input.chunk.z) },
42
- ]
43
- : []),
44
- ...(input.properties ?? []),
45
- ];
46
- return this.gameModel.createContainer({
47
- appId: this.appId,
48
- typeName: this.names.objectType,
49
- displayName: input.displayName,
50
- ...(input.ownerUserId !== undefined ? { ownerUserId: input.ownerUserId } : {}),
51
- ...(input.sessionId !== undefined ? { sessionId: input.sessionId } : {}),
52
- properties,
53
- });
54
- }
55
- /**
56
- * Grant a player a key item (admin/studio call). Creates a key container
57
- * owned by the player, with the owner mirrored into the `owner_user_id`
58
- * property that the key condition policy reads.
59
- */
60
- async grantKey(input) {
61
- return this.gameModel.createContainer({
62
- appId: this.appId,
63
- typeName: this.names.keyType,
64
- displayName: input.displayName ?? `Key ${input.keyId}`,
65
- ownerUserId: input.toUserId,
66
- properties: [
67
- { key: 'key_id', valueType: 'string', valueJson: JSON.stringify(input.keyId) },
68
- {
69
- key: 'owner_user_id',
70
- valueType: 'int',
71
- valueJson: String(input.toUserId),
72
- },
73
- ],
74
- });
75
- }
76
- /** List the key items a player holds. */
77
- async keysOf(userId) {
78
- const containers = await this.gameModel.containers({
79
- appId: this.appId,
80
- typeName: this.names.keyType,
81
- });
82
- return containers.filter((c) => c.ownerUserId != null && String(c.ownerUserId) === String(userId));
83
- }
84
- /**
85
- * Try to open an object. Pass `keyId` (the **container id** of a key the
86
- * caller holds) when the object is key-gated; owner/grid/group authorities
87
- * need no params. A denial is not an exception — check `success`.
88
- */
89
- async open(objectId, options = {}) {
90
- return kitInvoke(this.gameModel, {
91
- appId: String(this.appId),
92
- functionName: this.names.openFn,
93
- selfContainerId: objectId,
94
- params: options.keyId !== undefined ? { key_id: options.keyId } : {},
95
- });
96
- }
97
- /** Try to close an object; same authority as {@link open}. */
98
- async close(objectId, options = {}) {
99
- return kitInvoke(this.gameModel, {
100
- appId: String(this.appId),
101
- functionName: this.names.closeFn,
102
- selfContainerId: objectId,
103
- params: options.keyId !== undefined ? { key_id: options.keyId } : {},
104
- });
105
- }
106
- /** Read whether an object is currently open. */
107
- async isOpen(objectId) {
108
- const props = await kitContainerProperties(this.gameModel, String(this.appId), objectId);
109
- return props.is_open === true;
110
- }
111
- /** List all objects of this lockable type. */
112
- async list(options = {}) {
113
- return this.gameModel.containers({
114
- appId: this.appId,
115
- typeName: this.names.objectType,
116
- ...(options.sessionId !== undefined ? { sessionId: options.sessionId } : {}),
117
- });
118
- }
119
- }