@crowdedkingdoms/crowdyjs 17.14.0-dev.1 → 18.0.1-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 (289) hide show
  1. package/MIGRATION.md +129 -1
  2. package/README.md +97 -164
  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/apps.d.ts +1 -10
  33. package/dist/domains/apps.d.ts.map +1 -1
  34. package/dist/domains/apps.js +1 -16
  35. package/dist/domains/host.d.ts +3 -3
  36. package/dist/domains/host.js +3 -3
  37. package/dist/domains/hosting.d.ts +0 -6
  38. package/dist/domains/hosting.d.ts.map +1 -1
  39. package/dist/domains/hosting.js +1 -16
  40. package/dist/domains/marketplace.d.ts +9 -70
  41. package/dist/domains/marketplace.d.ts.map +1 -1
  42. package/dist/domains/marketplace.js +9 -120
  43. package/dist/domains/organizations.d.ts +1 -9
  44. package/dist/domains/organizations.d.ts.map +1 -1
  45. package/dist/domains/organizations.js +1 -15
  46. package/dist/domains/payments.d.ts +5 -48
  47. package/dist/domains/payments.d.ts.map +1 -1
  48. package/dist/domains/payments.js +5 -57
  49. package/dist/domains/playerWallet.d.ts +6 -12
  50. package/dist/domains/playerWallet.d.ts.map +1 -1
  51. package/dist/domains/playerWallet.js +6 -21
  52. package/dist/domains/quotas.d.ts +20 -7
  53. package/dist/domains/quotas.d.ts.map +1 -1
  54. package/dist/domains/quotas.js +15 -6
  55. package/dist/domains/users.d.ts +7 -74
  56. package/dist/domains/users.d.ts.map +1 -1
  57. package/dist/domains/users.js +7 -105
  58. package/dist/errors.d.ts +7 -13
  59. package/dist/errors.d.ts.map +1 -1
  60. package/dist/errors.js +6 -10
  61. package/dist/generated/graphql.d.ts +955 -8272
  62. package/dist/generated/graphql.d.ts.map +1 -1
  63. package/dist/generated/graphql.js +5 -329
  64. package/dist/grid-mods/exec-client-halves.d.ts +19 -3
  65. package/dist/grid-mods/exec-client-halves.d.ts.map +1 -1
  66. package/dist/grid-mods/exec-client-halves.js +17 -2
  67. package/dist/grid-mods/grid-host-calls.d.ts +29 -17
  68. package/dist/grid-mods/grid-host-calls.d.ts.map +1 -1
  69. package/dist/grid-mods/grid-host-calls.js +40 -46
  70. package/dist/grid-mods/mod-runtime.d.ts +18 -11
  71. package/dist/grid-mods/mod-runtime.d.ts.map +1 -1
  72. package/dist/grid-mods/mod-runtime.js +4 -2
  73. package/dist/grid-scope.d.ts +0 -189
  74. package/dist/grid-scope.d.ts.map +1 -1
  75. package/dist/grid-scope.js +0 -70
  76. package/dist/index.d.ts +12 -18
  77. package/dist/index.d.ts.map +1 -1
  78. package/dist/index.js +10 -16
  79. package/dist/kit/actions.d.ts +5 -9
  80. package/dist/kit/actions.d.ts.map +1 -1
  81. package/dist/kit/actions.js +5 -9
  82. package/dist/kit/index.d.ts +2 -33
  83. package/dist/kit/index.d.ts.map +1 -1
  84. package/dist/kit/index.js +1 -32
  85. package/dist/kit/kit.d.ts +8 -208
  86. package/dist/kit/kit.d.ts.map +1 -1
  87. package/dist/kit/kit.js +5 -163
  88. package/dist/kit/social.d.ts +1 -3
  89. package/dist/kit/social.d.ts.map +1 -1
  90. package/dist/kit/social.js +1 -3
  91. package/dist/kit/wire.d.ts +16 -5
  92. package/dist/kit/wire.d.ts.map +1 -1
  93. package/dist/kit/wire.js +19 -5
  94. package/dist/live-coding/assets/browser-authoring-index.json +1 -1
  95. package/dist/live-coding/assets/manifest.json +1 -1
  96. package/dist/live-coding/browser-authoring-index.generated.d.ts.map +1 -1
  97. package/dist/live-coding/browser-authoring-index.generated.js +1496 -4386
  98. package/dist/live-coding/rust-analysis.d.ts.map +1 -1
  99. package/dist/live-coding/rust-analysis.js +30 -34
  100. package/dist/player-runtime/client-host-calls.d.ts +8 -0
  101. package/dist/player-runtime/client-host-calls.d.ts.map +1 -0
  102. package/dist/player-runtime/client-host-calls.js +28 -0
  103. package/dist/player-runtime/glue-runtime.d.ts +24 -20
  104. package/dist/player-runtime/glue-runtime.d.ts.map +1 -1
  105. package/dist/player-runtime/glue-runtime.js +26 -55
  106. package/dist/player-runtime/glue-sab.d.ts +2 -2
  107. package/dist/player-runtime/glue-sab.js +2 -2
  108. package/dist/player-runtime/player-code-broker.d.ts +70 -43
  109. package/dist/player-runtime/player-code-broker.d.ts.map +1 -1
  110. package/dist/player-runtime/player-code-broker.js +159 -64
  111. package/dist/player-runtime/player-glue-worker.d.ts +8 -9
  112. package/dist/player-runtime/player-glue-worker.d.ts.map +1 -1
  113. package/dist/player-runtime/player-glue-worker.js +26 -11
  114. package/dist/stores/inbox.d.ts +1 -1
  115. package/dist/stores/inbox.d.ts.map +1 -1
  116. package/dist/stores/index.d.ts +0 -11
  117. package/dist/stores/index.d.ts.map +1 -1
  118. package/dist/stores/index.js +0 -4
  119. package/dist/stores/session.d.ts +0 -2
  120. package/dist/stores/session.d.ts.map +1 -1
  121. package/package.json +1 -1
  122. package/dist/crowdy-studio/model-lint-log.d.ts +0 -76
  123. package/dist/crowdy-studio/model-lint-log.d.ts.map +0 -1
  124. package/dist/crowdy-studio/model-lint-log.js +0 -93
  125. package/dist/crowdy-studio/model-lint.d.ts +0 -61
  126. package/dist/crowdy-studio/model-lint.d.ts.map +0 -1
  127. package/dist/crowdy-studio/model-lint.js +0 -45
  128. package/dist/domains/compute.d.ts +0 -208
  129. package/dist/domains/compute.d.ts.map +0 -1
  130. package/dist/domains/compute.js +0 -274
  131. package/dist/domains/controlPlane.d.ts +0 -38
  132. package/dist/domains/controlPlane.d.ts.map +0 -1
  133. package/dist/domains/controlPlane.js +0 -43
  134. package/dist/domains/gameModel.d.ts +0 -1174
  135. package/dist/domains/gameModel.d.ts.map +0 -1
  136. package/dist/domains/gameModel.js +0 -1333
  137. package/dist/domains/playerCompute.d.ts +0 -91
  138. package/dist/domains/playerCompute.d.ts.map +0 -1
  139. package/dist/domains/playerCompute.js +0 -136
  140. package/dist/domains/playerModel.d.ts +0 -20
  141. package/dist/domains/playerModel.d.ts.map +0 -1
  142. package/dist/domains/playerModel.js +0 -54
  143. package/dist/kit/abilities.d.ts +0 -66
  144. package/dist/kit/abilities.d.ts.map +0 -1
  145. package/dist/kit/abilities.js +0 -71
  146. package/dist/kit/blueprints/combat.d.ts +0 -81
  147. package/dist/kit/blueprints/combat.d.ts.map +0 -1
  148. package/dist/kit/blueprints/combat.js +0 -357
  149. package/dist/kit/blueprints/core.d.ts +0 -222
  150. package/dist/kit/blueprints/core.d.ts.map +0 -1
  151. package/dist/kit/blueprints/core.js +0 -185
  152. package/dist/kit/blueprints/decks.d.ts +0 -50
  153. package/dist/kit/blueprints/decks.d.ts.map +0 -1
  154. package/dist/kit/blueprints/decks.js +0 -163
  155. package/dist/kit/blueprints/economy.d.ts +0 -88
  156. package/dist/kit/blueprints/economy.d.ts.map +0 -1
  157. package/dist/kit/blueprints/economy.js +0 -533
  158. package/dist/kit/blueprints/guild.d.ts +0 -51
  159. package/dist/kit/blueprints/guild.d.ts.map +0 -1
  160. package/dist/kit/blueprints/guild.js +0 -50
  161. package/dist/kit/blueprints/index.d.ts +0 -23
  162. package/dist/kit/blueprints/index.d.ts.map +0 -1
  163. package/dist/kit/blueprints/index.js +0 -22
  164. package/dist/kit/blueprints/inventory.d.ts +0 -84
  165. package/dist/kit/blueprints/inventory.d.ts.map +0 -1
  166. package/dist/kit/blueprints/inventory.js +0 -257
  167. package/dist/kit/blueprints/leaderboards.d.ts +0 -49
  168. package/dist/kit/blueprints/leaderboards.d.ts.map +0 -1
  169. package/dist/kit/blueprints/leaderboards.js +0 -126
  170. package/dist/kit/blueprints/liveops.d.ts +0 -42
  171. package/dist/kit/blueprints/liveops.d.ts.map +0 -1
  172. package/dist/kit/blueprints/liveops.js +0 -170
  173. package/dist/kit/blueprints/locks.d.ts +0 -82
  174. package/dist/kit/blueprints/locks.d.ts.map +0 -1
  175. package/dist/kit/blueprints/locks.js +0 -155
  176. package/dist/kit/blueprints/loot.d.ts +0 -90
  177. package/dist/kit/blueprints/loot.d.ts.map +0 -1
  178. package/dist/kit/blueprints/loot.js +0 -229
  179. package/dist/kit/blueprints/matches.d.ts +0 -84
  180. package/dist/kit/blueprints/matches.d.ts.map +0 -1
  181. package/dist/kit/blueprints/matches.js +0 -349
  182. package/dist/kit/blueprints/moderation.d.ts +0 -32
  183. package/dist/kit/blueprints/moderation.d.ts.map +0 -1
  184. package/dist/kit/blueprints/moderation.js +0 -140
  185. package/dist/kit/blueprints/npcs.d.ts +0 -78
  186. package/dist/kit/blueprints/npcs.d.ts.map +0 -1
  187. package/dist/kit/blueprints/npcs.js +0 -125
  188. package/dist/kit/blueprints/plots.d.ts +0 -63
  189. package/dist/kit/blueprints/plots.d.ts.map +0 -1
  190. package/dist/kit/blueprints/plots.js +0 -151
  191. package/dist/kit/blueprints/progression.d.ts +0 -68
  192. package/dist/kit/blueprints/progression.d.ts.map +0 -1
  193. package/dist/kit/blueprints/progression.js +0 -324
  194. package/dist/kit/blueprints/quests.d.ts +0 -72
  195. package/dist/kit/blueprints/quests.d.ts.map +0 -1
  196. package/dist/kit/blueprints/quests.js +0 -285
  197. package/dist/kit/blueprints/worldsim.d.ts +0 -91
  198. package/dist/kit/blueprints/worldsim.d.ts.map +0 -1
  199. package/dist/kit/blueprints/worldsim.js +0 -468
  200. package/dist/kit/combat.d.ts +0 -141
  201. package/dist/kit/combat.d.ts.map +0 -1
  202. package/dist/kit/combat.js +0 -196
  203. package/dist/kit/decks.d.ts +0 -157
  204. package/dist/kit/decks.d.ts.map +0 -1
  205. package/dist/kit/decks.js +0 -186
  206. package/dist/kit/director.d.ts +0 -88
  207. package/dist/kit/director.d.ts.map +0 -1
  208. package/dist/kit/director.js +0 -86
  209. package/dist/kit/economy.d.ts +0 -289
  210. package/dist/kit/economy.d.ts.map +0 -1
  211. package/dist/kit/economy.js +0 -427
  212. package/dist/kit/engine.d.ts +0 -48
  213. package/dist/kit/engine.d.ts.map +0 -1
  214. package/dist/kit/engine.js +0 -113
  215. package/dist/kit/features.d.ts +0 -60
  216. package/dist/kit/features.d.ts.map +0 -1
  217. package/dist/kit/features.js +0 -65
  218. package/dist/kit/instances.d.ts +0 -52
  219. package/dist/kit/instances.d.ts.map +0 -1
  220. package/dist/kit/instances.js +0 -60
  221. package/dist/kit/inventory.d.ts +0 -129
  222. package/dist/kit/inventory.d.ts.map +0 -1
  223. package/dist/kit/inventory.js +0 -200
  224. package/dist/kit/leaderboards.d.ts +0 -86
  225. package/dist/kit/leaderboards.d.ts.map +0 -1
  226. package/dist/kit/leaderboards.js +0 -133
  227. package/dist/kit/liveops.d.ts +0 -112
  228. package/dist/kit/liveops.d.ts.map +0 -1
  229. package/dist/kit/liveops.js +0 -183
  230. package/dist/kit/loot.d.ts +0 -128
  231. package/dist/kit/loot.d.ts.map +0 -1
  232. package/dist/kit/loot.js +0 -160
  233. package/dist/kit/matches.d.ts +0 -301
  234. package/dist/kit/matches.d.ts.map +0 -1
  235. package/dist/kit/matches.js +0 -458
  236. package/dist/kit/matchmaking.d.ts +0 -57
  237. package/dist/kit/matchmaking.d.ts.map +0 -1
  238. package/dist/kit/matchmaking.js +0 -59
  239. package/dist/kit/minigames.d.ts +0 -30
  240. package/dist/kit/minigames.d.ts.map +0 -1
  241. package/dist/kit/minigames.js +0 -38
  242. package/dist/kit/mobs.d.ts +0 -90
  243. package/dist/kit/mobs.d.ts.map +0 -1
  244. package/dist/kit/mobs.js +0 -98
  245. package/dist/kit/moderation.d.ts +0 -73
  246. package/dist/kit/moderation.d.ts.map +0 -1
  247. package/dist/kit/moderation.js +0 -103
  248. package/dist/kit/movement.d.ts +0 -78
  249. package/dist/kit/movement.d.ts.map +0 -1
  250. package/dist/kit/movement.js +0 -103
  251. package/dist/kit/notifications.d.ts +0 -45
  252. package/dist/kit/notifications.d.ts.map +0 -1
  253. package/dist/kit/notifications.js +0 -67
  254. package/dist/kit/npcs.d.ts +0 -226
  255. package/dist/kit/npcs.d.ts.map +0 -1
  256. package/dist/kit/npcs.js +0 -141
  257. package/dist/kit/objects.d.ts +0 -116
  258. package/dist/kit/objects.d.ts.map +0 -1
  259. package/dist/kit/objects.js +0 -119
  260. package/dist/kit/pets.d.ts +0 -85
  261. package/dist/kit/pets.d.ts.map +0 -1
  262. package/dist/kit/pets.js +0 -96
  263. package/dist/kit/plots.d.ts +0 -85
  264. package/dist/kit/plots.d.ts.map +0 -1
  265. package/dist/kit/plots.js +0 -113
  266. package/dist/kit/progression.d.ts +0 -181
  267. package/dist/kit/progression.d.ts.map +0 -1
  268. package/dist/kit/progression.js +0 -265
  269. package/dist/kit/quests.d.ts +0 -171
  270. package/dist/kit/quests.d.ts.map +0 -1
  271. package/dist/kit/quests.js +0 -237
  272. package/dist/kit/racing.d.ts +0 -85
  273. package/dist/kit/racing.d.ts.map +0 -1
  274. package/dist/kit/racing.js +0 -99
  275. package/dist/kit/shared.d.ts +0 -73
  276. package/dist/kit/shared.d.ts.map +0 -1
  277. package/dist/kit/shared.js +0 -101
  278. package/dist/kit/telemetry.d.ts +0 -66
  279. package/dist/kit/telemetry.d.ts.map +0 -1
  280. package/dist/kit/telemetry.js +0 -133
  281. package/dist/kit/territory.d.ts +0 -97
  282. package/dist/kit/territory.d.ts.map +0 -1
  283. package/dist/kit/territory.js +0 -114
  284. package/dist/kit/worldsim.d.ts +0 -263
  285. package/dist/kit/worldsim.d.ts.map +0 -1
  286. package/dist/kit/worldsim.js +0 -268
  287. package/dist/stores/model.d.ts +0 -81
  288. package/dist/stores/model.d.ts.map +0 -1
  289. 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
- }