@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.
- package/MIGRATION.md +129 -1
- package/README.md +97 -164
- package/dist/crowdy-client.d.ts +12 -31
- package/dist/crowdy-client.d.ts.map +1 -1
- package/dist/crowdy-client.js +15 -37
- package/dist/crowdy-dsh/bridge.d.ts.map +1 -1
- package/dist/crowdy-dsh/bridge.js +3 -6
- package/dist/crowdy-studio/controller.d.ts +34 -59
- package/dist/crowdy-studio/controller.d.ts.map +1 -1
- package/dist/crowdy-studio/controller.js +96 -225
- package/dist/crowdy-studio/diagnostics.d.ts +3 -12
- package/dist/crowdy-studio/diagnostics.d.ts.map +1 -1
- package/dist/crowdy-studio/dom-shell.d.ts +2 -4
- package/dist/crowdy-studio/dom-shell.d.ts.map +1 -1
- package/dist/crowdy-studio/dom-shell.js +16 -49
- package/dist/crowdy-studio/embed/hud-layer.d.ts +1 -2
- package/dist/crowdy-studio/embed/hud-layer.d.ts.map +1 -1
- package/dist/crowdy-studio/embed/panel.d.ts +3 -13
- package/dist/crowdy-studio/embed/panel.d.ts.map +1 -1
- package/dist/crowdy-studio/embed/panel.js +3 -6
- package/dist/crowdy-studio/index.d.ts +1 -3
- package/dist/crowdy-studio/index.d.ts.map +1 -1
- package/dist/crowdy-studio/index.js +0 -2
- package/dist/crowdy-studio/models.d.ts +3 -4
- package/dist/crowdy-studio/models.d.ts.map +1 -1
- package/dist/crowdy-studio/starter-projects.d.ts +8 -12
- package/dist/crowdy-studio/starter-projects.d.ts.map +1 -1
- package/dist/crowdy-studio/starter-projects.js +12 -103
- package/dist/domains/appAccess.d.ts +14 -1
- package/dist/domains/appAccess.d.ts.map +1 -1
- package/dist/domains/appAccess.js +37 -1
- package/dist/domains/apps.d.ts +1 -10
- package/dist/domains/apps.d.ts.map +1 -1
- package/dist/domains/apps.js +1 -16
- package/dist/domains/host.d.ts +3 -3
- package/dist/domains/host.js +3 -3
- package/dist/domains/hosting.d.ts +0 -6
- package/dist/domains/hosting.d.ts.map +1 -1
- package/dist/domains/hosting.js +1 -16
- package/dist/domains/marketplace.d.ts +9 -70
- package/dist/domains/marketplace.d.ts.map +1 -1
- package/dist/domains/marketplace.js +9 -120
- package/dist/domains/organizations.d.ts +1 -9
- package/dist/domains/organizations.d.ts.map +1 -1
- package/dist/domains/organizations.js +1 -15
- package/dist/domains/payments.d.ts +5 -48
- package/dist/domains/payments.d.ts.map +1 -1
- package/dist/domains/payments.js +5 -57
- package/dist/domains/playerWallet.d.ts +6 -12
- package/dist/domains/playerWallet.d.ts.map +1 -1
- package/dist/domains/playerWallet.js +6 -21
- package/dist/domains/quotas.d.ts +20 -7
- package/dist/domains/quotas.d.ts.map +1 -1
- package/dist/domains/quotas.js +15 -6
- package/dist/domains/users.d.ts +7 -74
- package/dist/domains/users.d.ts.map +1 -1
- package/dist/domains/users.js +7 -105
- package/dist/errors.d.ts +7 -13
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +6 -10
- package/dist/generated/graphql.d.ts +955 -8272
- package/dist/generated/graphql.d.ts.map +1 -1
- package/dist/generated/graphql.js +5 -329
- package/dist/grid-mods/exec-client-halves.d.ts +19 -3
- package/dist/grid-mods/exec-client-halves.d.ts.map +1 -1
- package/dist/grid-mods/exec-client-halves.js +17 -2
- package/dist/grid-mods/grid-host-calls.d.ts +29 -17
- package/dist/grid-mods/grid-host-calls.d.ts.map +1 -1
- package/dist/grid-mods/grid-host-calls.js +40 -46
- package/dist/grid-mods/mod-runtime.d.ts +18 -11
- package/dist/grid-mods/mod-runtime.d.ts.map +1 -1
- package/dist/grid-mods/mod-runtime.js +4 -2
- package/dist/grid-scope.d.ts +0 -189
- package/dist/grid-scope.d.ts.map +1 -1
- package/dist/grid-scope.js +0 -70
- package/dist/index.d.ts +12 -18
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +10 -16
- package/dist/kit/actions.d.ts +5 -9
- package/dist/kit/actions.d.ts.map +1 -1
- package/dist/kit/actions.js +5 -9
- package/dist/kit/index.d.ts +2 -33
- package/dist/kit/index.d.ts.map +1 -1
- package/dist/kit/index.js +1 -32
- package/dist/kit/kit.d.ts +8 -208
- package/dist/kit/kit.d.ts.map +1 -1
- package/dist/kit/kit.js +5 -163
- package/dist/kit/social.d.ts +1 -3
- package/dist/kit/social.d.ts.map +1 -1
- package/dist/kit/social.js +1 -3
- package/dist/kit/wire.d.ts +16 -5
- package/dist/kit/wire.d.ts.map +1 -1
- package/dist/kit/wire.js +19 -5
- package/dist/live-coding/assets/browser-authoring-index.json +1 -1
- package/dist/live-coding/assets/manifest.json +1 -1
- package/dist/live-coding/browser-authoring-index.generated.d.ts.map +1 -1
- package/dist/live-coding/browser-authoring-index.generated.js +1496 -4386
- package/dist/live-coding/rust-analysis.d.ts.map +1 -1
- package/dist/live-coding/rust-analysis.js +30 -34
- package/dist/player-runtime/client-host-calls.d.ts +8 -0
- package/dist/player-runtime/client-host-calls.d.ts.map +1 -0
- package/dist/player-runtime/client-host-calls.js +28 -0
- package/dist/player-runtime/glue-runtime.d.ts +24 -20
- package/dist/player-runtime/glue-runtime.d.ts.map +1 -1
- package/dist/player-runtime/glue-runtime.js +26 -55
- package/dist/player-runtime/glue-sab.d.ts +2 -2
- package/dist/player-runtime/glue-sab.js +2 -2
- package/dist/player-runtime/player-code-broker.d.ts +70 -43
- package/dist/player-runtime/player-code-broker.d.ts.map +1 -1
- package/dist/player-runtime/player-code-broker.js +159 -64
- package/dist/player-runtime/player-glue-worker.d.ts +8 -9
- package/dist/player-runtime/player-glue-worker.d.ts.map +1 -1
- package/dist/player-runtime/player-glue-worker.js +26 -11
- package/dist/stores/inbox.d.ts +1 -1
- package/dist/stores/inbox.d.ts.map +1 -1
- package/dist/stores/index.d.ts +0 -11
- package/dist/stores/index.d.ts.map +1 -1
- package/dist/stores/index.js +0 -4
- package/dist/stores/session.d.ts +0 -2
- package/dist/stores/session.d.ts.map +1 -1
- package/package.json +1 -1
- package/dist/crowdy-studio/model-lint-log.d.ts +0 -76
- package/dist/crowdy-studio/model-lint-log.d.ts.map +0 -1
- package/dist/crowdy-studio/model-lint-log.js +0 -93
- package/dist/crowdy-studio/model-lint.d.ts +0 -61
- package/dist/crowdy-studio/model-lint.d.ts.map +0 -1
- package/dist/crowdy-studio/model-lint.js +0 -45
- package/dist/domains/compute.d.ts +0 -208
- package/dist/domains/compute.d.ts.map +0 -1
- package/dist/domains/compute.js +0 -274
- package/dist/domains/controlPlane.d.ts +0 -38
- package/dist/domains/controlPlane.d.ts.map +0 -1
- package/dist/domains/controlPlane.js +0 -43
- package/dist/domains/gameModel.d.ts +0 -1174
- package/dist/domains/gameModel.d.ts.map +0 -1
- package/dist/domains/gameModel.js +0 -1333
- package/dist/domains/playerCompute.d.ts +0 -91
- package/dist/domains/playerCompute.d.ts.map +0 -1
- package/dist/domains/playerCompute.js +0 -136
- package/dist/domains/playerModel.d.ts +0 -20
- package/dist/domains/playerModel.d.ts.map +0 -1
- package/dist/domains/playerModel.js +0 -54
- package/dist/kit/abilities.d.ts +0 -66
- package/dist/kit/abilities.d.ts.map +0 -1
- package/dist/kit/abilities.js +0 -71
- package/dist/kit/blueprints/combat.d.ts +0 -81
- package/dist/kit/blueprints/combat.d.ts.map +0 -1
- package/dist/kit/blueprints/combat.js +0 -357
- package/dist/kit/blueprints/core.d.ts +0 -222
- package/dist/kit/blueprints/core.d.ts.map +0 -1
- package/dist/kit/blueprints/core.js +0 -185
- package/dist/kit/blueprints/decks.d.ts +0 -50
- package/dist/kit/blueprints/decks.d.ts.map +0 -1
- package/dist/kit/blueprints/decks.js +0 -163
- package/dist/kit/blueprints/economy.d.ts +0 -88
- package/dist/kit/blueprints/economy.d.ts.map +0 -1
- package/dist/kit/blueprints/economy.js +0 -533
- package/dist/kit/blueprints/guild.d.ts +0 -51
- package/dist/kit/blueprints/guild.d.ts.map +0 -1
- package/dist/kit/blueprints/guild.js +0 -50
- package/dist/kit/blueprints/index.d.ts +0 -23
- package/dist/kit/blueprints/index.d.ts.map +0 -1
- package/dist/kit/blueprints/index.js +0 -22
- package/dist/kit/blueprints/inventory.d.ts +0 -84
- package/dist/kit/blueprints/inventory.d.ts.map +0 -1
- package/dist/kit/blueprints/inventory.js +0 -257
- package/dist/kit/blueprints/leaderboards.d.ts +0 -49
- package/dist/kit/blueprints/leaderboards.d.ts.map +0 -1
- package/dist/kit/blueprints/leaderboards.js +0 -126
- package/dist/kit/blueprints/liveops.d.ts +0 -42
- package/dist/kit/blueprints/liveops.d.ts.map +0 -1
- package/dist/kit/blueprints/liveops.js +0 -170
- package/dist/kit/blueprints/locks.d.ts +0 -82
- package/dist/kit/blueprints/locks.d.ts.map +0 -1
- package/dist/kit/blueprints/locks.js +0 -155
- package/dist/kit/blueprints/loot.d.ts +0 -90
- package/dist/kit/blueprints/loot.d.ts.map +0 -1
- package/dist/kit/blueprints/loot.js +0 -229
- package/dist/kit/blueprints/matches.d.ts +0 -84
- package/dist/kit/blueprints/matches.d.ts.map +0 -1
- package/dist/kit/blueprints/matches.js +0 -349
- package/dist/kit/blueprints/moderation.d.ts +0 -32
- package/dist/kit/blueprints/moderation.d.ts.map +0 -1
- package/dist/kit/blueprints/moderation.js +0 -140
- package/dist/kit/blueprints/npcs.d.ts +0 -78
- package/dist/kit/blueprints/npcs.d.ts.map +0 -1
- package/dist/kit/blueprints/npcs.js +0 -125
- package/dist/kit/blueprints/plots.d.ts +0 -63
- package/dist/kit/blueprints/plots.d.ts.map +0 -1
- package/dist/kit/blueprints/plots.js +0 -151
- package/dist/kit/blueprints/progression.d.ts +0 -68
- package/dist/kit/blueprints/progression.d.ts.map +0 -1
- package/dist/kit/blueprints/progression.js +0 -324
- package/dist/kit/blueprints/quests.d.ts +0 -72
- package/dist/kit/blueprints/quests.d.ts.map +0 -1
- package/dist/kit/blueprints/quests.js +0 -285
- package/dist/kit/blueprints/worldsim.d.ts +0 -91
- package/dist/kit/blueprints/worldsim.d.ts.map +0 -1
- package/dist/kit/blueprints/worldsim.js +0 -468
- package/dist/kit/combat.d.ts +0 -141
- package/dist/kit/combat.d.ts.map +0 -1
- package/dist/kit/combat.js +0 -196
- package/dist/kit/decks.d.ts +0 -157
- package/dist/kit/decks.d.ts.map +0 -1
- package/dist/kit/decks.js +0 -186
- package/dist/kit/director.d.ts +0 -88
- package/dist/kit/director.d.ts.map +0 -1
- package/dist/kit/director.js +0 -86
- package/dist/kit/economy.d.ts +0 -289
- package/dist/kit/economy.d.ts.map +0 -1
- package/dist/kit/economy.js +0 -427
- package/dist/kit/engine.d.ts +0 -48
- package/dist/kit/engine.d.ts.map +0 -1
- package/dist/kit/engine.js +0 -113
- package/dist/kit/features.d.ts +0 -60
- package/dist/kit/features.d.ts.map +0 -1
- package/dist/kit/features.js +0 -65
- package/dist/kit/instances.d.ts +0 -52
- package/dist/kit/instances.d.ts.map +0 -1
- package/dist/kit/instances.js +0 -60
- package/dist/kit/inventory.d.ts +0 -129
- package/dist/kit/inventory.d.ts.map +0 -1
- package/dist/kit/inventory.js +0 -200
- package/dist/kit/leaderboards.d.ts +0 -86
- package/dist/kit/leaderboards.d.ts.map +0 -1
- package/dist/kit/leaderboards.js +0 -133
- package/dist/kit/liveops.d.ts +0 -112
- package/dist/kit/liveops.d.ts.map +0 -1
- package/dist/kit/liveops.js +0 -183
- package/dist/kit/loot.d.ts +0 -128
- package/dist/kit/loot.d.ts.map +0 -1
- package/dist/kit/loot.js +0 -160
- package/dist/kit/matches.d.ts +0 -301
- package/dist/kit/matches.d.ts.map +0 -1
- package/dist/kit/matches.js +0 -458
- package/dist/kit/matchmaking.d.ts +0 -57
- package/dist/kit/matchmaking.d.ts.map +0 -1
- package/dist/kit/matchmaking.js +0 -59
- package/dist/kit/minigames.d.ts +0 -30
- package/dist/kit/minigames.d.ts.map +0 -1
- package/dist/kit/minigames.js +0 -38
- package/dist/kit/mobs.d.ts +0 -90
- package/dist/kit/mobs.d.ts.map +0 -1
- package/dist/kit/mobs.js +0 -98
- package/dist/kit/moderation.d.ts +0 -73
- package/dist/kit/moderation.d.ts.map +0 -1
- package/dist/kit/moderation.js +0 -103
- package/dist/kit/movement.d.ts +0 -78
- package/dist/kit/movement.d.ts.map +0 -1
- package/dist/kit/movement.js +0 -103
- package/dist/kit/notifications.d.ts +0 -45
- package/dist/kit/notifications.d.ts.map +0 -1
- package/dist/kit/notifications.js +0 -67
- package/dist/kit/npcs.d.ts +0 -226
- package/dist/kit/npcs.d.ts.map +0 -1
- package/dist/kit/npcs.js +0 -141
- package/dist/kit/objects.d.ts +0 -116
- package/dist/kit/objects.d.ts.map +0 -1
- package/dist/kit/objects.js +0 -119
- package/dist/kit/pets.d.ts +0 -85
- package/dist/kit/pets.d.ts.map +0 -1
- package/dist/kit/pets.js +0 -96
- package/dist/kit/plots.d.ts +0 -85
- package/dist/kit/plots.d.ts.map +0 -1
- package/dist/kit/plots.js +0 -113
- package/dist/kit/progression.d.ts +0 -181
- package/dist/kit/progression.d.ts.map +0 -1
- package/dist/kit/progression.js +0 -265
- package/dist/kit/quests.d.ts +0 -171
- package/dist/kit/quests.d.ts.map +0 -1
- package/dist/kit/quests.js +0 -237
- package/dist/kit/racing.d.ts +0 -85
- package/dist/kit/racing.d.ts.map +0 -1
- package/dist/kit/racing.js +0 -99
- package/dist/kit/shared.d.ts +0 -73
- package/dist/kit/shared.d.ts.map +0 -1
- package/dist/kit/shared.js +0 -101
- package/dist/kit/telemetry.d.ts +0 -66
- package/dist/kit/telemetry.d.ts.map +0 -1
- package/dist/kit/telemetry.js +0 -133
- package/dist/kit/territory.d.ts +0 -97
- package/dist/kit/territory.d.ts.map +0 -1
- package/dist/kit/territory.js +0 -114
- package/dist/kit/worldsim.d.ts +0 -263
- package/dist/kit/worldsim.d.ts.map +0 -1
- package/dist/kit/worldsim.js +0 -268
- package/dist/stores/model.d.ts +0 -81
- package/dist/stores/model.d.ts.map +0 -1
- package/dist/stores/model.js +0 -163
package/MIGRATION.md
CHANGED
|
@@ -1,3 +1,125 @@
|
|
|
1
|
+
# CrowdyJS v18 — the legacy engines are gone
|
|
2
|
+
|
|
3
|
+
**Breaking.** The game API deleted its legacy developer-code engines on dev (cks-game-api #417,
|
|
4
|
+
ck-api `v2.27.0`): Studio compute, the game model and its automations, player compute (its
|
|
5
|
+
browser CLIENT modules too) and the player model. `18.0.0` removes their SDK surface. Their
|
|
6
|
+
code moves to ck-exec (`client.exec`): an app's server code as hubs and spokes, a player's grid
|
|
7
|
+
code as mods, and a mod's browser code as its CLIENT half. Nothing is migrated for you; port the
|
|
8
|
+
code, then upgrade.
|
|
9
|
+
|
|
10
|
+
**Which 18.** 18.0.0 was published only on the `dev` channel (`18.0.0-dev.1`). **18.0.1 is the
|
|
11
|
+
first 18.x a client on the production channel will see**, and it carries everything on this page:
|
|
12
|
+
the legacy engines' removal (18.0.0) and the platform-administration removal
|
|
13
|
+
([below](#platform-administration-is-not-in-the-sdk), 18.0.1).
|
|
14
|
+
|
|
15
|
+
**What it needs.** 18.0.0 calls nothing the legacy engines served, so it runs against any API
|
|
16
|
+
with ck-exec CLIENT halves (ck-api `v2.24.0`, as 17.14.0 did). **Crowdy Studio's CLIENT
|
|
17
|
+
projects need ck-api `v2.25.1` or later:** `v2.24.0` and `v2.25.0` refuse to save a
|
|
18
|
+
`crowdy-client-sdk` crate in a Studio project (`CROWDY_STUDIO_MANIFEST_INVALID`, cks-game-api
|
|
19
|
+
#425). The other way round, a 17.x SDK against `v2.27.0` fails every call into a deleted field
|
|
20
|
+
as a GraphQL validation error.
|
|
21
|
+
|
|
22
|
+
| 17.x | 18.0 |
|
|
23
|
+
| --- | --- |
|
|
24
|
+
| `client.gameModel` (containers, properties, functions, `invoke`, sessions, events, timers, automations, `seed`, lint, the player-count feed) | A hub's own state and endpoints: `client.exec.connect(appId, { nodeType, key })`, then `call` / `subscribe`; timers are `ctx.timer_after` / `ctx.timer_every` in the hub; sessions are a keyed hub (the `session` starter) |
|
|
25
|
+
| `gameModel.defineFeature`, `grantTierFeature`, `revokeTierFeature`, `features`, `tierFeatures` | `client.appAccess.defineFeature`, `grantTierFeature`, `revokeTierFeature`, `features(appId)`, `tierFeatures(appId, tierId?)` (same fields; a hub reads them with `players.features`) |
|
|
26
|
+
| `client.compute` (modules, `invoke`, templates, runs, logs) | `client.exec.starters` / `build` / `waitForBuild` / `deploy`, `logs`, `instances`, `versions`, `activateVersion`, `setEnabled`; manual calls through `connectAsDeveloper` |
|
|
27
|
+
| `client.playerModel` (containers, automations) | A mod's own state and timers |
|
|
28
|
+
| `client.playerCompute` SERVER side (`deploy` with `target: SERVER`, `setEnabled`, `setRequires`, `invoke`, `runs`, `logs`) | Mods: `client.exec.modBuild` / `waitForModBuild` / `modDeploy` / `modSetEnabled`, calls through `connect(appId, { nodeType: execModType(name), key: gridId })`, `modLogs` |
|
|
29
|
+
| `client.playerCompute` CLIENT modules (`deploy`, `versions`, `artifact`, `artifactBytes`, `usage`, `myModules`, `delete`, `setSwitch`, `switches`) | A mod's CLIENT half: `client.exec.modClientBuild` (polled with `modBuildStatus` / `waitForModBuild`), `modClientDeploy` / `modClientDelete`, `modClientArtifactBytes`; its kill ladder is the mod's, `modSetSwitch` |
|
|
30
|
+
| `marketplace.gridClientMods`, `consentGridClientMod`, `trustGridAuthor`, `clientArtifact`, `clientArtifactBytes`, and `client.grid(...).compute.clientMods` | `client.exec.gridClientMods`, `consentClientMod`, `trustAuthor`, `modClientArtifactBytes` (which checks the bytes against their digest); `ExecClientHalves` runs a grid's CLIENT halves |
|
|
31
|
+
| `marketplace.listings` / `versions` / `publishListing` / `publishVersion` / `acquire` / `install` / `uninstall` / `myAcquisitions` / `myInstalls` | `client.exec.modPublish` / `modListings` / `modInstall` / `modUnpublish`; a listing carries its mod's CLIENT half |
|
|
32
|
+
| `playerWallet.policies` / `setPolicy` / `deletePolicy` (`playerWasmPolicies`) | Mods run under the platform's mod limits; the kill ladder is `client.exec.modSetSwitch` |
|
|
33
|
+
| `client.operator` (`computePlatformCeilings`, `setComputePlatformCeilings`) | ck-exec code is bounded by its manifest limits within the platform's; there is nothing to call |
|
|
34
|
+
| `client.kit(appId)` blueprints, `kit.deploy`, engines, `kit.inventory` … `kit.minigames`, `kit.features` | Hubs; the starters for NPCs and mobs, sessions and matchmaking. `kit.social` stays; `kit/wire.ts` codecs and `runOptimisticAction` stay |
|
|
35
|
+
| `createWorldSession({ model })` (`ContainerMirror`) | Subscribe to the hub's topic |
|
|
36
|
+
| `client.grid(...).sessions`, `.model`, `.compute` | A mod on the grid (`client.exec.mod*`) |
|
|
37
|
+
| `PlayerCodeBroker` / `startGridMod` without `engine` (a legacy CLIENT module: unmetered, with the whole client catalog), `ALLOWED_HOST_CALLS` | A CLIENT half, the only kind of player module: `artifactHash`, `fuelPerDispatch` and `consentedHostCalls` are required, the allowlist is `EXEC_CLIENT_HOST_CALLS`, and the module must carry the `ck_fuel` meter |
|
|
38
|
+
| `MODEL_LINT_QUERY`, `modelLintDiagnostics`, `CrowdyModelLintLog`, the `'model-lint'` diagnostic source | The Rust compiler's diagnostics from the build |
|
|
39
|
+
|
|
40
|
+
- **The player runtime runs CLIENT halves only.** `PlayerCodeBroker`'s `artifactHash` (the
|
|
41
|
+
served `digest`), `fuelPerDispatch` and `consentedHostCalls` are required, and `engine` is
|
|
42
|
+
`'ck-exec'` or absent; a broker without them, or asked for another engine, does not start.
|
|
43
|
+
The glue offers exactly `EXEC_CLIENT_ABI_IMPORTS` and refuses a module without the `ck_fuel`
|
|
44
|
+
meter; its inert wasi stubs and the `wasi_unstable` alias are gone. `ALLOWED_HOST_CALLS` is
|
|
45
|
+
gone, and `GLUE_HOST_FUNCTIONS` names the CLIENT allowlist. `startGridMod`'s wasm spec needs
|
|
46
|
+
the same three values.
|
|
47
|
+
- **CLIENT host calls the legacy engines answered are refused** by the broker as not allowed:
|
|
48
|
+
the Game Model group (`container_*`, `containers_list`, `property_set`, `edge_*`,
|
|
49
|
+
`model_invoke`), `sessions_list`, and `grid_state_get` / `grid_state_set`. A mod's server
|
|
50
|
+
half, a hub keyed by the grid, holds grid state now. `createGridHostCalls` / `startGridMod`
|
|
51
|
+
lost `allowModelInvoke` and the client's `gameModel`.
|
|
52
|
+
- **What a CLIENT half says and answers, on the page** (new):
|
|
53
|
+
- `onLog`: its `crowdy::log` lines (crowdy-client-sdk levels 0 debug, 1 info, 2 warn,
|
|
54
|
+
3 error), at most `PLAYER_CODE_LOG_LINES_PER_SECOND` (20) a second and
|
|
55
|
+
`PLAYER_CODE_LOG_MAX_CHARS` (1,000) characters each, then a `warn` counting what was
|
|
56
|
+
dropped. On `PlayerCodeBroker`, `ExecClientHalves` (with the mod) and `startGridMod`. The
|
|
57
|
+
text is the mod author's: render it as text. Crowdy Studio shows its preview's lines in
|
|
58
|
+
Logs.
|
|
59
|
+
- `invoke(payload)`: the module's `handle_invoke` export, called by the page:
|
|
60
|
+
`PlayerCodeBroker.invoke`, `ExecClientHalves.invoke(modId, payload)` and
|
|
61
|
+
`RunningGridMod.invoke`, up to `PLAYER_CODE_INVOKE_MAX_BYTES` (256 KiB) each way. The reply
|
|
62
|
+
is the module's: treat it as untrusted input.
|
|
63
|
+
- `createGridHostCalls` answers `avatar_state_get` and `grid_permission_check` as the host
|
|
64
|
+
catalog scopes them: an avatar whose live actor the game places inside the grid
|
|
65
|
+
(`local.avatarChunk`, then the public `avatarAppState`), and the visiting player
|
|
66
|
+
(`userId`) on this grid, from the permission keys the game knows
|
|
67
|
+
(`local.gridPermissionKeys`). Without those they are refused as not offered, as
|
|
68
|
+
`actors_list` is without `local.actorsInChunk`.
|
|
69
|
+
- **Crowdy Studio runs on ck-exec only.** Drop `serverEngine` from the embed, the controller
|
|
70
|
+
and `mountCrowdyStudio`, and `playerCompute` from the embed's services and the controller's
|
|
71
|
+
and `mountCrowdyStudio`'s options (`CrowdyStudioPlayerCompute` is gone); they require
|
|
72
|
+
`mods: client.exec`, and the embed requires `client.exec`. `CrowdyStudioState` loses
|
|
73
|
+
`serverEngine`, `runs` (the Runs panel went) and `usage` (`CrowdyStudioUsageSnapshot`:
|
|
74
|
+
nothing on ck-exec spends player compute quota, and the `'usage'` surface reads the
|
|
75
|
+
wallet); `logs` are `CrowdyStudioLogLine`s (`id`, `source` `'mod' | 'preview'`,
|
|
76
|
+
`moduleName`, `level`, `at`, `text`); `CrowdyStudioInvokeResult` is
|
|
77
|
+
`{ resultJson, durationUs }`. `createCrowdyStudioStarterProject` needs `modStarter` for a
|
|
78
|
+
kind with a SERVER target and has no `engine`: a CLIENT target is a `crowdy-client-sdk`
|
|
79
|
+
CLIENT half. The pairing control went: a mod has no pairing.
|
|
80
|
+
- A CLIENT crate still on `crowdy-compute-sdk` is refused before any build, with what to
|
|
81
|
+
change: `crowdy-client-sdk = "0.1.0"` in `Cargo.toml` and `crowdy_client_sdk` in place of
|
|
82
|
+
`crowdy_compute_sdk` in `src/`. Its host calls are the same less the Game Model, sessions and
|
|
83
|
+
grid state (`grid_state_get` / `grid_state_set`).
|
|
84
|
+
- `ENGINE_SWITCHED_OFF` left `CrowdyFaultCode`: nothing raises it now.
|
|
85
|
+
- The kit's type-98 parser is `parseZoneChangeEvent` beside the other wire parsers.
|
|
86
|
+
|
|
87
|
+
## Platform administration is not in the SDK
|
|
88
|
+
|
|
89
|
+
The SDK is for normal clients and designed for production: it carries what players,
|
|
90
|
+
developers and org-admins call, and nothing only a super-admin or a platform operator can
|
|
91
|
+
call. **18.0.1** removes the wrappers that were left (18.0.0 still had them). The API still has every one of these
|
|
92
|
+
fields; **use the API directly from your own tooling** (a GraphQL request with an operator's or
|
|
93
|
+
super-admin's session). There is no SDK replacement.
|
|
94
|
+
|
|
95
|
+
| Removed | Root field |
|
|
96
|
+
| --- | --- |
|
|
97
|
+
| `client.users.paginated`, `client.users.listConnection` | `usersPaginated`, `usersConnection` |
|
|
98
|
+
| `client.users.setSuperAdmin` | `setSuperAdmin` |
|
|
99
|
+
| `client.users.setOperator` | `setOperator` |
|
|
100
|
+
| `client.users.setEarlyAccessOverride` | `setEarlyAccessOverride` |
|
|
101
|
+
| `client.users.updateType` | `updateUserType` |
|
|
102
|
+
| `client.users.forceLogout` | `forceLogoutUser` |
|
|
103
|
+
| `client.payments.all`, `allConnection` (also `client.admin.payments`) | `checkouts`, `checkoutsConnection` |
|
|
104
|
+
| `client.payments.events`, `eventsConnection` | `paymentEvents`, `paymentEventsConnection` |
|
|
105
|
+
| `client.organizations.setStatus` | `setOrgStatus` |
|
|
106
|
+
| `client.apps.setVisibility` | `setAppVisibility` |
|
|
107
|
+
| `client.hosting.all` | `allHostedGames` |
|
|
108
|
+
| `client.hosting.setListing` | `setHostedGameListing` |
|
|
109
|
+
| `client.hosting.takeDown` | `takeDownHostedGame` |
|
|
110
|
+
|
|
111
|
+
- `client.quotas.set` takes a `ScopedSetQuotaInput`: an `appId` or an `orgId` (and optionally a
|
|
112
|
+
`tierId`) is required, and it refuses a platform-global rule before any request.
|
|
113
|
+
`client.quotas.remove` is unchanged; it removes a rule on an org or app the caller manages.
|
|
114
|
+
- `client.users.get` and `client.users.updateState` stay: any session can call them
|
|
115
|
+
(`updateState` writes only the caller); their docs had said super-admin only.
|
|
116
|
+
- The generated types and documents for those operations are gone from
|
|
117
|
+
`@crowdedkingdoms/crowdyjs/generated` as well.
|
|
118
|
+
|
|
119
|
+
`schema.gql` and the generated types follow the game API: the release carries cks-game-api
|
|
120
|
+
`dev`'s SDL after #417 merged (`npm run schema:sync:paths -- --schema <that schema.gql>`, then
|
|
121
|
+
`npm run codegen`).
|
|
122
|
+
|
|
1
123
|
# 17.14.0 ck-exec CLIENT halves
|
|
2
124
|
|
|
3
125
|
Dev-tier preview (cks-game-api #422, P3 W1). **The release needs a game API that has #422:**
|
|
@@ -65,9 +187,15 @@ trust its author. It replaces the legacy grid-attached client mods, which keep w
|
|
|
65
187
|
Existing CLIENT projects keep their files: a CLIENT crate on `crowdy-compute-sdk` is refused on
|
|
66
188
|
ck-exec before any build, with what to change (the SDK line becomes
|
|
67
189
|
`crowdy-client-sdk = "0.1.0"`, `crowdy_compute_sdk` becomes `crowdy_client_sdk`; the host
|
|
68
|
-
calls are the same less the Game Model and
|
|
190
|
+
calls are the same less the Game Model, sessions and grid state, `grid_state_get` /
|
|
191
|
+
`grid_state_set`, which a mod's server half holds now). `serverEngine: 'player-compute'` keeps
|
|
69
192
|
both targets on legacy player compute until 18.0.
|
|
70
193
|
|
|
194
|
+
**Studio's CLIENT target on ck-exec needs ck-api `v2.25.1` or later.** `v2.24.0` and
|
|
195
|
+
`v2.25.0` refuse to save a `crowdy-client-sdk` crate in a Studio project
|
|
196
|
+
(`CROWDY_STUDIO_MANIFEST_INVALID`, cks-game-api #425), so a CLIENT project cannot start there;
|
|
197
|
+
the SDK calls themselves need only `v2.24.0`.
|
|
198
|
+
|
|
71
199
|
# 17.13.0 ck-exec observability
|
|
72
200
|
|
|
73
201
|
Additive (dev-tier preview; ck-api `v2.22.0`).
|
package/README.md
CHANGED
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
The official browser-first TypeScript SDK for **Crowded Kingdoms**. CrowdyJS
|
|
4
4
|
gives you typed clients for the whole platform: identity and
|
|
5
|
-
studio administration (the Management surface), world data
|
|
6
|
-
|
|
7
|
-
one unified GraphQL API.
|
|
5
|
+
studio administration (the Management surface), world data (the Game surface),
|
|
6
|
+
the UDP proxy realtime stream, and ck-exec, where an app's server code runs —
|
|
7
|
+
all behind one unified GraphQL API.
|
|
8
8
|
|
|
9
9
|
Authentication follows a two-token model: an identity **session token** for
|
|
10
10
|
account and admin operations, and short-lived **app-scoped tokens** for
|
|
@@ -221,27 +221,23 @@ never told about, so a native refresh without it is a re-placement.
|
|
|
221
221
|
| `client.users` | `me`, `updateGamertag`, profile reads. |
|
|
222
222
|
| `client.session` | Token store, `restore()`, `getToken()`, manual `setToken()`. |
|
|
223
223
|
| `client.portal` | App-scoped token minting (`mintAppToken`) and the cross-origin PKCE entry flow (`beginEntry` / `handleAuthorizeRequest` / `completeEntry` / `refresh`). |
|
|
224
|
-
| `client.hosting` | Third-party hosting on Crowdy Games (17.2.0): `claim` a slug for an app, `beginPublish` / `completePublish` / `abandonPublish` a built bundle, `setEnabled`; public `game(slug)` / `listed()
|
|
224
|
+
| `client.hosting` | Third-party hosting on Crowdy Games (17.2.0): `claim` a slug for an app, `beginPublish` / `completePublish` / `abandonPublish` a built bundle, `setEnabled`; public `game(slug)` / `listed()`. Mutations need an identity session with `manage_apps`. `@crowdedkingdoms/crowdyjs/hosting` exports `publishDirectory(client, { dir, slug })`, the Node helper that does the whole publish for a `dist/`. |
|
|
225
225
|
| `client.platform` | Public platform configuration (`config()`). |
|
|
226
226
|
| `client.serverStatus` | `gameClientBootstrap(appId)` — per-app version info, UDP status, spatial limits. |
|
|
227
227
|
| `client.chunks`, `client.voxels`, `client.actors`, `client.avatars`, `client.state` | World data reads + writes: terrain/LODs, voxel edit + history/rollback, durable actors, avatars, per-user app state blobs. |
|
|
228
|
-
| `client.host` | Game-host election (`get`, `amIHost`) + actor liveness `heartbeat`. `amIHost` is UI convenience only —
|
|
228
|
+
| `client.host` | Game-host election (`get`, `amIHost`) + actor liveness `heartbeat`. `amIHost` is UI convenience only — a hub decides host-only actions from its caller. |
|
|
229
229
|
| `client.teleport` | Teleport requests. |
|
|
230
230
|
| `client.channels`, `client.teams` | Messaging channels and app-scoped player teams (membership + roles). |
|
|
231
|
-
| `client.
|
|
232
|
-
| `client.
|
|
233
|
-
| `client.
|
|
234
|
-
| `client.playerCompute` | Player-authored SERVER/CLIENT Rust/WASM bound to player-owned grids: deploy source, activate/deactivate, list modules/versions, delete self-authored modules. |
|
|
235
|
-
| `client.playerModel` | Player-owned flexible model containers and grid-confined automations (`containers`, `createContainer`, `setProperty`, `automations`, `createAutomation`, …). |
|
|
236
|
-
| `client.playerWallet` | Player spend: balance, spend caps, card setup, policy, charges. |
|
|
237
|
-
| `client.marketplace` | Player-code store/install/consent flows plus player-authorized grid claims (`claimGridOwnership`, `claimGridChunk`, `releaseClaimedGrid`) and client-mod artifact fetches. The grid-attached client mods (`gridClientMods`, `consentGridClientMod`, `trustGridAuthor`, `clientArtifact(Bytes)`) are superseded by ck-exec CLIENT halves and go in 18.0. |
|
|
231
|
+
| `client.exec` | **ck-exec (dev-tier preview):** an app's server code as hubs and spokes. `connect(appId, { nodeType, key })` opens a player's connection to an execution host; the `ExecConnection` it returns has `call`, `callRaw`, `subscribe`, `ping`, `onReconnect` and `close`, with MessagePack payloads, and it reconnects and renews subscriptions by itself. `starters` / `build` / `deploy` build and deploy an app (`manage_compute`); `logs`, `instances`, `versions`, `activateVersion` and `setEnabled` operate it; `mod*` are players' mods on grids they own, and `modClient*`, `gridClientMods`, `consentClientMod` and `trustAuthor` their CLIENT halves. See [ck-exec](#ck-exec-dev-tier-preview). |
|
|
232
|
+
| `client.playerWallet` | Player spend: balance, ledger, hourly charges, spend caps, card setup, auto-recharge. A ck-exec mod's compute is billed here, to its owner. |
|
|
233
|
+
| `client.marketplace` | Player-authorized grid claims (`claimGridOwnership`, `claimGridChunk`, `releaseClaimedGrid`, requests and invites) and studio moderation of player code (admission queue, listing administration, claim policy). Mods publish and install through `client.exec`. |
|
|
238
234
|
| `client.crowdyStudio` | Cloud project, personal-library, and common-file APIs for Crowdy Studio: target-scoped files, metadata/module names, optimistic revisions, copy-by-value imports, atomic saves. |
|
|
239
235
|
| `client.crowdyStudioGitHub` | Optional GitHub repository for a Crowdy Studio project: status, `bind` (push the project in, or take the repository), `unbind`, `refresh`, `layout`, `tree`, `getFile`, commit-guarded `putFile` / `deleteFile`. While bound the repository is the working tree and every Studio save commits; the project's `files` are the server's mirror at `github.sha`. Never required. |
|
|
240
236
|
| `client.udp` | UDP proxy subscriptions + spatial mutations (`sendActorUpdate`, `sendVoxelUpdate`, `sendAudioPacket`, `sendVideoPacket` / `sendVideoFrame`, `sendTextPacket`, `sendClientEvent`, `sendSingleActorMessage`, `sendChannelMessage`). |
|
|
241
237
|
| `client.realtime` | Connection status, manual `connect()` / `disconnect()`, `onStatus()` listener. |
|
|
242
238
|
| `client.refreshGameplayToken()` | Safely rotates an active game client's app token (see [Token refresh](#token-refresh-during-gameplay)). |
|
|
243
239
|
| `client.world(appId)` | Higher-level helpers for browser games (`actor.join`, `actor.sendState`, `actor.sendText`, `actor.sendToActor`). |
|
|
244
|
-
| `client.kit(appId)` | Game Kit:
|
|
240
|
+
| `client.kit(appId)` | Game Kit: parties, guilds and chat over teams and channels (`kit.social`) — see [Game Kit](#game-kit). |
|
|
245
241
|
| `createWorldSession(client, appId, config)` | World Stores: opt-in, SDK-managed game state from the `@crowdedkingdoms/crowdyjs/stores` subpath — see [World Stores](#world-stores). |
|
|
246
242
|
|
|
247
243
|
**Studio-admin surface** (privileged; drive with a server-side / studio token,
|
|
@@ -251,7 +247,7 @@ grouped under `client.admin` and mirrored at the top level):
|
|
|
251
247
|
|---|---|
|
|
252
248
|
| `client.organizations` | Orgs, members, RBAC roles, org API tokens. |
|
|
253
249
|
| `client.apps` | App registry, discovery + routing (`create`, `routeFor`, `marketplace`), visibility, and player-code admission mode / allow-list administration. |
|
|
254
|
-
| `client.appAccess` | Access tiers + per-user grants. |
|
|
250
|
+
| `client.appAccess` | Access tiers + per-user grants, and the feature keys a tier grants (`defineFeature`, `grantTierFeature`, `tierFeatures`, …), which a hub checks with the node API's `players.features`. |
|
|
255
251
|
| `client.billing` | Org wallet + per-app spend budgets. |
|
|
256
252
|
| `client.payments` | Payment checkouts (wallet top-ups, plan purchases). |
|
|
257
253
|
| `client.quotas` | Usage quotas at the org/app scope. |
|
|
@@ -259,15 +255,15 @@ grouped under `client.admin` and mirrored at the top level):
|
|
|
259
255
|
| `client.sharedEnvironment` | Publish to shared, runtime gating, spend caps, auto-billing. |
|
|
260
256
|
| `client.gameApps` | App grids (`createGrid` / `deleteGrid`), first-class grid ownership (`ownership` / `assignOwnership` / `transferOwnership`), and grid runtime-permission administration. |
|
|
261
257
|
|
|
262
|
-
**
|
|
258
|
+
**The SDK is for normal clients, and designed for production.** It carries what players,
|
|
259
|
+
developers and org-admins call, and nothing only a super-admin or a platform operator can
|
|
260
|
+
call: those fields are in the API, and platform tooling calls them directly (18.0.1 removed
|
|
261
|
+
the last wrappers; see [MIGRATION.md](MIGRATION.md)). There is no `client.operator`, and
|
|
262
|
+
infrastructure operations live in the separate infra-control-plane service.
|
|
263
263
|
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
Auth, user reads and the studio-admin / operator surfaces use the **identity
|
|
269
|
-
session token**; the world/UDP surfaces require an **app-scoped token** for that
|
|
270
|
-
app. Both go to the same endpoint.
|
|
264
|
+
Auth, user reads and the studio-admin surface use the **identity session token**; the
|
|
265
|
+
world/UDP surfaces require an **app-scoped token** for that app. Both go to the same
|
|
266
|
+
endpoint.
|
|
271
267
|
|
|
272
268
|
CrowdyJS wraps the full public API surface — every
|
|
273
269
|
non-deprecated public root field has a typed method, with Relay `*Connection`
|
|
@@ -485,16 +481,14 @@ pre-bound — convenient for browser games. Advanced callers can always use
|
|
|
485
481
|
|
|
486
482
|
## Grids: player code inside one grid
|
|
487
483
|
|
|
488
|
-
A grid is a box of chunks a player can own.
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
bus, sessions hosted in it, and the player-tier Game Model.
|
|
484
|
+
A grid is a box of chunks a player can own. Code running in a grid is confined
|
|
485
|
+
to it: spatial messages that originate in it, the grid's own channels, and a
|
|
486
|
+
grid event bus. Its server side is a ck-exec mod (`client.exec.mod*`).
|
|
492
487
|
|
|
493
488
|
```ts
|
|
494
489
|
const plot = client.grid(appId, gridId);
|
|
495
490
|
await plot.mintToken(); // learns the box; a grid-scoped token
|
|
496
491
|
await plot.channels.create('plot-chat'); // a grid channel (owner only)
|
|
497
|
-
await plot.sessions.create({ name: 'race' }); // a game within the game
|
|
498
492
|
await plot.send.text({ chunk: { x: 4, y: 0, z: 0 }, uuid, text: 'hi', distance: 2 });
|
|
499
493
|
plot.send.text({ chunk: { x: 9, y: 0, z: 0 }, uuid, text: 'x' }); // throws GridScopeError
|
|
500
494
|
```
|
|
@@ -512,11 +506,17 @@ import { hostGridProgram } from '@crowdedkingdoms/crowdyjs/grid-program';
|
|
|
512
506
|
await hostGridProgram({ port, scope: client.grid(appId, gridId), graphqlUrl, graphqlWsUrl });
|
|
513
507
|
```
|
|
514
508
|
|
|
515
|
-
`startGridMod` runs either a
|
|
516
|
-
behind one interface
|
|
517
|
-
|
|
518
|
-
CLIENT half
|
|
519
|
-
|
|
509
|
+
`startGridMod` runs either a mod's CLIENT half (WASM) or a JS grid program
|
|
510
|
+
behind one interface, and `ExecClientHalves` runs a whole grid's CLIENT halves
|
|
511
|
+
(see [A mod's CLIENT half](#a-mods-client-half)). `createGridHostCalls` answers
|
|
512
|
+
a CLIENT half's host calls through CrowdyJS confined to the grid. The ones only
|
|
513
|
+
the game can answer need its knowledge: `local.actorsInChunk` for
|
|
514
|
+
`actors_list*`, `local.avatarChunk` (where an avatar's live actor is) for
|
|
515
|
+
`avatar_state_get`, `local.gridPermissionKeys` with the visiting player's
|
|
516
|
+
`userId` for `grid_permission_check`, and `local.drainPointerClicks` for
|
|
517
|
+
`pointer_clicks`; without its hook such a call is refused as not offered. The
|
|
518
|
+
Game Model, sessions and grid state calls went with the legacy engines in
|
|
519
|
+
18.0.0: the broker refuses them.
|
|
520
520
|
|
|
521
521
|
## World Stores
|
|
522
522
|
|
|
@@ -573,8 +573,8 @@ The available stores are `self` (your actor + send loop), `actors` (remote
|
|
|
573
573
|
actor registry with lanes/history/staleness), `errors` (attributed send
|
|
574
574
|
errors), `chunks` (chunk/voxel cache with realtime merge + worldgen
|
|
575
575
|
write-back), `channelInbox` / `actorInbox` (message inboxes), `events` (typed
|
|
576
|
-
event router), `host` (host tracking), `save` / `avatar` (typed durable
|
|
577
|
-
state)
|
|
576
|
+
event router), `host` (host tracking), and `save` / `avatar` (typed durable
|
|
577
|
+
state).
|
|
578
578
|
|
|
579
579
|
Every store is **opt-in twice over**: only configured stores are constructed
|
|
580
580
|
(and only they exist on the session's TYPE — `session.host` without
|
|
@@ -588,101 +588,25 @@ keep timer-driven sends at full rate while hidden. See the
|
|
|
588
588
|
|
|
589
589
|
## Game Kit
|
|
590
590
|
|
|
591
|
-
`client.kit(appId)`
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
runtime helpers. Everything composes `client.gameModel` — no new server
|
|
595
|
-
surface.
|
|
596
|
-
|
|
597
|
-
```ts
|
|
598
|
-
// Studio setup (admin context):
|
|
599
|
-
import { inventoryBlueprint, lockBlueprint, npcBlueprint } from '@crowdedkingdoms/crowdyjs';
|
|
600
|
-
|
|
601
|
-
await admin.kit(appId).deploy([
|
|
602
|
-
inventoryBlueprint(),
|
|
603
|
-
lockBlueprint({ objectTypeName: 'Door', authority: { kind: 'key' } }),
|
|
604
|
-
npcBlueprint({
|
|
605
|
-
behaviors: [{
|
|
606
|
-
name: 'npc-wander',
|
|
607
|
-
role: 'wanderer',
|
|
608
|
-
trigger: { intervalMs: 60000 },
|
|
609
|
-
mutations: [
|
|
610
|
-
{ target: 'self', property: 'x', expression: 'self.x + rand_int(-2, 2)' },
|
|
611
|
-
{ target: 'self', property: 'z', expression: 'self.z + rand_int(-2, 2)' },
|
|
612
|
-
],
|
|
613
|
-
}],
|
|
614
|
-
}),
|
|
615
|
-
]);
|
|
616
|
-
|
|
617
|
-
// Game client (player token):
|
|
618
|
-
const kit = game.kit(appId);
|
|
619
|
-
const bag = await kit.inventory.ensure(me.userId);
|
|
620
|
-
const result = await kit.objects.open(doorId, { keyId });
|
|
621
|
-
if (!result.success) console.warn('locked:', result.errorMessage);
|
|
622
|
-
```
|
|
623
|
-
|
|
624
|
-
Land sale closes the permission loop end to end:
|
|
591
|
+
`client.kit(appId).social` gives parties, guilds and chat rooms in familiar
|
|
592
|
+
words over teams (membership and roles) and channels (messaging), with
|
|
593
|
+
realtime delivery on the UDP notification subscription:
|
|
625
594
|
|
|
626
595
|
```ts
|
|
627
|
-
|
|
628
|
-
await
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
authority: { kind: 'chunkPermission', key: 'access', mode: 'smallest' } }),
|
|
632
|
-
]);
|
|
633
|
-
|
|
634
|
-
// Game client: buying spends gold AND grants enforced grid access atomically.
|
|
635
|
-
const buy = await kit.plots.buy(plotId, walletId);
|
|
636
|
-
if (buy.success) await kit.objects.open(doorId); // has_chunk_permission passes now
|
|
596
|
+
const kit = game.kit(appId, { social: { actorUuid: me.uuid } });
|
|
597
|
+
const party = await kit.social.party.create('raid'); // team + paired channel
|
|
598
|
+
const room = await kit.social.chat.room('lobby');
|
|
599
|
+
kit.social.chat.onMessage(room.groupId, (m) => log(m.senderUuid, m.text));
|
|
637
600
|
```
|
|
638
601
|
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
| Layer | Builder → helper | Highlights |
|
|
648
|
-
| --- | --- | --- |
|
|
649
|
-
| Inventory | `inventoryBlueprint` → `kit.inventory` | bags/stacks, grant/consume/transfer, craft, barter |
|
|
650
|
-
| Objects | `lockBlueprint` → `kit.objects` | lockable doors/chests with key or permission authority |
|
|
651
|
-
| NPCs | `npcBlueprint` → `kit.npcs` | automation-driven NPC instances (spawn, runNow, enable) |
|
|
652
|
-
| Plots | `plotBlueprint` → `kit.plots` | buy/rent land with transactional, replication-enforced grid grants |
|
|
653
|
-
| Economy | `economyBlueprint` → `kit.economy` | multi-currency wallets, atomic shop buys, escrow trades, player market, escrowed order book (`kit.economy.orderBook`) |
|
|
654
|
-
| Progression | `progressionBlueprint` → `kit.progression` | xp/levels via the `fn:` curve helper, skill prerequisite chains, achievements, host-gated rating |
|
|
655
|
-
| Loot | `lootBlueprint` → `kit.loot` | weighted tables unrolled into seed-driven expressions, atomic single-claim, event-triggered drops |
|
|
656
|
-
| Quests | `questsBlueprint` → `kit.quests` | event-automation progress, atomic claim into stack+wallet, cron daily resets, tutorial sequencing |
|
|
657
|
-
| Combat | `combatBlueprint` → `kit.combat` | server-side damage/death, status-effect tick automation, `turnBased`/`hostSynced`, routed attacks |
|
|
658
|
-
| Matches | `matchesBlueprint` → `kit.matches` | session lobbies/rounds/turns/scores, per-match channel + `onMatchChanged` (notify-to-pull) |
|
|
659
|
-
| Decks | `decksBlueprint` → `kit.decks` | hidden hands via owner-visibility `card_id`, shuffle-by-position automation |
|
|
660
|
-
| World sim | `worldsimBlueprint` → `kit.worldsim` | day/night clock with spatial notify, node regen + atomic gather, crops, wave counters, forecasts |
|
|
661
|
-
| Social | `guildBlueprint` → `kit.social` | parties/guilds/chat over teams+channels, grid territory grants, guild hall + bank composite |
|
|
662
|
-
| Leaderboards | `leaderboardsBlueprint` → `kit.leaderboards` | trusted keep-best submits, client-side ranking, cron seasons |
|
|
663
|
-
| Live ops | `liveopsBlueprint` → `kit.liveops` | timed event windows and seasons |
|
|
664
|
-
| Moderation | `moderationBlueprint` → `kit.moderation` | reports, queues, mutes |
|
|
665
|
-
| Telemetry | `telemetryBlueprint` → `kit.telemetry` | counters and lightweight event tracking |
|
|
666
|
-
| Monetization | `featureGate` → `kit.features` | feature keys, tier grants, `*policyExtra` gating on builders |
|
|
667
|
-
| Abilities | — → `kit.abilities` | ability definitions, casts, loadouts |
|
|
668
|
-
| Movement | — → `kit.movement` | movement warden configs + violation parsing |
|
|
669
|
-
| Territory | — → `kit.territory` | control points, factions, enrollment |
|
|
670
|
-
| Racing | — → `kit.racing` | courses, entries, possession (claim/pass/shoot) |
|
|
671
|
-
|
|
672
|
-
Engine-aware layers talk to compute-module game engines when they are
|
|
673
|
-
deployed, and degrade gracefully on model-only apps via capability detection
|
|
674
|
-
(`kit.engines`): `kit.mobs` (refereed attacks, defs/slots, contact-damage
|
|
675
|
-
parsing), `kit.pets` (adopt/summon/dismiss/rename), `kit.instances` (private
|
|
676
|
-
world slices, seeded runs), `kit.director` (encounter runs),
|
|
677
|
-
`kit.matchmaking` (queues/proposals/rating), `kit.minigames` (invoke-loop
|
|
678
|
-
wrapper), plus engine paths on `kit.matches` / `kit.decks` /
|
|
679
|
-
`kit.leaderboards` and the `kit/wire` pose codec + event parsers. Deploy
|
|
680
|
-
engines alongside blueprints with `kit.deploy(blueprints, { engines })`.
|
|
681
|
-
|
|
682
|
-
See the docs guides [Modeling game concepts](https://docs.crowdedkingdoms.com/game-api/modeling-game-concepts)
|
|
683
|
-
(the underlying model + genre map) and [Game Kit](https://docs.crowdedkingdoms.com/crowdyjs/game-kit)
|
|
684
|
-
(the SDK surface + the simulation-tier / notify-to-pull / timer / hidden-info
|
|
685
|
-
/ anti-cheat patterns).
|
|
602
|
+
Game rules and state are ck-exec hubs (`client.exec`, below). Two kit pieces
|
|
603
|
+
stand alone: the wire codecs (`encodeEnginePose` / `decodeEnginePose`, the
|
|
604
|
+
48-byte engine pose, `engineLanes`, and `parseEngineEvent` with the typed
|
|
605
|
+
parsers for server events 77 and 90-98) for games whose hubs keep that wire,
|
|
606
|
+
and `runOptimisticAction`, which applies an action locally, asks a referee
|
|
607
|
+
(a hub endpoint, say) and rolls back on a denial. The blueprints,
|
|
608
|
+
`kit.deploy`, the engines and the model-backed helpers went with the game
|
|
609
|
+
model in 18.0.0; see [MIGRATION.md](MIGRATION.md).
|
|
686
610
|
|
|
687
611
|
## ck-exec (dev-tier preview)
|
|
688
612
|
|
|
@@ -742,7 +666,8 @@ Integers above 2^53 decode as `number` and lose precision unless you pass
|
|
|
742
666
|
A mod (a player's code on a grid they own: `modBuild`, `modDeploy`) can carry a **CLIENT
|
|
743
667
|
half** (17.14.0): browser WASM from one `crowdy-client-sdk` crate, which the mod's grid serves
|
|
744
668
|
to visitors who consent to it or trust its author. It runs in the visitor's
|
|
745
|
-
`PlayerCodeBroker`,
|
|
669
|
+
`PlayerCodeBroker`, in a worker with no DOM, token or network, and it is the only kind of
|
|
670
|
+
player module the broker runs since 18.0.0.
|
|
746
671
|
|
|
747
672
|
```ts
|
|
748
673
|
// The mod's owner builds one crowdy-client-sdk crate and attaches it to the mod.
|
|
@@ -770,24 +695,30 @@ const halves = new ExecClientHalves({
|
|
|
770
695
|
workerUrl, // the platform glue worker, same origin
|
|
771
696
|
onHostCall: (call) => hostCalls(call), // e.g. createGridHostCalls({ scope, client })
|
|
772
697
|
onPresentation: (p, mod) => hud.set({ source: mod.modId, label: mod.name, payload: p.payload }),
|
|
698
|
+
onLog: (line, mod) => devConsole.append(mod.name, line.level, line.message), // text, never HTML
|
|
773
699
|
confirm: (prompt) => window.confirm(describe(prompt)), // once per author; ask: 'mod' for each
|
|
774
700
|
onStopped: (mod) => hud.remove(mod.modId),
|
|
775
701
|
});
|
|
776
702
|
halves.enterGrid({ gridId, low, high }); // the grid the player stands in; null to leave
|
|
777
703
|
setInterval(() => void halves.refresh().catch(console.warn), 10_000);
|
|
704
|
+
|
|
705
|
+
// The page calls a running CLIENT half's handle_invoke; the reply is the module's bytes.
|
|
706
|
+
const reply = await halves.invoke(modId, new TextEncoder().encode('{"ask":"score"}'));
|
|
778
707
|
```
|
|
779
708
|
|
|
780
709
|
Each refresh stops the CLIENT halves whose mod is gone or whose digest, capability hash or
|
|
781
|
-
tick interval changed, asks about the rest, and starts the consented ones in a broker
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
`
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
710
|
+
tick interval changed, asks about the rest, and starts the consented ones in a broker. The
|
|
711
|
+
broker allows at most the host calls crowdy-client-sdk makes (`EXEC_CLIENT_HOST_CALLS`: no Game
|
|
712
|
+
Model, sessions or `grid_state_*`), offers exactly the CLIENT ABI imports
|
|
713
|
+
(`EXEC_CLIENT_ABI_IMPORTS`) and runs a module only with its digest, its fuel budget and
|
|
714
|
+
`consentedHostCalls`, the host calls of the summary the player consented to: a call outside them
|
|
715
|
+
is refused, even one whose name the module assembled at run time. A CLIENT half's
|
|
716
|
+
`crowdy::log` lines reach `onLog` at most 20 a second and 1,000 characters each (then a `warn`
|
|
717
|
+
counts what was dropped); `invoke` sends at most 256 KiB each way and is refused while the
|
|
718
|
+
module is not running. `NOT_FOUND` holds a CLIENT half back 15 s and `RATE_LIMITED` 60 s. The
|
|
719
|
+
grid's owner is asked about their own CLIENT halves like anyone; answer yes in `confirm` when
|
|
720
|
+
`prompt.authorId` is the player. See
|
|
721
|
+
[CLIENT halves](https://docs.dev.crowdedkingdoms.com/exec/client-halves).
|
|
791
722
|
|
|
792
723
|
## Hosting a game on Crowdy Games
|
|
793
724
|
|
|
@@ -818,7 +749,7 @@ uploads with the exact signed headers, and `completeGamePublish` verifies every
|
|
|
818
749
|
object, promotes it and invalidates the CDN. The slug is a DNS label, global on the
|
|
819
750
|
tier, and first-party names are reserved (`HOSTED_SLUG_UNAVAILABLE`); a tier without
|
|
820
751
|
a content CDN answers `CONTENT_HOSTING_DISABLED`. Being *listed* in the lobby is an
|
|
821
|
-
operator decision
|
|
752
|
+
operator decision, made outside the SDK; publishing is self-serve. `the-construct`'s
|
|
822
753
|
`npm run publish` is this section as a command.
|
|
823
754
|
|
|
824
755
|
## Crowdy Studio
|
|
@@ -827,28 +758,32 @@ Crowdy Studio is the in-game SERVER/CLIENT Rust authoring surface for player
|
|
|
827
758
|
code: cloud projects with target-scoped files, optimistic-concurrency
|
|
828
759
|
autosave, draft/live/stop orchestration, and a Monaco editor backed by a local
|
|
829
760
|
Rust language worker. The worker receives source files and the embedded
|
|
830
|
-
platform index
|
|
831
|
-
|
|
832
|
-
on the page, allow-lists host calls
|
|
833
|
-
to the
|
|
834
|
-
|
|
835
|
-
|
|
761
|
+
platform index (the `ckx-sdk` and `crowdy-client-sdk` symbols) only — never a
|
|
762
|
+
credential and never a server connection. A CLIENT half runs through
|
|
763
|
+
`PlayerCodeBroker`, which keeps tokens on the page, allow-lists host calls
|
|
764
|
+
(narrowed to what the player consented to), and locally clamps chunk-targeted
|
|
765
|
+
effects to the owned grid before the normal SDK path reaches server
|
|
766
|
+
authorization. It takes what the platform served with the module, and ticks it
|
|
767
|
+
only when `tickIntervalMs` is set (omit or `0` is invoke-only):
|
|
836
768
|
|
|
837
769
|
```ts
|
|
838
770
|
import { PlayerCodeBroker } from '@crowdedkingdoms/crowdyjs';
|
|
839
771
|
|
|
772
|
+
const half = await client.exec.modClientArtifactBytes(appId, modId);
|
|
840
773
|
const broker = new PlayerCodeBroker({
|
|
841
774
|
workerUrl,
|
|
842
775
|
grid,
|
|
843
776
|
onHostCall,
|
|
844
|
-
|
|
777
|
+
moduleName: half.name,
|
|
778
|
+
artifactHash: half.digest,
|
|
779
|
+
fuelPerDispatch: half.fuelPerDispatch,
|
|
780
|
+
consentedHostCalls: half.capabilitySummary.hostFunctions,
|
|
781
|
+
tickIntervalMs: half.tickIntervalMs, // omit for invoke-only
|
|
782
|
+
onLog: (line) => console.log(`[${line.moduleName}] ${line.level}: ${line.message}`),
|
|
845
783
|
});
|
|
846
|
-
await broker.start(
|
|
784
|
+
await broker.start(half.bytes);
|
|
847
785
|
```
|
|
848
786
|
|
|
849
|
-
The Studio embed defaults `clientTickIntervalMs` to `1000` when you do not
|
|
850
|
-
pass one; a raw `PlayerCodeBroker` does not.
|
|
851
|
-
|
|
852
787
|
Most games embed the ready-made shell rather than hand-rolling window chrome
|
|
853
788
|
around `mountCrowdyStudio`:
|
|
854
789
|
|
|
@@ -859,7 +794,7 @@ import { createCrowdyStudioEmbed } from '@crowdedkingdoms/crowdyjs/crowdy-studio
|
|
|
859
794
|
import workerUrl from '@crowdedkingdoms/crowdyjs/player-glue-worker?worker&url';
|
|
860
795
|
|
|
861
796
|
const studio = createCrowdyStudioEmbed({
|
|
862
|
-
client: game, // CrowdyClient: crowdyStudio, exec,
|
|
797
|
+
client: game, // CrowdyClient: crowdyStudio, exec, playerWallet, crowdyStudioGitHub
|
|
863
798
|
appId,
|
|
864
799
|
gameName: 'My Game',
|
|
865
800
|
suppressGameplayInput: () => pauseInput(),
|
|
@@ -882,29 +817,27 @@ fullscreen modal on narrow screens. For custom chrome, call
|
|
|
882
817
|
`new CrowdyStudioController(options)`. New games should start SERVER-only.
|
|
883
818
|
Untrusted HUD payloads always render as text, never HTML.
|
|
884
819
|
|
|
885
|
-
**The SERVER target runs as a ck-exec mod.**
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
`
|
|
889
|
-
|
|
890
|
-
default) over an exec connection, and Logs shows its `ctx.log` lines.
|
|
820
|
+
**The SERVER target runs as a ck-exec mod.** A new project's SERVER target starts from
|
|
821
|
+
the platform's mod starter (`client.exec.modStarter(appId)`, a `ckx-sdk` crate), Test draft
|
|
822
|
+
and Deploy live build it with `modBuild` and deploy it to the grid as the mod
|
|
823
|
+
`mod:<server module name>`, Invoke calls one of its endpoints (`state` by default) over an
|
|
824
|
+
exec connection, and Logs shows its `ctx.log` lines.
|
|
891
825
|
|
|
892
826
|
**The CLIENT target is that mod's CLIENT half** (17.14.0). A new CLIENT target starts from a
|
|
893
827
|
`crowdy-client-sdk` crate; Test draft and Deploy live build it with `modClientBuild`, attach
|
|
894
828
|
it to the project's mod with `modClientDeploy`, consent to it as its author (the API serves a
|
|
895
829
|
CLIENT half only to players who consented, its author too) and preview the served module in
|
|
896
|
-
the HUD layer
|
|
830
|
+
the HUD layer; the preview's `crowdy::log` lines show in Logs beside the mod's own. A
|
|
831
|
+
CLIENT-only project's CLIENT half rides the mod named for its CLIENT module:
|
|
897
832
|
when the player has no mod of that name on the grid, Studio deploys the mod starter's server
|
|
898
833
|
half under it first and says so in the build log, and Stop switches that mod off. The
|
|
899
|
-
preview loads only while the player stands in the grid with `run_client_code
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
`mountCrowdyStudio` and the controller take
|
|
903
|
-
|
|
904
|
-
`serverEngine: 'player-compute'` keeps it explicitly for both targets. The platform is
|
|
905
|
-
switching legacy player compute off, so that option lasts only until 18.0 removes it.
|
|
834
|
+
preview loads only while the player stands in the grid with `run_client_code`, and saving a
|
|
835
|
+
CLIENT project needs ck-api `v2.25.1` or later. A CLIENT crate still on the legacy
|
|
836
|
+
`crowdy-compute-sdk` is refused with what to change. The embed takes `exec` from the client;
|
|
837
|
+
`mountCrowdyStudio` and the controller take `mods: client.exec`. Crowdy Studio runs nothing
|
|
838
|
+
on legacy player compute since 18.0.0.
|
|
906
839
|
|
|
907
|
-
See [
|
|
840
|
+
See [CLIENT halves](https://docs.dev.crowdedkingdoms.com/exec/client-halves), [mods](https://docs.dev.crowdedkingdoms.com/exec/mods)
|
|
908
841
|
and [Embed Crowdy Studio in your game](https://docs.crowdedkingdoms.com/crowdyjs/crowdy-studio-embed).
|
|
909
842
|
|
|
910
843
|
### The Studio agent (DeepSeek Harness in the browser)
|