@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,468 +0,0 @@
1
- import { kitPolicyJson, ownerEqualsCaller, ownerMirrorProperty, toSnakeCase, } from './core.js';
2
- /** Compute the type/function names a worldsim blueprint (and its runtime helper) uses. */
3
- export function worldsimNames(typePrefix = '') {
4
- const fnPrefix = typePrefix ? `${toSnakeCase(typePrefix)}_` : '';
5
- const autoPrefix = fnPrefix.replace(/_/g, '-');
6
- return {
7
- worldStateType: `${typePrefix}WorldState`,
8
- nodeType: `${typePrefix}ResourceNode`,
9
- cropType: `${typePrefix}Crop`,
10
- spawnerType: `${typePrefix}WaveSpawner`,
11
- advanceTimeFn: `${fnPrefix}advance_time`,
12
- setWeatherFn: `${fnPrefix}set_weather`,
13
- regenNodeFn: `${fnPrefix}regen_node`,
14
- gatherNodeFn: `${fnPrefix}gather_node`,
15
- growCropFn: `${fnPrefix}grow_crop`,
16
- harvestFn: `${fnPrefix}harvest`,
17
- spawnWaveFn: `${fnPrefix}spawn_wave`,
18
- clockAutomation: `${autoPrefix}world-clock`,
19
- regenAutomation: `${autoPrefix}node-regen`,
20
- growthAutomation: `${autoPrefix}crop-growth`,
21
- waveAutomation: `${autoPrefix}wave-spawner`,
22
- };
23
- }
24
- /**
25
- * Blueprint for **world simulation**: day/night + weather (`WorldState`
26
- * singleton), regenerating `ResourceNode`s, growing `Crop`s / production
27
- * jobs, and `WaveSpawner` counters — all driven by interval automations on the
28
- * automations simulation tier (seconds, never per-frame).
29
- *
30
- * **These automations run only while the app has a player in it.** Since
31
- * 2026-09-01 scheduled work for an empty app is skipped and rescheduled from the
32
- * moment a player returns; missed runs are never made up. Design the tick to be
33
- * IDEMPOTENT IN ELAPSED TIME rather than to assume a fixed cadence: read the
34
- * clock, advance the world by however long it has been, and write the result. A
35
- * crop that grows by one step per tick will stall while nobody is playing; one
36
- * that grows by `now - lastTick` will be correct whenever anybody looks at it.
37
- *
38
- * The world clock emits a **spatial notification** at the world anchor chunk
39
- * each tick, so nearby clients update the sky push-style instead of polling;
40
- * everything else is pull-on-demand (or wire your own notify-to-pull pings).
41
- * Wave spawners only advance counters — actual entity spawning belongs on
42
- * the replication plane under host authority (the BWF hybrid).
43
- *
44
- * Runtime counterpart: `client.kit(appId).worldsim`.
45
- */
46
- export function worldsimBlueprint(options = {}) {
47
- const { typePrefix = '', ownerIdKind: kind = 'int' } = options;
48
- const names = worldsimNames(typePrefix);
49
- const automationOnly = kitPolicyJson({ type: 'is_automation' });
50
- const containerTypes = [];
51
- const propertyDefinitions = [];
52
- const functions = [];
53
- const automations = [];
54
- // --- Day/night + weather ---------------------------------------------------
55
- if (options.time !== false) {
56
- const time = options.time === undefined ? {} : options.time;
57
- const hoursPerDay = time.hoursPerDay ?? 24;
58
- const weather = time.weather ?? true;
59
- const lastHour = hoursPerDay - 1;
60
- containerTypes.push({
61
- typeName: names.worldStateType,
62
- displayName: names.worldStateType,
63
- instantiableBy: 'admin',
64
- description: 'Singleton world clock/weather state (create one via kit.worldsim.ensureWorld).',
65
- });
66
- propertyDefinitions.push({
67
- containerTypeName: names.worldStateType,
68
- key: 'time_of_day',
69
- valueType: 'int',
70
- defaultValueJson: '0',
71
- description: `In-game hour, 0..${lastHour}, advanced by the world-clock automation.`,
72
- }, {
73
- containerTypeName: names.worldStateType,
74
- key: 'day',
75
- valueType: 'int',
76
- defaultValueJson: '0',
77
- description: 'In-game day counter (bumps when the clock wraps).',
78
- }, {
79
- containerTypeName: names.worldStateType,
80
- key: 'weather',
81
- valueType: 'string',
82
- defaultValueJson: '"clear"',
83
- description: "Current weather: 'clear' | 'rain' | 'storm'.",
84
- }, {
85
- containerTypeName: names.worldStateType,
86
- key: 'cx',
87
- valueType: 'int',
88
- defaultValueJson: '0',
89
- description: 'Anchor chunk of the time-changed spatial notification.',
90
- }, {
91
- containerTypeName: names.worldStateType,
92
- key: 'cy',
93
- valueType: 'int',
94
- defaultValueJson: '0',
95
- description: 'Anchor chunk (y).',
96
- }, {
97
- containerTypeName: names.worldStateType,
98
- key: 'cz',
99
- valueType: 'int',
100
- defaultValueJson: '0',
101
- description: 'Anchor chunk (z).',
102
- });
103
- functions.push({
104
- name: names.advanceTimeFn,
105
- containerTypeName: names.worldStateType,
106
- returnType: 'int',
107
- mutations: [
108
- {
109
- target: 'self',
110
- property: 'day',
111
- expression: `if(self.time_of_day >= ${lastHour}, self.day + 1, self.day)`,
112
- },
113
- {
114
- target: 'self',
115
- property: 'time_of_day',
116
- expression: `(self.time_of_day + 1) % ${hoursPerDay}`,
117
- },
118
- ...(weather
119
- ? [
120
- {
121
- target: 'self',
122
- property: 'weather',
123
- expression: 'if(rand() < 0.7, "clear", if(rand() < 0.5, "rain", "storm"))',
124
- },
125
- ]
126
- : []),
127
- ],
128
- returnExpression: 'self.time_of_day',
129
- invokePolicyJson: automationOnly,
130
- autonomousInvocable: true,
131
- notifications: [
132
- {
133
- kind: 'spatial',
134
- args: [
135
- { name: 'chunk_x', expression: 'self.cx' },
136
- { name: 'chunk_y', expression: 'self.cy' },
137
- { name: 'chunk_z', expression: 'self.cz' },
138
- { name: 'event_type', expression: '1' },
139
- { name: 'state', expression: 'to_string(self.time_of_day)' },
140
- { name: 'distance', expression: String(time.notifyDistance ?? 8) },
141
- ],
142
- },
143
- ],
144
- description: 'World-clock tick (automation-only): advances the hour/day, re-rolls weather, and pushes a spatial time-changed ping so nearby clients skip polling.',
145
- });
146
- if (weather) {
147
- functions.push({
148
- name: names.setWeatherFn,
149
- containerTypeName: names.worldStateType,
150
- returnType: 'string',
151
- parameters: [
152
- {
153
- name: 'weather',
154
- valueType: 'string',
155
- required: true,
156
- description: "The weather to force (e.g. 'storm').",
157
- },
158
- ],
159
- mutations: [
160
- { target: 'self', property: 'weather', expression: '$weather' },
161
- ],
162
- returnExpression: 'self.weather',
163
- // not(allow) denies everyone — app admins bypass invoke policies,
164
- // making this an admin-only lever.
165
- invokePolicyJson: kitPolicyJson({ type: 'not', rule: { type: 'allow' } }),
166
- description: 'Force the weather (app admins only — everyone else is denied).',
167
- });
168
- }
169
- automations.push({
170
- name: names.clockAutomation,
171
- functionName: names.advanceTimeFn,
172
- targetMode: 'type',
173
- targetTypeName: names.worldStateType,
174
- triggerType: 'schedule',
175
- scheduleKind: 'interval',
176
- intervalMs: time.intervalMs ?? 60000,
177
- maxTargets: 1,
178
- description: 'Advances the world clock (and weather) every tick.',
179
- });
180
- }
181
- // --- Resource nodes ----------------------------------------------------------
182
- if (options.nodes !== false) {
183
- const nodes = options.nodes === undefined ? {} : options.nodes;
184
- containerTypes.push({
185
- typeName: names.nodeType,
186
- displayName: names.nodeType,
187
- instantiableBy: 'admin',
188
- description: 'A shared harvestable resource node that regenerates server-side.',
189
- });
190
- propertyDefinitions.push({
191
- containerTypeName: names.nodeType,
192
- key: 'node_id',
193
- valueType: 'string',
194
- defaultValueJson: '""',
195
- description: 'Stable node identifier.',
196
- }, {
197
- containerTypeName: names.nodeType,
198
- key: 'resource_item_id',
199
- valueType: 'string',
200
- defaultValueJson: '""',
201
- description: 'The item gathering yields (matched against the stack).',
202
- }, {
203
- containerTypeName: names.nodeType,
204
- key: 'amount',
205
- valueType: 'int',
206
- defaultValueJson: '0',
207
- description: 'Units currently available.',
208
- }, {
209
- containerTypeName: names.nodeType,
210
- key: 'max_amount',
211
- valueType: 'int',
212
- defaultValueJson: '100',
213
- description: 'Regeneration ceiling.',
214
- }, {
215
- containerTypeName: names.nodeType,
216
- key: 'regen_rate',
217
- valueType: 'int',
218
- defaultValueJson: '1',
219
- description: 'Units regenerated per tick.',
220
- }, {
221
- containerTypeName: names.nodeType,
222
- key: 'x',
223
- valueType: 'float',
224
- defaultValueJson: '0',
225
- description: 'World position (informational).',
226
- }, {
227
- containerTypeName: names.nodeType,
228
- key: 'y',
229
- valueType: 'float',
230
- defaultValueJson: '0',
231
- description: 'World position.',
232
- }, {
233
- containerTypeName: names.nodeType,
234
- key: 'z',
235
- valueType: 'float',
236
- defaultValueJson: '0',
237
- description: 'World position.',
238
- });
239
- functions.push({
240
- name: names.regenNodeFn,
241
- containerTypeName: names.nodeType,
242
- returnType: 'int',
243
- mutations: [
244
- {
245
- target: 'self',
246
- property: 'amount',
247
- expression: 'min(self.max_amount, self.amount + self.regen_rate)',
248
- },
249
- ],
250
- returnExpression: 'self.amount',
251
- invokePolicyJson: automationOnly,
252
- autonomousInvocable: true,
253
- description: 'Server-driven node regeneration tick (automation-only).',
254
- }, {
255
- name: names.gatherNodeFn,
256
- containerTypeName: names.nodeType,
257
- returnType: 'int',
258
- parameters: [
259
- {
260
- name: 'amount',
261
- valueType: 'int',
262
- required: true,
263
- description: 'Units to gather (must not exceed the node amount).',
264
- },
265
- {
266
- name: 'to_stack_id',
267
- valueType: 'container_ref',
268
- required: true,
269
- description: 'A caller-owned stack of the node resource that receives the units.',
270
- },
271
- ],
272
- mutations: [
273
- { target: 'self', property: 'amount', expression: 'self.amount - $amount' },
274
- {
275
- target: 'ref($to_stack_id)',
276
- property: 'quantity',
277
- expression: 'ref($to_stack_id).quantity + $amount',
278
- },
279
- ],
280
- returnExpression: 'self.amount',
281
- invokePolicyJson: kitPolicyJson({
282
- type: 'condition',
283
- expression: [
284
- '$amount > 0',
285
- 'self.amount >= $amount',
286
- 'ref($to_stack_id).item_id == self.resource_item_id',
287
- ownerEqualsCaller('ref($to_stack_id).owner_user_id', kind),
288
- ].join(' && '),
289
- }),
290
- description: 'Gather from a shared node into your stack: the node decrement and the grant commit atomically (no over-gathering races).',
291
- });
292
- automations.push({
293
- name: names.regenAutomation,
294
- functionName: names.regenNodeFn,
295
- targetMode: 'type',
296
- targetTypeName: names.nodeType,
297
- triggerType: 'schedule',
298
- scheduleKind: 'interval',
299
- intervalMs: nodes.intervalMs ?? 60000,
300
- maxTargets: 64,
301
- selectorJson: JSON.stringify({
302
- selfWhere: [{ key: 'amount', op: '<', value: 'self.max_amount' }],
303
- }),
304
- description: 'Regenerates depleted resource nodes.',
305
- });
306
- }
307
- // --- Crops / production jobs -------------------------------------------------
308
- if (options.crops !== false) {
309
- const crops = options.crops === undefined ? {} : options.crops;
310
- containerTypes.push({
311
- typeName: names.cropType,
312
- displayName: names.cropType,
313
- instantiableBy: 'member',
314
- description: 'A planted crop / production job that matures server-side.',
315
- });
316
- propertyDefinitions.push(ownerMirrorProperty(names.cropType, kind), {
317
- containerTypeName: names.cropType,
318
- key: 'stage',
319
- valueType: 'int',
320
- defaultValueJson: '0',
321
- description: 'Growth stage, advanced by the crop-growth automation.',
322
- }, {
323
- containerTypeName: names.cropType,
324
- key: 'max_stage',
325
- valueType: 'int',
326
- defaultValueJson: '3',
327
- description: 'Stage at which the crop is harvestable.',
328
- }, {
329
- containerTypeName: names.cropType,
330
- key: 'output_item_id',
331
- valueType: 'string',
332
- defaultValueJson: '""',
333
- description: 'The item harvesting yields.',
334
- }, {
335
- containerTypeName: names.cropType,
336
- key: 'output_qty',
337
- valueType: 'int',
338
- defaultValueJson: '1',
339
- description: 'Units yielded per harvest.',
340
- });
341
- functions.push({
342
- name: names.growCropFn,
343
- containerTypeName: names.cropType,
344
- returnType: 'int',
345
- mutations: [
346
- {
347
- target: 'self',
348
- property: 'stage',
349
- expression: 'min(self.stage + 1, self.max_stage)',
350
- },
351
- ],
352
- returnExpression: 'self.stage',
353
- invokePolicyJson: automationOnly,
354
- autonomousInvocable: true,
355
- description: 'Server-driven growth tick (automation-only).',
356
- }, {
357
- name: names.harvestFn,
358
- containerTypeName: names.cropType,
359
- returnType: 'int',
360
- parameters: [
361
- {
362
- name: 'to_stack_id',
363
- valueType: 'container_ref',
364
- required: true,
365
- description: 'A caller-owned stack of the output item that receives the yield.',
366
- },
367
- ],
368
- mutations: [
369
- { target: 'self', property: 'stage', expression: '0' },
370
- {
371
- target: 'ref($to_stack_id)',
372
- property: 'quantity',
373
- expression: 'ref($to_stack_id).quantity + self.output_qty',
374
- },
375
- ],
376
- returnExpression: 'self.output_qty',
377
- invokePolicyJson: kitPolicyJson({
378
- type: 'and',
379
- rules: [
380
- { type: 'owner_of_self' },
381
- {
382
- type: 'condition',
383
- expression: [
384
- 'self.stage >= self.max_stage',
385
- 'ref($to_stack_id).item_id == self.output_item_id',
386
- ownerEqualsCaller('ref($to_stack_id).owner_user_id', kind),
387
- ].join(' && '),
388
- },
389
- ],
390
- }),
391
- description: 'Harvest a grown crop: the stage reset and the yield grant commit atomically; regrows via the automation.',
392
- });
393
- automations.push({
394
- name: names.growthAutomation,
395
- functionName: names.growCropFn,
396
- targetMode: 'type',
397
- targetTypeName: names.cropType,
398
- triggerType: 'schedule',
399
- scheduleKind: 'interval',
400
- intervalMs: crops.intervalMs ?? 60000,
401
- maxTargets: 128,
402
- selectorJson: JSON.stringify({
403
- selfWhere: [{ key: 'stage', op: '<', value: 'self.max_stage' }],
404
- }),
405
- description: 'Advances growing crops one stage per tick.',
406
- });
407
- }
408
- // --- Wave spawners -------------------------------------------------------------
409
- if (options.waves) {
410
- containerTypes.push({
411
- typeName: names.spawnerType,
412
- displayName: names.spawnerType,
413
- instantiableBy: 'admin',
414
- description: 'A wave counter the server advances; entity spawning stays host-side on the replication plane.',
415
- });
416
- propertyDefinitions.push({
417
- containerTypeName: names.spawnerType,
418
- key: 'wave',
419
- valueType: 'int',
420
- defaultValueJson: '0',
421
- description: 'Current wave number.',
422
- }, {
423
- containerTypeName: names.spawnerType,
424
- key: 'next_wave_size',
425
- valueType: 'int',
426
- defaultValueJson: '5',
427
- description: 'Entities the host should spawn for the next wave.',
428
- });
429
- functions.push({
430
- name: names.spawnWaveFn,
431
- containerTypeName: names.spawnerType,
432
- returnType: 'int',
433
- mutations: [
434
- { target: 'self', property: 'wave', expression: 'self.wave + 1' },
435
- {
436
- target: 'self',
437
- property: 'next_wave_size',
438
- expression: `self.next_wave_size + ${options.waves.growth ?? 1}`,
439
- },
440
- ],
441
- returnExpression: 'self.wave',
442
- invokePolicyJson: automationOnly,
443
- autonomousInvocable: true,
444
- description: 'Server-driven wave advance (automation-only): bumps the counters the host reads to spawn entities.',
445
- });
446
- automations.push({
447
- name: names.waveAutomation,
448
- functionName: names.spawnWaveFn,
449
- targetMode: 'type',
450
- targetTypeName: names.spawnerType,
451
- triggerType: 'schedule',
452
- scheduleKind: 'interval',
453
- intervalMs: options.waves.intervalMs ?? 60000,
454
- maxTargets: 16,
455
- description: 'Advances wave counters on schedule.',
456
- });
457
- }
458
- if (!containerTypes.length) {
459
- throw new Error('worldsimBlueprint has every feature disabled — nothing to build');
460
- }
461
- return {
462
- name: names.worldStateType,
463
- containerTypes,
464
- propertyDefinitions,
465
- functions,
466
- automations,
467
- };
468
- }
@@ -1,141 +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 KitInvokeResult } from './shared.js';
5
- /** Options for {@link CombatKit}. Must match the deployed combat blueprint. */
6
- export interface CombatKitOptions {
7
- /** The `typePrefix` the combat blueprint was deployed with. */
8
- typePrefix?: string;
9
- /**
10
- * The compute module whose referee serves `attack_mob` when the app runs
11
- * an engine. Defaults to `'mob-engine'`.
12
- */
13
- engineModuleName?: string;
14
- }
15
- /** The verdict of a routed attack ({@link CombatKit.attackRouted}). */
16
- export interface KitRoutedAttack {
17
- success: boolean;
18
- /** The target's remaining health/hp after an accepted hit. */
19
- health?: number;
20
- killed?: boolean;
21
- /** The denial reason (engine referee) or error message (model path). */
22
- reason?: string;
23
- /** Which authority resolved the attack. */
24
- via: 'engine' | 'model';
25
- }
26
- /** A parsed view of one combatant. */
27
- export interface KitCombatant {
28
- containerId: string;
29
- displayName: string;
30
- ownerUserId: string | null;
31
- combatKey: string;
32
- hp: number;
33
- maxHp: number;
34
- attack: number;
35
- defense: number;
36
- alive: boolean;
37
- }
38
- /** A parsed view of one status effect. */
39
- export interface KitStatusEffect {
40
- containerId: string;
41
- displayName: string;
42
- ownerUserId: string | null;
43
- effectId: string;
44
- targetKey: string;
45
- magnitude: number;
46
- ticksLeft: number;
47
- }
48
- /**
49
- * Runtime helpers for the {@link combatBlueprint} conventions: spawn
50
- * combatants, attack (server-side damage formula + death flip), arm status
51
- * effects the tick automation applies over time, respawn, and route
52
- * competitive realtime attacks through a compute referee. `hostSynced`
53
- * remains a low-stakes/legacy fallback for persisting elected-host state;
54
- * it is not an anti-cheat boundary. Denials resolve with `success: false`.
55
- *
56
- * Obtained via `client.kit(appId).combat`.
57
- */
58
- export declare class CombatKit {
59
- private readonly appId;
60
- private readonly gameModel;
61
- private readonly engines?;
62
- private readonly names;
63
- private readonly engineModuleName;
64
- constructor(appId: Scalars['BigInt']['input'], gameModel: GameModelAPI, options?: CombatKitOptions, engines?: EngineDetector | undefined);
65
- /**
66
- * Route an attack through the strongest available authority: the compute
67
- * referee (`attack_mob` on the mob engine — presence/range validated
68
- * server-side) when the engine is deployed (capability-detected, cached),
69
- * else today's model attack function. One call, both deployments.
70
- *
71
- * @param input.targetId - The target container (engine mob slot or model
72
- * combatant).
73
- * @param input.attackerId - The caller's combatant container — required
74
- * for the model path, ignored by the engine referee (it referees by the
75
- * caller's live actor position).
76
- * @param input.amount - Engine-path damage (clamped by the referee).
77
- */
78
- attackRouted(input: {
79
- targetId: string;
80
- attackerId?: string;
81
- amount?: number;
82
- }): Promise<KitRoutedAttack>;
83
- /**
84
- * Spawn a combatant with a unique `combat_key` (the status-effect join
85
- * key) and the `owner_user_id` mirror.
86
- */
87
- spawnCombatant(input: {
88
- ownerUserId: Scalars['BigInt']['input'];
89
- displayName: string;
90
- hp?: number;
91
- maxHp?: number;
92
- attack?: number;
93
- defense?: number;
94
- combatKey?: string;
95
- sessionId?: string;
96
- properties?: SeedPropertyInput[];
97
- }): Promise<{
98
- __typename?: "GmContainer";
99
- containerId: string;
100
- appId: string;
101
- sessionId: string | null;
102
- typeName: string;
103
- displayName: string;
104
- description: string | null;
105
- ownerUserId: string | null;
106
- metadataJson: string;
107
- }>;
108
- /** Read one combatant's state. */
109
- state(combatantId: string): Promise<KitCombatant>;
110
- /**
111
- * Attack a target with your combatant. The damage formula and the death
112
- * flip run server-side. Resolves with the target's remaining hp.
113
- */
114
- attack(attackerId: string, targetId: string): Promise<KitInvokeResult<number>>;
115
- /**
116
- * Arm a status effect against a target's `combat_key`: creates the
117
- * caller's StatusEffect container (when `effectContainerId` is omitted)
118
- * and invokes the gated apply function; the interval automation then
119
- * ticks it server-side.
120
- */
121
- applyEffect(input: {
122
- targetKey: string;
123
- effectId: string;
124
- magnitude: number;
125
- ticks: number;
126
- effectContainerId?: string;
127
- sessionId?: string;
128
- }): Promise<KitInvokeResult<number>>;
129
- /** List the active status effects targeting a combat_key. */
130
- effects(targetKey?: string): Promise<KitStatusEffect[]>;
131
- /** Respawn your downed combatant at full hp. */
132
- respawn(combatantId: string): Promise<KitInvokeResult<number>>;
133
- /** Revive a downed combatant (blueprint deployed with `reviveGroup`). */
134
- revive(combatantId: string): Promise<KitInvokeResult<number>>;
135
- /**
136
- * Persist host-simulated hp (blueprint deployed with `hostSynced: true`;
137
- * `is_host` enforced server-side). Resolves with the clamped hp.
138
- */
139
- syncCombatant(combatantId: string, hp: number): Promise<KitInvokeResult<number>>;
140
- }
141
- //# sourceMappingURL=combat.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"combat.d.ts","sourceRoot":"","sources":["../../src/kit/combat.ts"],"names":[],"mappings":"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"}