@voltro/plugin-rooms 0.0.0-stage → 0.88.0

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 (495) hide show
  1. package/CHANGELOG.md +24492 -0
  2. package/LICENSE +61 -0
  3. package/README.md +9204 -2
  4. package/SECURITY.md +56 -0
  5. package/THIRD-PARTY-NOTICES.md +12496 -0
  6. package/dist/actor.js +1473 -0
  7. package/dist/apiBinding.js +677 -0
  8. package/dist/apiRegistryBinding.js +398 -0
  9. package/dist/apiReservations.js +432 -0
  10. package/dist/baselines.js +72 -0
  11. package/dist/bots.d.ts +1485 -0
  12. package/dist/bots.js +562 -0
  13. package/dist/catalog.js +79 -0
  14. package/dist/checkpointJson.js +23 -0
  15. package/dist/checkpointStore.js +385 -0
  16. package/dist/client.js +55 -0
  17. package/dist/clockSync.js +50 -0
  18. package/dist/collision.js +155 -0
  19. package/dist/commandDelivery.js +100 -0
  20. package/dist/commandRecord.js +10 -0
  21. package/dist/commandWithdrawal.js +182 -0
  22. package/dist/connection.js +496 -0
  23. package/dist/controlCarrier.js +374 -0
  24. package/dist/controlRegistry.js +78 -0
  25. package/dist/controlTarget.js +44 -0
  26. package/dist/controlTransport.js +573 -0
  27. package/dist/developmentBinding.js +112 -0
  28. package/dist/directory.js +322 -0
  29. package/dist/directoryProjection.js +116 -0
  30. package/dist/errors.d.ts +125 -0
  31. package/dist/errors.js +52 -0
  32. package/dist/fixed.d.ts +284 -0
  33. package/dist/fixed.js +10 -0
  34. package/dist/fixed32.js +133 -0
  35. package/dist/fixedCollision.js +59 -0
  36. package/dist/fixedCollision32.js +108 -0
  37. package/dist/fixedMath.js +55 -0
  38. package/dist/fixedRaw.js +10 -0
  39. package/dist/fixedSlabs.js +33 -0
  40. package/dist/fixedTrig.js +47 -0
  41. package/dist/fixedTrig32.js +37 -0
  42. package/dist/fixedVectors.js +112 -0
  43. package/dist/fixedVectors32.js +94 -0
  44. package/dist/fixedWide.js +49 -0
  45. package/dist/fixedWords.js +45 -0
  46. package/dist/gateway.js +56 -0
  47. package/dist/geometry-retention-app/rooms.geometryJournalRetention.workflow.server.tsx +4 -0
  48. package/dist/geometry-retention-app/rooms.geometryJournalRetention.workflow.tsx +14 -0
  49. package/dist/geometry-worker/worker.d.mts +2 -0
  50. package/dist/geometry-worker/worker.mjs +50 -0
  51. package/dist/geometry.d.ts +2249 -0
  52. package/dist/geometry.js +40 -0
  53. package/dist/geometryActivation.js +81 -0
  54. package/dist/geometryActorInventory.js +107 -0
  55. package/dist/geometryAdminClient.js +86 -0
  56. package/dist/geometryAdminData.js +31 -0
  57. package/dist/geometryAdminFixtures.js +49 -0
  58. package/dist/geometryAdminPorts.js +4 -0
  59. package/dist/geometryAdminRpc.js +57 -0
  60. package/dist/geometryAdminRpcRoutes.js +48 -0
  61. package/dist/geometryAdminSchemas.js +38 -0
  62. package/dist/geometryAdministration.js +189 -0
  63. package/dist/geometryAdministrationPorts.js +4 -0
  64. package/dist/geometryApiBinding.js +164 -0
  65. package/dist/geometryAppStorage.js +57 -0
  66. package/dist/geometryArtifacts.js +197 -0
  67. package/dist/geometryAssetBundle.js +116 -0
  68. package/dist/geometryAssetClient.js +24 -0
  69. package/dist/geometryAssetData.js +105 -0
  70. package/dist/geometryAssetHttp.js +122 -0
  71. package/dist/geometryAssetPorts.js +4 -0
  72. package/dist/geometryAssetRpc.js +29 -0
  73. package/dist/geometryAssetRpcRoutes.js +39 -0
  74. package/dist/geometryAssetStorageGrant.js +102 -0
  75. package/dist/geometryBoxOverlap.js +109 -0
  76. package/dist/geometryCatalogueDigest.js +110 -0
  77. package/dist/geometryCellCoverage.js +84 -0
  78. package/dist/geometryCellLoader.js +27 -0
  79. package/dist/geometryChannel.js +133 -0
  80. package/dist/geometryChunkHttp.js +53 -0
  81. package/dist/geometryChunkLeases.js +21 -0
  82. package/dist/geometryClient.d.ts +1429 -0
  83. package/dist/geometryClient.js +148 -0
  84. package/dist/geometryClientChunks.js +329 -0
  85. package/dist/geometryClientDelta.js +24 -0
  86. package/dist/geometryClientHttp.js +36 -0
  87. package/dist/geometryClientInterest.js +108 -0
  88. package/dist/geometryClientStatic.js +33 -0
  89. package/dist/geometryCms.d.ts +763 -0
  90. package/dist/geometryCms.js +216 -0
  91. package/dist/geometryCommitCoordinator.js +240 -0
  92. package/dist/geometryCompactionFixture.js +83 -0
  93. package/dist/geometryCompactionStrategies.js +37 -0
  94. package/dist/geometryConnectionClient.js +22 -0
  95. package/dist/geometryDerivationFixtures.js +140 -0
  96. package/dist/geometryDerivationStrategies.js +26 -0
  97. package/dist/geometryDigest.js +12 -0
  98. package/dist/geometryEditChannel.js +69 -0
  99. package/dist/geometryEditIngress.js +262 -0
  100. package/dist/geometryEdits.js +365 -0
  101. package/dist/geometryEnvelope.js +40 -0
  102. package/dist/geometryGridRaycast.js +91 -0
  103. package/dist/geometryGridSweep.js +91 -0
  104. package/dist/geometryHeightfield.js +165 -0
  105. package/dist/geometryHeightfieldRaycast.js +73 -0
  106. package/dist/geometryHeightfieldSweep.js +84 -0
  107. package/dist/geometryHeightfieldVolume.js +44 -0
  108. package/dist/geometryHost.js +321 -0
  109. package/dist/geometryHostDirectory.js +206 -0
  110. package/dist/geometryHostMutations.js +136 -0
  111. package/dist/geometryHostStreams.js +123 -0
  112. package/dist/geometryHttpBody.js +75 -0
  113. package/dist/geometryHttpRoutes.js +111 -0
  114. package/dist/geometryImportGltf.js +299 -0
  115. package/dist/geometryImportLdtk.js +53 -0
  116. package/dist/geometryImportPng.js +143 -0
  117. package/dist/geometryImportPublication.js +66 -0
  118. package/dist/geometryImportTiled.js +38 -0
  119. package/dist/geometryImportTiles.js +135 -0
  120. package/dist/geometryImportVox.js +129 -0
  121. package/dist/geometryImportedSource.js +100 -0
  122. package/dist/geometryInspectEndpoint.js +247 -0
  123. package/dist/geometryInspection.js +91 -0
  124. package/dist/geometryInstall.js +120 -0
  125. package/dist/geometryJournalArchiveData.js +20 -0
  126. package/dist/geometryJournalArchiveIndex.js +329 -0
  127. package/dist/geometryJournalArchiveTable.js +20 -0
  128. package/dist/geometryJournalCompaction.js +99 -0
  129. package/dist/geometryJournalPatch.js +46 -0
  130. package/dist/geometryJournalRetention.js +111 -0
  131. package/dist/geometryJournalRetentionSchemas.js +35 -0
  132. package/dist/geometryJournalRetentionSweep.js +111 -0
  133. package/dist/geometryJournalRetentionWorkflow.js +27 -0
  134. package/dist/geometryJournalRetentionWorkflowData.js +30 -0
  135. package/dist/geometryJournalStorage.js +147 -0
  136. package/dist/geometryLoader.js +117 -0
  137. package/dist/geometryManifest.js +112 -0
  138. package/dist/geometryManifestChannel.js +92 -0
  139. package/dist/geometryManifestClient.js +121 -0
  140. package/dist/geometryManifestData.js +48 -0
  141. package/dist/geometryManifestPorts.js +4 -0
  142. package/dist/geometryManifestPublication.js +108 -0
  143. package/dist/geometryManifestSource.js +67 -0
  144. package/dist/geometryMigrationJournal.js +13 -0
  145. package/dist/geometryMigrationStrategies.js +6 -0
  146. package/dist/geometryMigrations.js +322 -0
  147. package/dist/geometryNativeMetadata.js +51 -0
  148. package/dist/geometryPatch.js +169 -0
  149. package/dist/geometryPersistence.js +448 -0
  150. package/dist/geometryPersistenceCapture.js +68 -0
  151. package/dist/geometryPersistenceData.js +139 -0
  152. package/dist/geometryPersistencePorts.js +4 -0
  153. package/dist/geometryPlayerAdmission.js +33 -0
  154. package/dist/geometryPlayerEditOwner.js +264 -0
  155. package/dist/geometryPlayerEdits.js +48 -0
  156. package/dist/geometryPrepared.js +187 -0
  157. package/dist/geometryPrivacyFence.js +23 -0
  158. package/dist/geometryProceduralPublication.js +90 -0
  159. package/dist/geometryProceduralWorker.js +163 -0
  160. package/dist/geometryPublication.js +109 -0
  161. package/dist/geometryRayAlgebra.js +115 -0
  162. package/dist/geometryReadClient.js +156 -0
  163. package/dist/geometryReadPorts.js +4 -0
  164. package/dist/geometryReadRpc.js +26 -0
  165. package/dist/geometryReadRpcRoutes.js +46 -0
  166. package/dist/geometryReliablePublication.js +81 -0
  167. package/dist/geometryReloadPorts.js +45 -0
  168. package/dist/geometryReloadSource.js +277 -0
  169. package/dist/geometryRenderCache.js +164 -0
  170. package/dist/geometryRenderLod.js +101 -0
  171. package/dist/geometryRollback.js +124 -0
  172. package/dist/geometryRollbackCoordinator.js +202 -0
  173. package/dist/geometryRollbackPorts.js +45 -0
  174. package/dist/geometryRollbackSource.js +208 -0
  175. package/dist/geometryRollbackStore.js +197 -0
  176. package/dist/geometrySchemas.js +26 -0
  177. package/dist/geometryServer.d.ts +2766 -0
  178. package/dist/geometryServer.js +62 -0
  179. package/dist/geometryShapeRaycast.js +110 -0
  180. package/dist/geometryShapeSegments.js +33 -0
  181. package/dist/geometryShapes.js +222 -0
  182. package/dist/geometrySnapshot.js +75 -0
  183. package/dist/geometrySnapshotChannel.js +159 -0
  184. package/dist/geometrySnapshotClient.js +158 -0
  185. package/dist/geometrySnapshotPreparation.js +75 -0
  186. package/dist/geometrySnapshotServer.js +190 -0
  187. package/dist/geometrySqlOwner.js +20 -0
  188. package/dist/geometryStorage.js +126 -0
  189. package/dist/geometryStorageGrant.js +68 -0
  190. package/dist/geometryStorageIdentity.js +8 -0
  191. package/dist/geometryTileArtifact.js +9 -0
  192. package/dist/geometryTileCodec.js +193 -0
  193. package/dist/geometryTileCollision.js +95 -0
  194. package/dist/geometryTileNavigation.js +127 -0
  195. package/dist/geometryTileView.js +34 -0
  196. package/dist/geometryVersionActivation.js +113 -0
  197. package/dist/geometryVersionClient.js +237 -0
  198. package/dist/geometryVersionCompare.js +39 -0
  199. package/dist/geometryVersionMigration.js +105 -0
  200. package/dist/geometryVoxel.js +252 -0
  201. package/dist/geometryWorldEntitySubject.js +31 -0
  202. package/dist/geometryWorldExtent.js +11 -0
  203. package/dist/geometryWorldMetadata.js +37 -0
  204. package/dist/geometryWorldStrategyFixtures.js +126 -0
  205. package/dist/geometryWorldView.js +306 -0
  206. package/dist/host.js +127 -0
  207. package/dist/hostBinding.js +276 -0
  208. package/dist/hostCellObservation.js +113 -0
  209. package/dist/hostClientCapacity.js +89 -0
  210. package/dist/hostCommandScope.js +63 -0
  211. package/dist/hostController.js +3093 -0
  212. package/dist/hostDeployment.js +64 -0
  213. package/dist/hostDrain.js +151 -0
  214. package/dist/hostDrainPorts.js +4 -0
  215. package/dist/hostDriver.js +178 -0
  216. package/dist/hostLane.js +287 -0
  217. package/dist/hostListener.js +78 -0
  218. package/dist/hostListenerBinding.js +18 -0
  219. package/dist/hostLoopObservation.js +89 -0
  220. package/dist/hostMetrics.js +55 -0
  221. package/dist/hostRegistryBinding.js +417 -0
  222. package/dist/hostSelection.js +15 -0
  223. package/dist/hostShutdown.js +46 -0
  224. package/dist/hostTurnObservation.js +52 -0
  225. package/dist/identities.js +3 -0
  226. package/dist/index.d.ts +8632 -0
  227. package/dist/index.js +231 -0
  228. package/dist/inputReceipts.js +62 -0
  229. package/dist/inputRedundancy.js +54 -0
  230. package/dist/inspect.js +237 -0
  231. package/dist/lockstep.d.ts +436 -0
  232. package/dist/lockstep.js +381 -0
  233. package/dist/lockstepAdmission.js +261 -0
  234. package/dist/lockstepAdmissionCodec.js +93 -0
  235. package/dist/lockstepAdmissionPorts.js +4 -0
  236. package/dist/lockstepClientSession.js +577 -0
  237. package/dist/lockstepDefinition.js +147 -0
  238. package/dist/lockstepHostLoop.js +242 -0
  239. package/dist/lockstepInitialAdmission.js +66 -0
  240. package/dist/lockstepInitialStrategyFixtures.js +44 -0
  241. package/dist/lockstepJournal.js +394 -0
  242. package/dist/lockstepJournalCodec.js +253 -0
  243. package/dist/lockstepJournalPorts.js +4 -0
  244. package/dist/lockstepJournalRebuild.js +207 -0
  245. package/dist/lockstepJournalRows.js +56 -0
  246. package/dist/lockstepMembers.js +130 -0
  247. package/dist/lockstepMessages.js +46 -0
  248. package/dist/lockstepOwnedRoom.js +763 -0
  249. package/dist/lockstepPolicies.js +83 -0
  250. package/dist/lockstepReact.js +46 -0
  251. package/dist/lockstepRecoveryTruth.js +120 -0
  252. package/dist/lockstepRosterConfig.js +31 -0
  253. package/dist/lockstepSeed.js +11 -0
  254. package/dist/lockstepSeedFixture.js +19 -0
  255. package/dist/lockstepServer.d.ts +3897 -0
  256. package/dist/lockstepServer.js +324 -0
  257. package/dist/lockstepServerConfig.js +100 -0
  258. package/dist/lockstepServerRoles.js +402 -0
  259. package/dist/lockstepServerStrategyFixtures.js +32 -0
  260. package/dist/lockstepStrategies.js +5 -0
  261. package/dist/lockstepStrategyFixtures.js +136 -0
  262. package/dist/lockstepTerminal.js +89 -0
  263. package/dist/lockstepTerminalPorts.js +4 -0
  264. package/dist/lockstepTransport.js +772 -0
  265. package/dist/lockstepTransportConfig.js +31 -0
  266. package/dist/lockstepWireRoster.js +33 -0
  267. package/dist/matchRoomProvider.js +31 -0
  268. package/dist/matchRooms.js +18 -0
  269. package/dist/membershipObserver.js +46 -0
  270. package/dist/moderation.js +97 -0
  271. package/dist/movementSpecials.js +103 -0
  272. package/dist/ownership.js +16 -0
  273. package/dist/ownershipWithdrawal.js +17 -0
  274. package/dist/pcg32.js +95 -0
  275. package/dist/ports.d.ts +1241 -0
  276. package/dist/ports.js +10 -0
  277. package/dist/quaternion.js +69 -0
  278. package/dist/react.d.ts +406 -0
  279. package/dist/react.js +108 -0
  280. package/dist/reaper-app/rooms.reaper.workflow.server.tsx +5 -0
  281. package/dist/reaper-app/rooms.reaper.workflow.tsx +13 -0
  282. package/dist/reaper.js +242 -0
  283. package/dist/reaperSchemas.js +41 -0
  284. package/dist/reaperWorkflow.js +69 -0
  285. package/dist/recovery.js +188 -0
  286. package/dist/recoverySeats.js +25 -0
  287. package/dist/replay.d.ts +273 -0
  288. package/dist/replay.js +484 -0
  289. package/dist/replayPorts.js +4 -0
  290. package/dist/replayRecording.js +66 -0
  291. package/dist/replaySchema.js +156 -0
  292. package/dist/replayStorage.d.ts +149 -0
  293. package/dist/replayStorage.js +484 -0
  294. package/dist/reservationBatch.js +421 -0
  295. package/dist/reservationSchemas.js +16 -0
  296. package/dist/reservations.js +258 -0
  297. package/dist/reservePort.js +68 -0
  298. package/dist/resolvedOptions.js +3 -0
  299. package/dist/room.d.ts +1006 -0
  300. package/dist/room.js +283 -0
  301. package/dist/roomAccessSweep.js +94 -0
  302. package/dist/roomAppCommandControl.js +58 -0
  303. package/dist/roomAuthoringStrategy.js +16 -0
  304. package/dist/roomErasure.js +197 -0
  305. package/dist/roomPoolRuntimeDefaults.js +23 -0
  306. package/dist/roomPoolSelection.js +18 -0
  307. package/dist/roomPoolTopology.js +211 -0
  308. package/dist/rpc.d.ts +551 -0
  309. package/dist/rpc.js +111 -0
  310. package/dist/rpcClient.js +151 -0
  311. package/dist/rpcRoutes.js +27 -0
  312. package/dist/runtime.js +1122 -0
  313. package/dist/schemaHistory.js +97 -0
  314. package/dist/seatStore.js +150 -0
  315. package/dist/seatStrategyFixtures.js +51 -0
  316. package/dist/seatSubject.js +31 -0
  317. package/dist/seats.js +129 -0
  318. package/dist/serverSession.js +810 -0
  319. package/dist/serverSessionConfig.js +42 -0
  320. package/dist/sessionAdmission.js +52 -0
  321. package/dist/sidecarAdmission.js +102 -0
  322. package/dist/sidecarConfig.js +115 -0
  323. package/dist/sidecarConfigPublication.js +63 -0
  324. package/dist/sidecarHostListener.js +207 -0
  325. package/dist/sidecarIpc.js +204 -0
  326. package/dist/sidecarPeer.js +309 -0
  327. package/dist/sidecarProcessPort.js +27 -0
  328. package/dist/sidecarRuntime.js +167 -0
  329. package/dist/sidecarSelection.js +141 -0
  330. package/dist/sidecarWire.js +177 -0
  331. package/dist/sidecarWrites.js +162 -0
  332. package/dist/simulation.d.ts +391 -0
  333. package/dist/simulation.js +281 -0
  334. package/dist/simulationAuthoring.js +28 -0
  335. package/dist/simulationBytes.js +26 -0
  336. package/dist/simulationConformance.js +304 -0
  337. package/dist/simulationInputHistoryCapture.js +34 -0
  338. package/dist/simulationInputHistoryWire.js +192 -0
  339. package/dist/simulationOptionsWire.js +77 -0
  340. package/dist/simulationRecoveryWire.js +133 -0
  341. package/dist/simulationReplay.js +126 -0
  342. package/dist/simulationSnapshotWire.js +111 -0
  343. package/dist/simulationState.js +177 -0
  344. package/dist/snapshotBlob.js +125 -0
  345. package/dist/snapshotBlobCleanup.js +92 -0
  346. package/dist/snapshotBlobIndex.js +37 -0
  347. package/dist/snapshotBudget.js +79 -0
  348. package/dist/snapshotChain.js +184 -0
  349. package/dist/snapshotErasure.js +171 -0
  350. package/dist/snapshotInspection.js +104 -0
  351. package/dist/snapshotSegmentBlobs.js +57 -0
  352. package/dist/snapshotUploads.js +165 -0
  353. package/dist/socketTransport.js +252 -0
  354. package/dist/spatial.js +103 -0
  355. package/dist/spectatorPolicy.js +25 -0
  356. package/dist/spectatorProducer.js +88 -0
  357. package/dist/startFailureCause.js +3 -0
  358. package/dist/stateCodec.js +657 -0
  359. package/dist/strategies.d.ts +210 -0
  360. package/dist/strategies.js +8 -0
  361. package/dist/strategiesServer.d.ts +286 -0
  362. package/dist/strategiesServer.js +11 -0
  363. package/dist/strategyFixtures.js +181 -0
  364. package/dist/streamFraming.js +121 -0
  365. package/dist/streamTransport.js +265 -0
  366. package/dist/subjectAdmission.js +49 -0
  367. package/dist/subjectPrivacy.js +280 -0
  368. package/dist/subjectPrivacyBinding.js +89 -0
  369. package/dist/systemManifest.js +181 -0
  370. package/dist/tables.js +158 -0
  371. package/dist/testHarness.js +88 -0
  372. package/dist/testing.d.ts +3684 -0
  373. package/dist/testing.js +220 -0
  374. package/dist/testingPorts.js +270 -0
  375. package/dist/testingServer.d.ts +4060 -0
  376. package/dist/testingServer.js +18 -0
  377. package/dist/transform.d.ts +692 -0
  378. package/dist/transform.js +216 -0
  379. package/dist/transform3d.js +117 -0
  380. package/dist/transformCollection.js +23 -0
  381. package/dist/transformCollection3d.js +23 -0
  382. package/dist/transformCollectionCore.js +155 -0
  383. package/dist/transformFrames.js +120 -0
  384. package/dist/transformPrediction3d.js +126 -0
  385. package/dist/transformRules.js +122 -0
  386. package/dist/transformSchemas.js +19 -0
  387. package/dist/transport.js +31 -0
  388. package/dist/transportAuthoring.js +28 -0
  389. package/dist/transportCleanup.js +21 -0
  390. package/dist/transportConformance.js +123 -0
  391. package/dist/transportConnector.js +81 -0
  392. package/dist/transportEndpoints.js +37 -0
  393. package/dist/transportsServer.d.ts +5515 -0
  394. package/dist/transportsServer.js +6 -0
  395. package/dist/viewProjection.js +15 -0
  396. package/dist/web.d.ts +2286 -0
  397. package/dist/web.js +517 -0
  398. package/dist/webTransportClient.js +172 -0
  399. package/dist/wire.d.ts +992 -0
  400. package/dist/wire.js +491 -0
  401. package/dist/withdrawalPort.js +27 -0
  402. package/dist/world.d.ts +1894 -0
  403. package/dist/world.js +332 -0
  404. package/dist/worldActorReceipts.js +47 -0
  405. package/dist/worldActorTransferSnapshot.js +13 -0
  406. package/dist/worldAdmissionPending.js +7 -0
  407. package/dist/worldBoundaryCoordinator.js +147 -0
  408. package/dist/worldCatalog.js +80 -0
  409. package/dist/worldCellAllocation.js +202 -0
  410. package/dist/worldCellDestination.js +67 -0
  411. package/dist/worldCells.js +488 -0
  412. package/dist/worldChange.js +31 -0
  413. package/dist/worldClient.js +663 -0
  414. package/dist/worldClientControl.js +140 -0
  415. package/dist/worldClientPendingInput.js +15 -0
  416. package/dist/worldClientRpc.js +132 -0
  417. package/dist/worldClientRpcRoutes.js +42 -0
  418. package/dist/worldClientSchemas.js +27 -0
  419. package/dist/worldCommands.js +139 -0
  420. package/dist/worldData.js +41 -0
  421. package/dist/worldDefaultBinding.js +376 -0
  422. package/dist/worldDefaultGroupAdmission.js +81 -0
  423. package/dist/worldDefaultGroupAppServices.js +30 -0
  424. package/dist/worldDefaultGroupCompensation.js +108 -0
  425. package/dist/worldDefaultGroupContinuation.js +95 -0
  426. package/dist/worldDefaultGroupControl.js +71 -0
  427. package/dist/worldDefaultGroupMembers.js +84 -0
  428. package/dist/worldDefaultGroups.js +20 -0
  429. package/dist/worldDefaultPending.js +78 -0
  430. package/dist/worldDefaultService.js +244 -0
  431. package/dist/worldEntities.js +2979 -0
  432. package/dist/worldEntityCodec.js +20 -0
  433. package/dist/worldEntityHandoffView.js +153 -0
  434. package/dist/worldGeometry.js +169 -0
  435. package/dist/worldGhostAdmission.js +64 -0
  436. package/dist/worldGhostDestination.js +117 -0
  437. package/dist/worldGhostGateway.js +131 -0
  438. package/dist/worldGhostHandshake.js +107 -0
  439. package/dist/worldGhostHost.js +41 -0
  440. package/dist/worldGhostIngress.js +131 -0
  441. package/dist/worldGhostNeighborhood.js +69 -0
  442. package/dist/worldGhostNeighbors.js +85 -0
  443. package/dist/worldGhostOutbound.js +109 -0
  444. package/dist/worldGhostPublisher.js +215 -0
  445. package/dist/worldGhostReceiver.js +212 -0
  446. package/dist/worldGhostSender.js +145 -0
  447. package/dist/worldGhostSocket.js +77 -0
  448. package/dist/worldGhostWire.js +171 -0
  449. package/dist/worldGroupCommand.js +48 -0
  450. package/dist/worldGroupDeadline.js +114 -0
  451. package/dist/worldGroupPreparation.js +114 -0
  452. package/dist/worldGroupReadyControl.js +127 -0
  453. package/dist/worldGroupSupervisor.js +119 -0
  454. package/dist/worldHandoffMetrics.js +58 -0
  455. package/dist/worldHandoffView.js +99 -0
  456. package/dist/worldHostSource.js +68 -0
  457. package/dist/worldInspectEndpoint.js +249 -0
  458. package/dist/worldInspection.js +108 -0
  459. package/dist/worldInstanceAdmission.js +30 -0
  460. package/dist/worldInstanceAllocation.js +115 -0
  461. package/dist/worldInstanceDestination.js +63 -0
  462. package/dist/worldInstanceExpiry.js +281 -0
  463. package/dist/worldInstanceExpirySupervisor.js +87 -0
  464. package/dist/worldInstanceLifecycle.js +102 -0
  465. package/dist/worldInstanceState.js +51 -0
  466. package/dist/worldInstances.js +477 -0
  467. package/dist/worldJoin.js +55 -0
  468. package/dist/worldLayers.js +150 -0
  469. package/dist/worldLeases.js +77 -0
  470. package/dist/worldManifest.js +24 -0
  471. package/dist/worldMovement.js +62 -0
  472. package/dist/worldPersistence.js +133 -0
  473. package/dist/worldProjection.js +220 -0
  474. package/dist/worldReact.js +109 -0
  475. package/dist/worldRecoveryActor.js +34 -0
  476. package/dist/worldReturnAnchor.js +48 -0
  477. package/dist/worldRoomHooks.js +56 -0
  478. package/dist/worldRoomPool.js +26 -0
  479. package/dist/worldRoomSteps.js +132 -0
  480. package/dist/worldSeatBinding.js +35 -0
  481. package/dist/worldServer.d.ts +6936 -0
  482. package/dist/worldServer.js +48 -0
  483. package/dist/worldSourceSeatPending.js +8 -0
  484. package/dist/worldStrategyFixtures.js +163 -0
  485. package/dist/worldTesting.js +26 -0
  486. package/dist/worldTransitionDefaults.js +197 -0
  487. package/dist/worldTransitionExecutor.js +518 -0
  488. package/dist/worldTransitionGroup.js +112 -0
  489. package/dist/worldTransitionPhysicalSteps.js +39 -0
  490. package/dist/worldTransitionResolver.js +227 -0
  491. package/dist/worldTransitionSeatGroup.js +63 -0
  492. package/dist/worldTransitionSeats.js +259 -0
  493. package/dist/worldTransitionState.js +94 -0
  494. package/dist/worldTransitions.js +100 -0
  495. package/package.json +189 -4
@@ -0,0 +1,3897 @@
1
+ import { Context } from 'effect';
2
+ import { DataStore } from '@voltro/database';
3
+ import { DeclaredAccess } from '@voltro/protocol';
4
+ import { Duration } from 'effect';
5
+ import { Effect } from 'effect';
6
+ import { Layer } from 'effect';
7
+ import { PluginPrivacyRequest } from '@voltro/protocol';
8
+ import { Result } from 'effect';
9
+ import { Schema } from 'effect';
10
+ import { SessionSecrets } from '@voltro/protocol/session';
11
+ import { YieldableError } from 'effect/Cause';
12
+
13
+ /** Configuration consumers never invoke a player callback. Its player type
14
+ * stays author-owned; this inventory type does not erase it into an input. */
15
+ declare type AnyWorldDescriptor = WorldDescriptor<never>;
16
+
17
+ declare type CollisionBody2D = {
18
+ readonly kind: 'circle';
19
+ readonly radius: number;
20
+ } | {
21
+ readonly kind: 'aabb';
22
+ readonly halfWidth: number;
23
+ readonly halfHeight: number;
24
+ };
25
+
26
+ declare interface CollisionResult2D {
27
+ readonly transform: Transform2D;
28
+ readonly collided: ReadonlyArray<string>;
29
+ readonly iterations: number;
30
+ }
31
+
32
+ export declare const createRoomLockstepHostLoop: <S extends Schema.Codec<unknown, unknown>, I extends Schema.Codec<unknown, unknown>, O extends Schema.Codec<unknown, unknown>>(simulation: Simulation<S, I, O>, seed: number, options: O["Type"], scope: RoomLockstepRosterScope, now: () => number, serverOptions?: RoomLockstepServerOptions, loopOptions?: RoomLockstepHostLoopOptions) => RoomLockstepHostLoop<S, I, O>;
33
+
34
+ export declare const createRoomLockstepInputRoster: <I extends Schema.Codec<unknown, unknown>>(schema: I, scope: RoomLockstepRosterScope, options?: RoomLockstepRosterOptions) => RoomLockstepInputRoster<I>;
35
+
36
+ export declare const createRoomLockstepServer: <S extends Schema.Codec<unknown, unknown>, I extends Schema.Codec<unknown, unknown>, O extends Schema.Codec<unknown, unknown>>(simulation: Simulation<S, I, O>, seed: number, options: O["Type"], scope: RoomLockstepRosterScope, budgets?: RoomLockstepServerOptions) => RoomLockstepServer<S, I, O>;
37
+
38
+ export declare const createRoomLockstepTransportOwner: <S extends Schema.Codec<unknown, unknown>, I extends Schema.Codec<unknown, unknown>, O extends Schema.Codec<unknown, unknown>>(simulation: Simulation<S, I, O>, seed: number, options: O["Type"], scope: RoomLockstepRosterScope, now: () => number, serverOptions?: RoomLockstepServerOptions, loopOptions?: RoomLockstepHostLoopOptions, transportOptions?: RoomLockstepTransportOptions) => RoomLockstepTransportOwner<S, I, O>;
39
+
40
+ /** Real SQL pre-seat creation: immutable seed/options/schema/creator, no fake
41
+ * state checkpoint or game actor. Shared Room row remains the sole truth. */
42
+ export declare const dataStoreRoomLockstepAdmission: <S extends Schema.Codec<unknown, unknown>, I extends Schema.Codec<unknown, unknown>, O extends Schema.Codec<unknown, unknown>>(store: DataStore, offeredDescriptor: RoomLockstepDescriptor<S, I, O>, offered: RoomLockstepAdmissionStoreOptions) => Context.Service.Shape<typeof RoomLockstepAdmissionPort>;
43
+
44
+ /** The journal's header is an owned nullable JSON column on the Room row, its confirmed
45
+ * inputs one row per tick (`lockstepJournalRows.ts`): SQL alone retains seed, options,
46
+ * admitted roster and every confirmed input; no simulation in this store. An append writes
47
+ * one row and the small header, whatever the match length. Bound full history refuses
48
+ * exhaustion rather than pruning a Relay's rebuild base. */
49
+ export declare const dataStoreRoomLockstepJournal: <S extends Schema.Codec<unknown, unknown>, I extends Schema.Codec<unknown, unknown>, O extends Schema.Codec<unknown, unknown>>(store: DataStore, simulation: Simulation<S, I, O>, offered: RoomLockstepJournalStoreOptions) => Context.Service.Shape<typeof RoomLockstepJournalPort>;
50
+
51
+ /** Same existing SQL Room row, exact current owner and admission receipt. */
52
+ export declare const dataStoreRoomLockstepTerminal: <S extends Schema.Codec<unknown, unknown>, I extends Schema.Codec<unknown, unknown>, O extends Schema.Codec<unknown, unknown>>(store: DataStore, offeredDescriptor: RoomLockstepDescriptor<S, I, O>, offered: RoomLockstepTerminalStoreOptions) => Context.Service.Shape<typeof RoomLockstepTerminalPort>;
53
+
54
+ /** Exact reduced integer ratio over admitted coordinates/differences of magnitude <= u32.
55
+ * Shared 2D/3D slab arithmetic; never round a fraction before comparing it. */
56
+ declare interface FixedSlabFraction {
57
+ readonly numerator: number;
58
+ readonly denominator: number;
59
+ }
60
+
61
+ declare interface GeometryActivation {
62
+ readonly _tag: 'GeometryActivation';
63
+ readonly receipt: GeometryPersistenceReceipt;
64
+ }
65
+
66
+ declare interface GeometryActorInventory {
67
+ at(coordinate: GeometryPreparedCoordinate): GeometryPreparedEntry;
68
+ contains(coordinate: GeometryPreparedCoordinate): boolean;
69
+ /** CPU pointer activation only; a stale before-frame refuses, exact repeat is false. */
70
+ activate(activation: GeometryActivation): boolean;
71
+ /** CPU-only whole-version swap after genuine outside-Tick SQL preparation. */
72
+ activateVersion(activation: GeometryVersionActivation): boolean;
73
+ observation(): GeometryActorInventoryObservation;
74
+ close(): void;
75
+ }
76
+
77
+ declare interface GeometryActorInventoryObservation {
78
+ readonly scope: GeometryPreparedScope;
79
+ readonly generation: number;
80
+ readonly chunks: number;
81
+ readonly accountedBytes: number;
82
+ readonly closed: boolean;
83
+ }
84
+
85
+ declare interface GeometryArtifact<C extends GeometryChunk = GeometryChunk> {
86
+ readonly chunk: C;
87
+ readonly blobSha256: string;
88
+ /** Canonical declared content/layout, excluding actual address/version only. */
89
+ readonly contentSha256: string;
90
+ bytes(): Uint8Array;
91
+ }
92
+
93
+ declare type GeometryArtifactLimits<K extends GeometryKind> = K extends '2d-tiles' ? Partial<GeometryTileLimits> : K extends '2d-heightfield' ? Partial<GeometryHeightfieldLimits> : K extends '3d-shapes' ? Partial<GeometryShapesLimits> : Partial<GeometryVoxelLimits>;
94
+
95
+ declare interface GeometryBoxOverlapOptions {
96
+ readonly maxTests?: number;
97
+ }
98
+
99
+ declare type GeometryChunk = GeometryTileChunk | GeometryHeightfieldChunk | GeometryShapesChunk | GeometryVoxelChunk;
100
+
101
+ declare type GeometryCollisionDerive = (context: GeometryDerivationContext) => GeometryChunk;
102
+
103
+ declare type GeometryCompaction = (context: GeometryCompactionContext) => GeometryPatch;
104
+
105
+ /** Genuine immutable native artifacts only. Compaction preserves the current
106
+ * truth; it cannot authorize a different edit, owner, revision or SQL write. */
107
+ declare interface GeometryCompactionContext {
108
+ readonly static: GeometryArtifact;
109
+ readonly current: GeometryArtifact;
110
+ readonly limits: GeometryPatchLimits;
111
+ readonly codecLimits: GeometryArtifactLimits<GeometryKind>;
112
+ }
113
+
114
+ declare interface GeometryCompactionStrategies {
115
+ readonly compaction: GeometryCompaction;
116
+ }
117
+
118
+ declare interface GeometryDeltaMigrationFrom {
119
+ readonly static: GeometryArtifact;
120
+ readonly current: GeometryArtifact;
121
+ readonly revision: number;
122
+ }
123
+
124
+ declare interface GeometryDeltaMigrationTo {
125
+ readonly static: GeometryArtifact;
126
+ }
127
+
128
+ /** Outside-Tick native data only. No query callback, provider, actor, Store or
129
+ * authority capability is accepted as a derivation result. */
130
+ declare interface GeometryDerivationContext {
131
+ readonly chunk: GeometryChunk;
132
+ readonly codecLimits: GeometryArtifactLimits<GeometryKind>;
133
+ }
134
+
135
+ declare interface GeometryDerivationStrategies {
136
+ readonly collisionDerive: GeometryCollisionDerive;
137
+ readonly navDerive: GeometryNavDerive;
138
+ }
139
+
140
+ /** Trusted server snapshot. Never derive these rights, positions, budgets or
141
+ * catalogs from the intent body. App policy must recheck authority at commit. */
142
+ declare interface GeometryEditAuthority {
143
+ readonly dynamicEnabled: boolean;
144
+ readonly ownsChunk: boolean;
145
+ readonly canBuild: boolean;
146
+ readonly cooldownReady: boolean;
147
+ readonly remainingOps: number;
148
+ readonly maxReachRaw: number;
149
+ readonly maxHeightUnits: number;
150
+ readonly position: {
151
+ readonly xRaw: number;
152
+ readonly yRaw: number;
153
+ readonly zRaw: number;
154
+ };
155
+ readonly materials: ReadonlyArray<GeometryTileMaterial>;
156
+ readonly shapes: ReadonlyArray<GeometryShapeTemplate>;
157
+ }
158
+
159
+ declare interface GeometryEditContext {
160
+ readonly chunk: GeometryChunk;
161
+ readonly intent: GeometryEditIntent;
162
+ readonly authority: GeometryEditAuthority;
163
+ readonly placementId: string;
164
+ readonly codecLimits?: GeometryArtifactLimits<GeometryKind> | undefined;
165
+ }
166
+
167
+ /** Player requests an action and its target, never solidity, shape dimensions,
168
+ * an authoritative player position, revision, owner, full chunk or Delta bytes. */
169
+ declare type GeometryEditIntent = {
170
+ readonly op: 'setTile';
171
+ readonly x: number;
172
+ readonly y: number;
173
+ readonly material: string;
174
+ } | {
175
+ readonly op: 'raiseHeight';
176
+ readonly x: number;
177
+ readonly y: number;
178
+ readonly units: number;
179
+ } | {
180
+ readonly op: 'setVoxel';
181
+ readonly x: number;
182
+ readonly y: number;
183
+ readonly z: number;
184
+ readonly material: string;
185
+ } | {
186
+ readonly op: 'placeShape';
187
+ readonly template: string;
188
+ readonly xRaw: number;
189
+ readonly yRaw: number;
190
+ readonly zRaw: number;
191
+ } | {
192
+ readonly op: 'removeShape';
193
+ readonly id: string;
194
+ };
195
+
196
+ declare interface GeometryEditStrategies {
197
+ /** Pure policy slot. Current native Session/SQL ownership and codec integrity cannot be overridden by this slot. */
198
+ readonly opValidator: (context: GeometryEditContext) => void;
199
+ /** Pure rule slot; returned chunk is admitted under the original identity/layout/profile. */
200
+ readonly applyOp: (context: GeometryEditContext) => GeometryChunk;
201
+ }
202
+
203
+ declare type GeometryGenerator = (context: GeometryProceduralContext) => GeometryChunk;
204
+
205
+ declare interface GeometryGridRayHit {
206
+ readonly kind: '2d-tiles' | '3d-voxel';
207
+ readonly scope: GeometryPersistenceScope;
208
+ readonly revision: number;
209
+ readonly cell: {
210
+ readonly x: number;
211
+ readonly y: number;
212
+ readonly z?: number;
213
+ };
214
+ /** Exact reduced infimum entry fraction on the offered segment, not a
215
+ * rounded contact point or a floating-point distance. */
216
+ readonly fraction: {
217
+ readonly numerator: number;
218
+ readonly denominator: number;
219
+ };
220
+ readonly visitedCells: number;
221
+ }
222
+
223
+ declare interface GeometryGridRayOptions {
224
+ readonly maxVisitedCells?: number;
225
+ }
226
+
227
+ declare interface GeometryGridSweepHit {
228
+ readonly kind: '2d-tiles' | '3d-voxel';
229
+ readonly scope: GeometryPersistenceScope;
230
+ readonly revision: number;
231
+ readonly cell: {
232
+ readonly x: number;
233
+ readonly y: number;
234
+ readonly z?: number;
235
+ };
236
+ /** Infimum/supremum of positive-volume overlap, clipped to [0,1]. Contact
237
+ * alone is not an overlap; fractions are exact reduced integer ratios. */
238
+ readonly entry: FixedSlabFraction;
239
+ readonly exit: FixedSlabFraction;
240
+ readonly initialOverlap: boolean;
241
+ readonly testedCells: number;
242
+ }
243
+
244
+ /** A half-open raw box `[min, max)` on all three axes; a heightfield box needs its z extent. */
245
+ declare interface GeometryHeightfieldBoxRaw {
246
+ readonly minXRaw: number;
247
+ readonly minYRaw: number;
248
+ readonly minZRaw: number;
249
+ readonly maxXRaw: number;
250
+ readonly maxYRaw: number;
251
+ readonly maxZRaw: number;
252
+ }
253
+
254
+ declare type GeometryHeightfieldChunk = (typeof GeometryHeightfieldChunkSchema)["Type"];
255
+
256
+ declare const GeometryHeightfieldChunkSchema: Schema.Struct<{
257
+ readonly kind: Schema.Literal<"2d-heightfield">;
258
+ readonly formatVersion: Schema.Literal<1>;
259
+ readonly address: Schema.Struct<{
260
+ readonly worldId: Schema.String;
261
+ readonly layerSetId: Schema.String;
262
+ readonly cx: Schema.Int;
263
+ readonly cy: Schema.Int;
264
+ }>;
265
+ readonly version: Schema.String;
266
+ readonly width: Schema.Int;
267
+ readonly height: Schema.Int;
268
+ readonly sampleSpacingRaw: Schema.Int;
269
+ readonly baseHeightRaw: Schema.Int;
270
+ readonly heightQuantumRaw: Schema.Int;
271
+ readonly heights: Schema.$Array<Schema.Int>;
272
+ }>;
273
+
274
+ declare interface GeometryHeightfieldLimits {
275
+ readonly maxSide: number;
276
+ readonly maxSamples: number;
277
+ readonly maxBytes: number;
278
+ }
279
+
280
+ declare interface GeometryHeightfieldRayHit {
281
+ readonly kind: '2d-heightfield';
282
+ readonly scope: GeometryPersistenceScope;
283
+ readonly revision: number;
284
+ /** The first point on the segment at or below the surface, in global raw units. */
285
+ readonly point: GeometryHeightfieldRayPoint;
286
+ /** Exact reduced position on the offered segment whose raw-grid point is `point`. */
287
+ readonly fraction: {
288
+ readonly numerator: number;
289
+ readonly denominator: number;
290
+ };
291
+ readonly visitedSamples: number;
292
+ }
293
+
294
+ declare interface GeometryHeightfieldRayPoint {
295
+ readonly xRaw: number;
296
+ readonly yRaw: number;
297
+ readonly zRaw: number;
298
+ }
299
+
300
+ declare interface GeometryHeightfieldSweepHit {
301
+ readonly kind: '2d-heightfield';
302
+ /** The first box position along the path that reaches under the surface, on the raw grid. */
303
+ readonly box: GeometryHeightfieldBoxRaw;
304
+ /** Exact reduced position of `box` on the path: raw steps along the longest axis over its length. */
305
+ readonly fraction: {
306
+ readonly numerator: number;
307
+ readonly denominator: number;
308
+ };
309
+ /** The start box already reaches under the surface (fraction 0). */
310
+ readonly initialOverlap: boolean;
311
+ /** Overlap evaluations used, coarse and refining together. */
312
+ readonly evaluations: number;
313
+ }
314
+
315
+ declare interface GeometryHeightfieldView {
316
+ readonly chunk: GeometryHeightfieldChunk;
317
+ heightAtSample(x: number, y: number): number;
318
+ heightAtRaw(xRaw: number, yRaw: number): number;
319
+ }
320
+
321
+ declare type GeometryKind = GeometryChunk['kind'];
322
+
323
+ /** Pure native data rule only; no SQL, actor, journal, permission or Subject. */
324
+ declare type GeometryMigrateDelta = (from: GeometryDeltaMigrationFrom, to: GeometryDeltaMigrationTo) => GeometryChunk | null;
325
+
326
+ declare interface GeometryMigrationReceipt {
327
+ readonly requestKey: string;
328
+ readonly inputSha256: string;
329
+ readonly from: GeometryPersistenceScope;
330
+ readonly to: GeometryPersistenceScope;
331
+ readonly fromRevision: number;
332
+ readonly revision: number;
333
+ readonly decision: 'kept' | 'discarded' | 'custom';
334
+ readonly staticChanged: boolean;
335
+ readonly fromManifestSha256: string;
336
+ readonly toManifestSha256: string;
337
+ readonly blobSha256: string;
338
+ readonly contentSha256: string;
339
+ }
340
+
341
+ declare type GeometryNavDerive = (context: GeometryDerivationContext) => GeometryTileChunk | null;
342
+
343
+ declare interface GeometryPatch {
344
+ readonly metadata: GeometryPatchMetadata;
345
+ bytes(): Uint8Array;
346
+ }
347
+
348
+ declare interface GeometryPatchLimits {
349
+ readonly maxBytes: number;
350
+ readonly maxMetadataBytes: number;
351
+ }
352
+
353
+ declare type GeometryPatchMetadata = (typeof GeometryPatchMetadataSchema)["Type"];
354
+
355
+ declare const GeometryPatchMetadataSchema: Schema.Struct<{
356
+ readonly kind: Schema.Literals<readonly ["2d-tiles", "2d-heightfield", "3d-shapes", "3d-voxel"]>;
357
+ readonly formatVersion: Schema.Literal<1>;
358
+ readonly worldId: Schema.String;
359
+ readonly layerSetId: Schema.String;
360
+ readonly cx: Schema.Int;
361
+ readonly cy: Schema.Int;
362
+ readonly cz: Schema.optional<Schema.Int>;
363
+ readonly version: Schema.String;
364
+ readonly baseRevision: Schema.Int;
365
+ readonly revision: Schema.Int;
366
+ readonly baseBlobSha256: Schema.String;
367
+ readonly blobSha256: Schema.String;
368
+ readonly baseContentSha256: Schema.String;
369
+ readonly contentSha256: Schema.String;
370
+ readonly changed: Schema.Boolean;
371
+ readonly stateSchemaHash: Schema.Int;
372
+ }>;
373
+
374
+ declare interface GeometryPersistenceReceipt {
375
+ readonly scope: GeometryPersistenceScope;
376
+ readonly requestId: string;
377
+ readonly baseRevision: number;
378
+ readonly revision: number;
379
+ readonly changed: boolean;
380
+ readonly blobSha256: string;
381
+ readonly contentSha256: string;
382
+ }
383
+
384
+ declare interface GeometryPersistenceScope {
385
+ readonly tenantId: string;
386
+ readonly kind: GeometryKind;
387
+ readonly worldId: string;
388
+ readonly version: string;
389
+ readonly layerSetId: string;
390
+ readonly cx: number;
391
+ readonly cy: number;
392
+ readonly cz?: number | undefined;
393
+ }
394
+
395
+ declare interface GeometryPersistenceSubject {
396
+ readonly id: string;
397
+ readonly kind: 'user' | 'guest';
398
+ }
399
+
400
+ declare interface GeometryPointRaw3D {
401
+ readonly xRaw: number;
402
+ readonly yRaw: number;
403
+ readonly zRaw: number;
404
+ }
405
+
406
+ declare interface GeometryPreparedCoordinate {
407
+ readonly cx: number;
408
+ readonly cy: number;
409
+ readonly cz?: number | undefined;
410
+ }
411
+
412
+ declare type GeometryPreparedEntry = PreparedCommon & GeometryPreparedView & {
413
+ /** Independently prepared native collision data. Original view/artifact remains the edit/rebuild baseline. */
414
+ readonly collision: GeometryPreparedView;
415
+ readonly navigation: GeometryTileView | null;
416
+ };
417
+
418
+ declare interface GeometryPreparedScope {
419
+ readonly tenantId: string;
420
+ readonly kind: GeometryKind;
421
+ readonly worldId: string;
422
+ readonly layerSetId: string;
423
+ readonly version: string;
424
+ }
425
+
426
+ declare type GeometryPreparedView = ({
427
+ readonly kind: '2d-tiles';
428
+ readonly view: GeometryTileView;
429
+ } | {
430
+ readonly kind: '2d-heightfield';
431
+ readonly view: GeometryHeightfieldView;
432
+ } | {
433
+ readonly kind: '3d-shapes';
434
+ readonly view: GeometryShapesView;
435
+ } | {
436
+ readonly kind: '3d-voxel';
437
+ readonly view: GeometryVoxelView;
438
+ });
439
+
440
+ declare interface GeometryPrivacyTarget {
441
+ readonly tenantId: string;
442
+ readonly subject: GeometryPersistenceSubject;
443
+ readonly requestId: string;
444
+ }
445
+
446
+ declare interface GeometryProceduralContext {
447
+ readonly seed: number;
448
+ readonly kind: GeometryKind;
449
+ readonly address: GeometryChunk['address'];
450
+ readonly version: string;
451
+ }
452
+
453
+ declare type GeometryShape = (typeof GeometryShapeSchema)["Type"];
454
+
455
+ declare interface GeometryShapeRayHit {
456
+ readonly kind: '3d-shapes';
457
+ readonly scope: GeometryPersistenceScope;
458
+ readonly revision: number;
459
+ /** Native LOCAL shape; scope identifies its owning chunk. */
460
+ readonly shape: GeometryShape;
461
+ /** Encloses the exact infimum entry time; width <= 2^-52. Presentation only.
462
+ * Selection and ownership decisions never use these rounded bounds. */
463
+ readonly fractionBounds: {
464
+ readonly lower: number;
465
+ readonly upper: number;
466
+ };
467
+ readonly visitedChunks: number;
468
+ readonly testedShapes: number;
469
+ }
470
+
471
+ declare const GeometryShapeSchema: Schema.Union<readonly [Schema.Struct<{
472
+ readonly halfXRaw: Schema.Int;
473
+ readonly halfYRaw: Schema.Int;
474
+ readonly halfZRaw: Schema.Int;
475
+ readonly id: Schema.String;
476
+ readonly xRaw: Schema.Int;
477
+ readonly yRaw: Schema.Int;
478
+ readonly zRaw: Schema.Int;
479
+ readonly kind: Schema.Literal<"aabb">;
480
+ }>, Schema.Struct<{
481
+ readonly radiusRaw: Schema.Int;
482
+ readonly id: Schema.String;
483
+ readonly xRaw: Schema.Int;
484
+ readonly yRaw: Schema.Int;
485
+ readonly zRaw: Schema.Int;
486
+ readonly kind: Schema.Literal<"sphere">;
487
+ }>]>;
488
+
489
+ declare type GeometryShapesChunk = (typeof GeometryShapesChunkSchema)["Type"];
490
+
491
+ declare const GeometryShapesChunkSchema: Schema.Struct<{
492
+ readonly kind: Schema.Literal<"3d-shapes">;
493
+ readonly formatVersion: Schema.Literal<1>;
494
+ readonly address: Schema.Struct<{
495
+ readonly worldId: Schema.String;
496
+ readonly layerSetId: Schema.String;
497
+ readonly cx: Schema.Int;
498
+ readonly cy: Schema.Int;
499
+ readonly cz: Schema.Int;
500
+ }>;
501
+ readonly version: Schema.String;
502
+ readonly extentXRaw: Schema.Int;
503
+ readonly extentYRaw: Schema.Int;
504
+ readonly extentZRaw: Schema.Int;
505
+ readonly shapes: Schema.$Array<Schema.Union<readonly [Schema.Struct<{
506
+ readonly halfXRaw: Schema.Int;
507
+ readonly halfYRaw: Schema.Int;
508
+ readonly halfZRaw: Schema.Int;
509
+ readonly id: Schema.String;
510
+ readonly xRaw: Schema.Int;
511
+ readonly yRaw: Schema.Int;
512
+ readonly zRaw: Schema.Int;
513
+ readonly kind: Schema.Literal<"aabb">;
514
+ }>, Schema.Struct<{
515
+ readonly radiusRaw: Schema.Int;
516
+ readonly id: Schema.String;
517
+ readonly xRaw: Schema.Int;
518
+ readonly yRaw: Schema.Int;
519
+ readonly zRaw: Schema.Int;
520
+ readonly kind: Schema.Literal<"sphere">;
521
+ }>]>>;
522
+ }>;
523
+
524
+ declare interface GeometryShapesLimits {
525
+ readonly maxShapes: number;
526
+ readonly maxBytes: number;
527
+ }
528
+
529
+ declare interface GeometryShapesView {
530
+ readonly chunk: GeometryShapesChunk;
531
+ containingRaw(point: GeometryPointRaw3D, maximumShapes?: number): ReadonlyArray<GeometryShape>;
532
+ /** Closed LOCAL segment and native volumes. Canonical ID order, not distance
533
+ * order; no first-hit fraction or cross-chunk ownership is implied. */
534
+ intersectingSegmentRaw(from: GeometryPointRaw3D, to: GeometryPointRaw3D, maximumShapes?: number): ReadonlyArray<GeometryShape>;
535
+ }
536
+
537
+ declare type GeometryShapeTemplate = {
538
+ readonly key: string;
539
+ readonly kind: 'aabb';
540
+ readonly halfXRaw: number;
541
+ readonly halfYRaw: number;
542
+ readonly halfZRaw: number;
543
+ } | {
544
+ readonly key: string;
545
+ readonly kind: 'sphere';
546
+ readonly radiusRaw: number;
547
+ };
548
+
549
+ declare type GeometrySource = {
550
+ readonly _tag: 'GeometrySource';
551
+ readonly kind: 'cms';
552
+ readonly key: string;
553
+ readonly channel: string;
554
+ } | {
555
+ readonly _tag: 'GeometrySource';
556
+ readonly kind: 'imported';
557
+ readonly directory: string;
558
+ } | {
559
+ readonly _tag: 'GeometrySource';
560
+ readonly kind: 'procedural';
561
+ readonly seed: number;
562
+ readonly generator: GeometryGenerator;
563
+ };
564
+
565
+ declare interface GeometryTileCellBounds {
566
+ readonly minXRaw: number;
567
+ readonly minYRaw: number;
568
+ readonly maxXRaw: number;
569
+ readonly maxYRaw: number;
570
+ }
571
+
572
+ declare type GeometryTileChunk = (typeof GeometryTileChunkSchema)["Type"];
573
+
574
+ declare const GeometryTileChunkSchema: Schema.Struct<{
575
+ readonly kind: Schema.Literal<"2d-tiles">;
576
+ readonly formatVersion: Schema.Literal<1>;
577
+ readonly address: Schema.Struct<{
578
+ readonly worldId: Schema.String;
579
+ readonly layerSetId: Schema.String;
580
+ readonly cx: Schema.Int;
581
+ readonly cy: Schema.Int;
582
+ }>;
583
+ readonly version: Schema.String;
584
+ readonly width: Schema.Int;
585
+ readonly height: Schema.Int;
586
+ readonly tileSizeRaw: Schema.Int;
587
+ readonly palette: Schema.$Array<Schema.Struct<{
588
+ readonly key: Schema.String;
589
+ readonly solid: Schema.Boolean;
590
+ }>>;
591
+ readonly runs: Schema.$Array<Schema.Struct<{
592
+ readonly paletteIndex: Schema.Int;
593
+ readonly length: Schema.Int;
594
+ }>>;
595
+ }>;
596
+
597
+ declare interface GeometryTileCollisionOptions {
598
+ /** Total visited cells across every solver query, including its final check.
599
+ * May only narrow the world's maxOverlapTests. */
600
+ readonly maxTests?: number;
601
+ /** Existing discrete solver limit; defaults to 8, maximum 256. */
602
+ readonly maxIterations?: number;
603
+ }
604
+
605
+ declare interface GeometryTileLimits {
606
+ readonly maxSide: number;
607
+ readonly maxCells: number;
608
+ readonly maxPalette: number;
609
+ readonly maxRuns: number;
610
+ readonly maxBytes: number;
611
+ }
612
+
613
+ declare type GeometryTileMaterial = (typeof GeometryTileMaterialSchema)["Type"];
614
+
615
+ declare const GeometryTileMaterialSchema: Schema.Struct<{
616
+ readonly key: Schema.String;
617
+ readonly solid: Schema.Boolean;
618
+ }>;
619
+
620
+ declare interface GeometryTileView {
621
+ readonly chunk: GeometryTileChunk;
622
+ /** Local integer cell queries. Outside cells refuse; no missing-neighbor air. */
623
+ materialAt(x: number, y: number): GeometryTileMaterial;
624
+ solidAt(x: number, y: number): boolean;
625
+ materialAtRaw(xRaw: number, yRaw: number): GeometryTileMaterial;
626
+ cellBounds(x: number, y: number): GeometryTileCellBounds;
627
+ /** Detached row-major little-bit occupancy, never the retained mutable grid. */
628
+ occupancy(): Uint8Array;
629
+ }
630
+
631
+ declare interface GeometryVersionActivation {
632
+ readonly _tag: 'GeometryVersionActivation';
633
+ readonly receipts: ReadonlyArray<GeometryMigrationReceipt>;
634
+ }
635
+
636
+ declare interface GeometryVersionMigrationStrategies {
637
+ readonly migrateDelta?: GeometryMigrateDelta;
638
+ }
639
+
640
+ declare type GeometryVoxelChunk = (typeof GeometryVoxelChunkSchema)["Type"];
641
+
642
+ declare const GeometryVoxelChunkSchema: Schema.Struct<{
643
+ readonly kind: Schema.Literal<"3d-voxel">;
644
+ readonly formatVersion: Schema.Literal<1>;
645
+ readonly address: Schema.Struct<{
646
+ readonly worldId: Schema.String;
647
+ readonly layerSetId: Schema.String;
648
+ readonly cx: Schema.Int;
649
+ readonly cy: Schema.Int;
650
+ readonly cz: Schema.Int;
651
+ }>;
652
+ readonly version: Schema.String;
653
+ readonly side: Schema.Int;
654
+ readonly voxelSizeRaw: Schema.Int;
655
+ readonly palette: Schema.$Array<Schema.Struct<{
656
+ readonly key: Schema.String;
657
+ readonly solid: Schema.Boolean;
658
+ }>>;
659
+ readonly sections: Schema.$Array<Schema.Struct<{
660
+ readonly sx: Schema.Int;
661
+ readonly sy: Schema.Int;
662
+ readonly sz: Schema.Int;
663
+ readonly runs: Schema.$Array<Schema.Struct<{
664
+ readonly paletteIndex: Schema.Int;
665
+ readonly length: Schema.Int;
666
+ }>>;
667
+ }>>;
668
+ }>;
669
+
670
+ declare interface GeometryVoxelLimits {
671
+ readonly maxSide: number;
672
+ readonly maxVoxels: number;
673
+ readonly maxPalette: number;
674
+ readonly maxSections: number;
675
+ readonly maxRunsPerSection: number;
676
+ readonly maxBytes: number;
677
+ }
678
+
679
+ declare interface GeometryVoxelView {
680
+ readonly chunk: GeometryVoxelChunk;
681
+ materialAt(x: number, y: number, z: number): GeometryTileMaterial;
682
+ solidAt(x: number, y: number, z: number): boolean;
683
+ materialAtRaw(xRaw: number, yRaw: number, zRaw: number): GeometryTileMaterial;
684
+ occupancy(): Uint8Array;
685
+ }
686
+
687
+ /** Nonempty half-open raw box. Three-dimensional kinds require both Z fields. */
688
+ declare interface GeometryWorldBoxRaw {
689
+ readonly minXRaw: number;
690
+ readonly minYRaw: number;
691
+ readonly maxXRaw: number;
692
+ readonly maxYRaw: number;
693
+ readonly minZRaw?: number;
694
+ readonly maxZRaw?: number;
695
+ }
696
+
697
+ declare interface GeometryWorldPointRaw {
698
+ readonly xRaw: number;
699
+ readonly yRaw: number;
700
+ readonly zRaw?: number;
701
+ }
702
+
703
+ declare type GeometryWorldRayHit = GeometryGridRayHit | GeometryShapeRayHit | GeometryHeightfieldRayHit;
704
+
705
+ declare interface GeometryWorldRayOptions extends GeometryGridRayOptions {
706
+ /** Shapes only; narrows maxOverlapTests for the total shape scan. */
707
+ readonly maxTests?: number;
708
+ }
709
+
710
+ declare interface GeometryWorldShapeHit {
711
+ readonly scope: GeometryPersistenceScope;
712
+ readonly revision: number;
713
+ readonly shape: GeometryShape;
714
+ }
715
+
716
+ declare interface GeometryWorldView {
717
+ readonly kind: GeometryKind;
718
+ readonly scope: GeometryPreparedScope;
719
+ /** Discrete AABB/circle resolution in world units against current tile data.
720
+ * Reuses the Transform solver; no swept movement or velocity integration. */
721
+ collide(transform: Transform2D, body: CollisionBody2D, options?: GeometryTileCollisionOptions): CollisionResult2D;
722
+ /** Tiles/voxels only. Unloaded coordinates refuse, never implicit empty terrain. */
723
+ materialAtRaw(point: GeometryWorldPointRaw): GeometryTileMaterial;
724
+ /** Tiles/voxels/shapes: the stored solidity. Heightfields (points with `zRaw`): terrain is solid at and
725
+ * below its surface, the same surface `raycastRaw` hits. Heightfield material is not invented. */
726
+ solidAtRaw(point: GeometryWorldPointRaw): boolean;
727
+ /** Heightfield only, with exact existing native interpolation. */
728
+ heightAtRaw(point: GeometryWorldPointRaw): number;
729
+ /** Shapes only; hit volumes retain native LOCAL coordinates and exact chunk scope. */
730
+ shapesAtRaw(point: GeometryWorldPointRaw): ReadonlyArray<GeometryWorldShapeHit>;
731
+ /** Tiles/voxels return exact rational entry; shapes select exact quadratic
732
+ * entry and expose enclosing presentation bounds; heightfields (points with
733
+ * `zRaw`) return the first sampled point at or below the surface, refined to
734
+ * one raw unit (`raycastGeometryHeightfield`). Missing coverage refuses. */
735
+ raycastRaw(from: GeometryWorldPointRaw, to: GeometryWorldPointRaw, options?: GeometryWorldRayOptions): GeometryWorldRayHit | null;
736
+ /** Tiles/voxels/closed native shapes, clipped by half-open chunk ownership. Heightfields need the z extent:
737
+ * the box touches terrain when the highest surface point over its footprint is at or above `minZRaw`
738
+ * (`overlapsGeometryHeightfieldBox`). Nonempty half-open raw boxes only; missing data or work exhaustion refuses. */
739
+ overlapsBoxRaw(box: GeometryWorldBoxRaw, options?: GeometryBoxOverlapOptions): boolean;
740
+ /** Translation-only tile/voxel sweep. Shares maxOverlapTests; validates the
741
+ * whole swept bounding region before publishing the earliest overlap. */
742
+ sweepBoxRaw(from: GeometryWorldBoxRaw, to: GeometryWorldBoxRaw, options?: GeometryBoxOverlapOptions): GeometryGridSweepHit | null;
743
+ /** Heightfields only (boxes with a z extent): the first raw-grid position that reaches under the surface
744
+ * (`sweepGeometryHeightfieldBox`), coarse steps of a quarter sample spacing, at most
745
+ * `geometry.budgets.maxRayCells` overlap evaluations of `maxTests` reads each. */
746
+ sweepHeightfieldBoxRaw(from: GeometryHeightfieldBoxRaw, to: GeometryHeightfieldBoxRaw, options?: GeometryBoxOverlapOptions): GeometryHeightfieldSweepHit | null;
747
+ }
748
+
749
+ /** Narrow actor seam; transport and persistence are owned outside this loop. */
750
+ declare interface HostedRoom {
751
+ readonly id: string;
752
+ advance(): number;
753
+ dispose(): void;
754
+ isDisposed(): boolean;
755
+ isRetiring?(): boolean;
756
+ drainOutbox(): ReadonlyArray<RoomOutboxCommand>;
757
+ metrics(): RoomActorMetrics;
758
+ }
759
+
760
+ declare type LockstepClientFrame = Extract<RoomFrame, {
761
+ readonly kind: 'LsInput' | 'LsHash';
762
+ }>;
763
+
764
+ declare type LockstepDesyncAction = 'resync' | 'end' | 'flag';
765
+
766
+ declare interface LockstepDesyncContext {
767
+ readonly tick: number;
768
+ readonly playerId: number;
769
+ readonly expected: Uint64Words;
770
+ readonly received: Uint64Words;
771
+ }
772
+
773
+ declare type LockstepInputPrediction<I> = 'repeat-last' | 'none' | ((last: I, context: {
774
+ readonly playerId: number;
775
+ readonly tick: number;
776
+ }) => I);
777
+
778
+ declare interface LockstepPolicyStrategies {
779
+ readonly refereeLag?: (configuredTicks: number) => number;
780
+ readonly stallPolicy?: (options: LockstepStallPolicyOptions) => LockstepStallPolicy;
781
+ readonly onDesync?: (incident: LockstepDesyncContext, configuredAction: LockstepDesyncAction) => LockstepDesyncAction;
782
+ }
783
+
784
+ declare type LockstepServerFrame = Extract<RoomFrame, {
785
+ readonly kind: 'LsStart' | 'LsInputs' | 'LsStall' | 'LsDesync' | 'LsJoin';
786
+ }>;
787
+
788
+ declare interface LockstepSessionBinding {
789
+ readonly receive: (frame: LockstepClientFrame) => undefined;
790
+ readonly tick: () => number;
791
+ }
792
+
793
+ declare type LockstepStallDecision = {
794
+ readonly _tag: 'waiting';
795
+ readonly tick: number;
796
+ readonly elapsedTicks: number;
797
+ readonly waitingFor: Uint64Words;
798
+ } | {
799
+ readonly _tag: 'action';
800
+ readonly tick: number;
801
+ readonly elapsedTicks: number;
802
+ readonly waitingFor: Uint64Words;
803
+ readonly action: 'pause' | 'drop-player';
804
+ };
805
+
806
+ declare interface LockstepStallPolicy {
807
+ readonly afterTicks: number;
808
+ readonly action: 'pause' | 'drop-player';
809
+ }
810
+
811
+ declare interface LockstepStallPolicyOptions {
812
+ readonly afterTicks?: number;
813
+ readonly action?: 'pause' | 'drop-player';
814
+ }
815
+
816
+ /** PCG-XSH-RR 64/32. Numeric seeds are unsigned 32-bit; word seeds retain 64 bits.
817
+ * Algorithm reference: https://www.pcg-random.org/using-pcg-c-basic.html
818
+ * No global generator, BigInt, native dependency or implicit time/entropy seed. */
819
+ declare class Pcg32 {
820
+ #private;
821
+ constructor(seed: Pcg32Seed, stream?: Pcg32Seed, maxRejectionAttempts?: number);
822
+ get maxRejectionAttempts(): number;
823
+ nextU32(): number;
824
+ /** Rejection removes modulo bias. Exhaustion consumes exactly the bounded
825
+ * draws and fails; it never returns a biased fallback or substitutes entropy. */
826
+ bounded(bound: number): number;
827
+ snapshot(): Pcg32Snapshot;
828
+ restore(offered: Pcg32Snapshot): void;
829
+ clone(): Pcg32;
830
+ /** Exact skip-ahead modulo 2^64; at most 32 iterations for this delta API. */
831
+ advance(delta: number): void;
832
+ }
833
+
834
+ declare type Pcg32Seed = number | Uint64Words;
835
+
836
+ declare interface Pcg32Snapshot {
837
+ readonly stateHi: number;
838
+ readonly stateLo: number;
839
+ readonly incrementHi: number;
840
+ readonly incrementLo: number;
841
+ }
842
+
843
+ declare interface PreparedCommon {
844
+ readonly scope: GeometryPersistenceScope;
845
+ readonly revision: number;
846
+ readonly blobSha256: string;
847
+ readonly contentSha256: string;
848
+ readonly accountedBytes: number;
849
+ }
850
+
851
+ declare class ProtocolError extends ProtocolError_base {
852
+ get message(): string;
853
+ }
854
+
855
+ declare const ProtocolError_base: Schema.Class<ProtocolError, Schema.TaggedStruct<"ProtocolError", {
856
+ readonly detail: Schema.String;
857
+ }>, YieldableError>;
858
+
859
+ /** Reconstruct the actual existing authority role from retained SQL intentions.
860
+ * All real Session evidence must match current scope and historical Subject/ID.
861
+ * Borrowed Sessions are never closed or activated here. No routing/lease claimed. */
862
+ export declare const rebuildRoomLockstepAuthorityFromSql: <S extends Schema.Codec<unknown, unknown>, I extends Schema.Codec<unknown, unknown>, O extends Schema.Codec<unknown, unknown>>(simulation: Simulation<S, I, O>, offeredScope: RoomLockstepRosterScope, offered: RoomLockstepAuthorityRebuildOptions) => Effect.Effect<RoomLockstepAuthorityRebuild<S, I, O>, ProtocolError, RoomLockstepJournalPort>;
863
+
864
+ /** Reconstruct a fresh private CPU runner; no Session, host or input authority. */
865
+ export declare const rebuildRoomLockstepFromSql: <S extends Schema.Codec<unknown, unknown>, I extends Schema.Codec<unknown, unknown>, O extends Schema.Codec<unknown, unknown>>(simulation: Simulation<S, I, O>, scope: RoomLockstepRosterScope, options: RoomLockstepJournalRebuildOptions) => Effect.Effect<RoomLockstepJournalRebuild<S["Type"], O["Type"]>, ProtocolError, RoomLockstepJournalPort>;
866
+
867
+ /** One authoritative actor. This module contains no store, socket or timer. */
868
+ declare class RoomActor<S extends Schema.Codec<unknown, unknown>, I extends Schema.Codec<unknown, unknown>, O extends Schema.Codec<unknown, unknown>> {
869
+ readonly id: string;
870
+ readonly descriptor: RoomDescriptor<S, I, O>;
871
+ private readonly clock;
872
+ readonly tenantId: string;
873
+ private currentState;
874
+ private lastGoodState;
875
+ private lastGoodTick;
876
+ readonly options: (O)["Type"];
877
+ private readonly members;
878
+ private readonly grace;
879
+ private readonly inputs;
880
+ private readonly outbox;
881
+ private readonly clientOperations;
882
+ private readonly schedules;
883
+ private readonly extensionDurationMs;
884
+ private readonly extensionOverruns;
885
+ private tick;
886
+ private droppedTicks;
887
+ private commandSeq;
888
+ readonly epoch: number;
889
+ private nextTickAt;
890
+ private emptyAt;
891
+ private locked;
892
+ private disposed;
893
+ private publicationHeldAt;
894
+ private drainFrozen;
895
+ private drainAt;
896
+ private retiring;
897
+ private faulted;
898
+ private ticking;
899
+ private lastNow;
900
+ private readonly app;
901
+ private readonly scheduler;
902
+ private readonly worldPreviews;
903
+ private readonly worldReceipts;
904
+ private readonly deferredWorldLeaves;
905
+ private worldMovement;
906
+ private worldMovementClamps;
907
+ private worldMovementMargin;
908
+ private worldMovementIntents;
909
+ private worldFinalizationHold;
910
+ private readonly worldPublishedTransitions;
911
+ private lifecycleTail;
912
+ private lifecycleRequests;
913
+ private lifecycleActive;
914
+ private readonly geometry;
915
+ constructor(id: string, descriptor: RoomDescriptor<S, I, O>, initialState: (S)["Type"], options: (O)["Type"], clock: RoomClock, tenantId: string, recovery?: RoomActorRecovery, geometry?: GeometryWorldView);
916
+ get state(): RoomState<(S)["Type"]>;
917
+ private now;
918
+ private ensureOpen;
919
+ private stage;
920
+ private schedule;
921
+ join(client: RoomClient): void;
922
+ joinAsync(client: RoomClient, signal?: AbortSignal): Promise<void>;
923
+ /** Only a trusted SQL seat adapter supplies this cursor; player Hello/input
924
+ * never contains it. The successful lifecycle commits cursor and membership. */
925
+ /** `authorizeCommit` runs before the join hook and again before publication; the World
926
+ * member its first run returns reaches `onJoin` as `world`. */
927
+ joinReservedAsync(client: RoomClient, consumed: RoomConsumedSeat, signal?: AbortSignal, authorizeCommit?: () => Promise<RoomWorldMember | undefined | void>): Promise<void>;
928
+ /** Trusted Host-only pending membership. The caller must separately establish
929
+ * current SQL transition/Seat authority; the marker itself grants nothing. */
930
+ joinWorldReservedAsync(client: RoomClient, consumed: RoomConsumedSeat, authorize: () => Promise<void | 'pending' | 'committed' | 'settled'>, signal?: AbortSignal): Promise<void>;
931
+ /** The author's view of a transition arrival becoming an active member (`world.onMemberEnter`). */
932
+ private worldMemberEntered;
933
+ /** The committed World point of one entity through `world.movement.position`: the last good state, never a
934
+ * draft. Null without a movement hook, without that entity, or without a finite point. */
935
+ worldEntityPoint(entityId: string): WorldPoint | null;
936
+ /** Release only after the Host has persisted actual target enter and rechecked
937
+ * SQL authority. The retained canonical enter receipt is required locally. */
938
+ activateWorldReservedAsync(binding: WorldTargetSeatBinding, authorize: () => Promise<void>): Promise<void>;
939
+ private assertWorldMemberEntity;
940
+ isWorldPending(sessionId: string): boolean;
941
+ /** Explicit trusted local-host admission. Authentication still follows the
942
+ * descriptor; the resulting capability is bound to this exact Member object,
943
+ * so a stale bot cannot submit to or release a later reused session ID. */
944
+ joinBotAsync(client: RoomClient, countsAsPlayer?: boolean, signal?: AbortSignal): Promise<RoomActorBotLease>;
945
+ playerCount(): number;
946
+ availablePlayerSlots(): number;
947
+ monotonicNow(): number;
948
+ roster(): ReadonlyArray<Pick<RoomClient, 'sessionId' | 'subjectId' | 'tenantId'> & {
949
+ readonly isBot: boolean;
950
+ readonly countsAsPlayer: boolean;
951
+ }>;
952
+ /** Check identity/lock and current counted/grace capacity before replacing a
953
+ * bot. Full prepareJoin repeats these immediately before membership commit. */
954
+ humanAdmissionNeedsReplacement(client: RoomClient): boolean;
955
+ private prepareClientIdentity;
956
+ private prepareJoin;
957
+ leave(sessionId: string, reason?: RoomLeaveReason): void;
958
+ leaveAsync(sessionId: string, reason?: RoomLeaveReason, signal?: AbortSignal): Promise<void>;
959
+ private prepareLeave;
960
+ private assertWorldArrival;
961
+ private enterWorldDraft;
962
+ /** Execute actual target admission on an isolated draft. Nothing is published
963
+ * or receipted here. Author Effects receive prepare phase and must supply their
964
+ * own external idempotency/compensation; this is not an ownership commit. */
965
+ previewWorldEnter(input: Parameters<RoomActor<S, I, O>['applyWorldHook']>[1], maxBytes: number, signal?: AbortSignal): Promise<void>;
966
+ /** Trusted server lifecycle only. The caller supplies the configured World
967
+ * byte budget and current epoch; this grants no SQL/transition admission. */
968
+ applyWorldHook(operation: 'enter' | 'exit' | 'ghost', input: RoomWorldHookInput<RoomWorldEntity<(S)["Type"]>>, maxBytes: number, signal?: AbortSignal, authorizeCommit?: () => Promise<void>, replaceExitReceipt?: boolean, previousGhost?: RoomWorldHookInput<RoomWorldEntity<(S)["Type"]>>, retainGhostProjection?: boolean, promoteGhosts?: ReadonlyArray<RoomWorldHookInput<RoomWorldEntity<(S)["Type"]>>>): Promise<void>;
969
+ private assertWorldHookResult;
970
+ private assertWorldEnterVacant;
971
+ /** Trusted Host terminal-proof path only; it checkpoints the removal before
972
+ * returning. No gameplay state or external effect is undone here. */
973
+ retireWorldReceipt(requestId: string, operation: 'enter' | 'exit' | 'ghost'): Promise<void>;
974
+ /** Failed transition compensation, guarded before draft publication. The
975
+ * author removes its projection in onGhost phase rollback; no source rewind. */
976
+ cancelWorldGhost(input: Parameters<RoomActor<S, I, O>['applyWorldHook']>[1], maxBytes: number, authorize: () => Promise<void>): Promise<void>;
977
+ cancelWorldPreview(requestId: string, authorize: () => Promise<void>): Promise<void>;
978
+ hasWorldReceipt(requestId: string, operation: 'enter' | 'exit' | 'ghost'): boolean;
979
+ worldReceiptSnapshot(): ReadonlyArray<RoomWorldReceipt>;
980
+ /** Capture the actual current actor entity, never a caller-provided replacement.
981
+ * Returned data is detached bounded JSON; persistence remains outside the tick. */
982
+ captureWorldEntity(entityId: string, epoch: number, maxBytes: number): Promise<{
983
+ readonly entity: RoomWorldEntity<(S)["Type"]>;
984
+ readonly data: unknown;
985
+ }>;
986
+ configureWorldCellMovement(epoch: number, bounds?: WorldBounds, marginUnits?: number): Promise<void>;
987
+ worldMovementSnapshot(): {
988
+ readonly bound: boolean;
989
+ readonly clamped: number;
990
+ };
991
+ captureWorldMovement(epoch: number): Promise<WorldMovementObservation>;
992
+ private constrainWorldMovement;
993
+ listWorldEntityIds(epoch: number, maximum: number, maxBytes: number): Promise<ReadonlyArray<string>>;
994
+ captureWorldProjection(entityId: string, epoch: number, maxBytes: number): Promise<{
995
+ readonly entity: RoomWorldEntity<(S)["Type"]>;
996
+ readonly data: unknown;
997
+ readonly tick: number;
998
+ }>;
999
+ private captureWorldEntityOwned;
1000
+ /** Trusted Host handoff: one bounded room hold survives ambiguous durable writes.
1001
+ * Completion must follow checkpoint acknowledgement; never release by timeout. */
1002
+ finalizeWorldExit(input: {
1003
+ readonly afterglow?: {
1004
+ readonly requestId: string;
1005
+ readonly expiresAt: number;
1006
+ };
1007
+ readonly subjectId?: string;
1008
+ readonly epoch: number;
1009
+ readonly entityId: string;
1010
+ readonly requestId: string;
1011
+ readonly location: WorldEntityLocation;
1012
+ }, maxBytes: number, retain: (capture: {
1013
+ readonly entity: RoomWorldEntity<(S)["Type"]>;
1014
+ readonly data: unknown;
1015
+ }) => Promise<void>, authorize: () => Promise<void>, expectedEntity?: unknown, signal?: AbortSignal): Promise<void>;
1016
+ /** The actual Runtime supplies the synchronous bounded reliable enqueue. No
1017
+ * network completion is awaited while the lifecycle/SQL fence is held. */
1018
+ notifyWorldHandoff(input: Omit<RoomWorldHandoffFrame, 'tick'>, authorize: () => Promise<void>, enqueue: (frame: RoomWorldHandoffFrame) => void): Promise<void>;
1019
+ /** Only the actual Host may call this after its durable checkpoint succeeds. */
1020
+ completeWorldFinalization(requestId: string, authorize: () => Promise<void>): Promise<void>;
1021
+ worldFinalizationAfterglow(): {
1022
+ readonly requestId: string;
1023
+ readonly expiresAt: number;
1024
+ } | undefined;
1025
+ worldFinalizationRequest(): string | null;
1026
+ isWorldFinalizationHeld(): boolean;
1027
+ /** Recovery-only source reconstruction from final durable capture. Caller owns
1028
+ * unpublished successor/recovery authority and checkpoints before fence clear. */
1029
+ reconcileWorldSource(input: {
1030
+ readonly epoch: number;
1031
+ readonly requestId: string;
1032
+ readonly entity: RoomWorldEntity<(S)["Type"]>;
1033
+ readonly location: WorldEntityLocation;
1034
+ }, maxBytes: number, authorize: () => Promise<void>, signal?: AbortSignal): Promise<void>;
1035
+ private assertSynchronousLifecycle;
1036
+ private serializeLifecycle;
1037
+ private mutateMemberAsync;
1038
+ private pruneGrace;
1039
+ private mutateMember;
1040
+ /** encodedBytes is measured by the host transport, never supplied by a player. */
1041
+ input(sessionId: string, seq: number, tickHint: number, payload: unknown, encodedBytes: number): boolean;
1042
+ private send;
1043
+ private extension;
1044
+ holdPublication(): void;
1045
+ releasePublication(): void;
1046
+ /** Called by the host's single monotonic loop. Catch-up never spins unbounded. */
1047
+ advance(): number;
1048
+ drainOutbox(): ReadonlyArray<RoomOutboxCommand>;
1049
+ private stageClientOperation;
1050
+ /** Transport callbacks are invoked only by the supervisor after advance. */
1051
+ flushClientOperations(): void;
1052
+ /** Ordinary socket members and reconnect grace only. Local bots own no SQL
1053
+ * seat. Queued-but-unapplied inputs never become applied receipts; discarded
1054
+ * pending World inputs carry a separate durable rejection cursor. */
1055
+ inputReceiptSnapshot(): ReadonlyArray<RoomInputReceipt>;
1056
+ /** Runtime-only confirmation after the actual checkpoint port acknowledges.
1057
+ * Inputs arriving during the write remain unconfirmed and block activation. */
1058
+ confirmInputCheckpoint(receipts: ReadonlyArray<RoomInputReceipt>): void;
1059
+ lastAppliedInputSeq(sessionId: string): number;
1060
+ lock(): void;
1061
+ unlock(): void;
1062
+ dispose(): void;
1063
+ isDisposed(): boolean;
1064
+ isLifecycleBusy(): boolean;
1065
+ /** Permanent local simulation fence before the final planned-handoff snapshot. */
1066
+ freezeForDrain(): Promise<void>;
1067
+ /** Only after real SQL ownership handoff. No leave/dispose game hooks, SQL,
1068
+ * or new commands may run after the saved state has moved to its successor. */
1069
+ releaseTransferred(): void;
1070
+ disposeAsync(signal?: AbortSignal): Promise<void>;
1071
+ isRetiring(): boolean;
1072
+ /** Only the supervisor calls this after the final hibernated SQL receipt.
1073
+ * Hibernate pauses a durable room; it must not run game-ending onDispose. */
1074
+ releaseHibernated(): void;
1075
+ isFaulted(): boolean;
1076
+ commandCursor(): number;
1077
+ scheduleSnapshot(): ReadonlyArray<RoomScheduleSnapshot>;
1078
+ lastGoodSnapshot(): {
1079
+ readonly tick: number;
1080
+ readonly state: RoomState<(S)["Type"]>;
1081
+ };
1082
+ metrics(): RoomActorMetrics;
1083
+ }
1084
+
1085
+ declare interface RoomActorBotLease {
1086
+ readonly sessionId: string;
1087
+ isCurrent(): boolean;
1088
+ input(seq: number, tickHint: number, payload: unknown, encodedBytes: number): boolean;
1089
+ leave(signal?: AbortSignal): Promise<void>;
1090
+ }
1091
+
1092
+ declare interface RoomActorMetrics {
1093
+ readonly tick: number;
1094
+ readonly droppedTicks: number;
1095
+ readonly queuedInputs: number;
1096
+ readonly outboxCommands: number;
1097
+ readonly clients: number;
1098
+ readonly extensionDurationMs: Readonly<Record<string, number>>;
1099
+ readonly extensionOverruns: Readonly<Record<string, number>>;
1100
+ }
1101
+
1102
+ declare interface RoomActorRecovery {
1103
+ /** SQL ownership generation; a new owner must use a strictly newer epoch. */
1104
+ readonly epoch: number;
1105
+ readonly commandCursor: number;
1106
+ readonly tick?: number;
1107
+ readonly rehydrate?: boolean;
1108
+ readonly worldReceipts?: ReadonlyArray<RoomWorldReceipt> | undefined;
1109
+ readonly schedules?: ReadonlyArray<RoomScheduleSnapshot>;
1110
+ }
1111
+
1112
+ /** Commands are staged in memory and drained outside the tick. */
1113
+ declare interface RoomAppBridge {
1114
+ publish(event: string, payload: unknown, options: {
1115
+ readonly key: string;
1116
+ }): string;
1117
+ run(descriptor: string, input: unknown): string;
1118
+ }
1119
+
1120
+ declare interface RoomAuthoringStrategies<S = unknown> {
1121
+ readonly budgets?: (options: Readonly<Partial<RoomBudgets>>) => RoomBudgets;
1122
+ readonly reconnectPolicy?: (options: Readonly<Partial<{
1123
+ readonly graceMs: number;
1124
+ }>>) => {
1125
+ readonly graceMs: number;
1126
+ };
1127
+ readonly snapshotPolicy?: (options: Readonly<Partial<RoomSnapshotPolicy<S>>>) => RoomSnapshotPolicy<S>;
1128
+ readonly spectatorPolicy?: (options: Readonly<Partial<RoomSpectatorPolicy>>) => RoomSpectatorPolicy;
1129
+ }
1130
+
1131
+ declare interface RoomBudgets {
1132
+ readonly inputsPerSecond: number;
1133
+ readonly bytesPerSecond: number;
1134
+ readonly burst: number;
1135
+ readonly maxQueuedInputs: number;
1136
+ readonly maxOutboxCommands: number;
1137
+ readonly maxScheduledHooks: number;
1138
+ readonly maxQueuedLifecycleHooks: number;
1139
+ readonly maxNpcs: number;
1140
+ /** A player input acting on state older than this many milliseconds behind the newest state
1141
+ * the Host sent that client is dropped (it arrived too late to apply fairly). */
1142
+ readonly inputLatencyBudgetMs: number;
1143
+ }
1144
+
1145
+ declare interface RoomChannel {
1146
+ readonly schema: Schema.Codec<unknown, unknown>;
1147
+ readonly direction: 'both' | 'server' | 'client';
1148
+ readonly reliable: boolean;
1149
+ }
1150
+
1151
+ declare interface RoomCheckpoint {
1152
+ readonly requestId: string;
1153
+ readonly roomId: string;
1154
+ readonly tenantId: string;
1155
+ readonly epoch: number;
1156
+ readonly revision: number;
1157
+ readonly tick: number;
1158
+ readonly commandCursor: number;
1159
+ readonly bytes: Uint8Array;
1160
+ readonly schemaHash: number;
1161
+ readonly schedules: ReadonlyArray<RoomScheduleSnapshot>;
1162
+ readonly worldReceipts?: ReadonlyArray<RoomWorldReceipt> | undefined;
1163
+ readonly inputReceipts: ReadonlyArray<RoomInputReceipt>;
1164
+ readonly commands: ReadonlyArray<RoomOutboxCommand>;
1165
+ readonly publication?: 'held' | undefined;
1166
+ /** Earliest World epoch represented by an interrupted held adoption. */
1167
+ readonly worldRecoveryEpoch?: number | undefined;
1168
+ readonly disposition: 'live' | 'faulted' | 'disposed' | 'hibernating' | 'hibernated';
1169
+ /** The Room's own listing (`RoomDefinition.listing`), written to the directory with a live checkpoint. */
1170
+ readonly listing?: RoomListing | undefined;
1171
+ readonly snapshot?: {
1172
+ readonly mode: 'full' | 'delta';
1173
+ readonly fullEvery: number;
1174
+ readonly keepFulls: number;
1175
+ readonly store: 'auto';
1176
+ readonly maxInlineBytes: number;
1177
+ };
1178
+ }
1179
+
1180
+ /** Browser-safe service contracts. Server adapters and fixture Layers share
1181
+ * these exact Tags; imports of server-owned data shapes are erased types. */
1182
+ declare class RoomCheckpointPort extends RoomCheckpointPort_base {
1183
+ }
1184
+
1185
+ declare const RoomCheckpointPort_base: Context.ServiceClass<RoomCheckpointPort, "@voltro/RoomCheckpointPort", {
1186
+ commit(checkpoint: RoomCheckpoint): Effect.Effect<void, ProtocolError | RoomHibernatePending>;
1187
+ load(roomId: string, tenantId: string): Effect.Effect<RoomCheckpoint | null, ProtocolError>;
1188
+ pending(roomId: string, tenantId: string, limit: number): Effect.Effect<ReadonlyArray<RoomOutboxCommand>, ProtocolError>;
1189
+ acknowledge(roomId: string, tenantId: string, requestId: string): Effect.Effect<void, ProtocolError>;
1190
+ /** Optional: retire a command whose handler keeps failing (marked failed, no longer pending).
1191
+ * Without it, a failing command is retried on every turn. */
1192
+ readonly park?: (roomId: string, tenantId: string, requestId: string) => Effect.Effect<void, ProtocolError>;
1193
+ }>;
1194
+
1195
+ declare interface RoomClient {
1196
+ readonly sessionId: string;
1197
+ readonly subjectId: string | null;
1198
+ readonly tenantId: string;
1199
+ /** App data the API resolved for this seat (`seatAttributes` on the Rooms API binding), signed into
1200
+ * the seat; absent without one. Not a secret from the player: it travels in their seat token. */
1201
+ readonly attributes?: RoomSeatAttributes | undefined;
1202
+ /** Actor-owned classification, never accepted from a socket input. */
1203
+ readonly isBot?: boolean | undefined;
1204
+ readonly countsAsPlayer?: boolean | undefined;
1205
+ send(channel: string, payload: unknown): void;
1206
+ kick(reason: string): void;
1207
+ }
1208
+
1209
+ declare interface RoomClock {
1210
+ now(): number;
1211
+ }
1212
+
1213
+ declare interface RoomCodecLimits {
1214
+ readonly maxBytes: number;
1215
+ readonly maxCollectionLength: number;
1216
+ readonly maxFieldId: number;
1217
+ }
1218
+
1219
+ declare interface RoomConsumedSeat {
1220
+ readonly lastAppliedSeq: number;
1221
+ readonly discardedThrough?: number;
1222
+ readonly worldTarget?: WorldTargetSeatBinding;
1223
+ }
1224
+
1225
+ declare interface RoomDatagramLane {
1226
+ readonly maxDatagramBytes: number;
1227
+ send(frame: Uint8Array): void;
1228
+ onFrame(listener: (frame: Uint8Array, receivedAt: number) => void): () => void;
1229
+ }
1230
+
1231
+ declare interface RoomDefinition<S extends Schema.Codec<unknown, unknown>, I extends Schema.Codec<unknown, unknown>, O extends Schema.Codec<unknown, unknown>> {
1232
+ readonly name: string;
1233
+ readonly mode?: 'state-sync';
1234
+ readonly state: S;
1235
+ readonly auth?: 'subject' | 'public';
1236
+ readonly guards?: DeclaredAccess;
1237
+ readonly openAccess?: string | undefined;
1238
+ readonly input: I;
1239
+ readonly options: O;
1240
+ /** Author-owned initial state; no game values are guessed by the host. */
1241
+ readonly initialState?: (options: (O)["Type"]) => (S)["Type"];
1242
+ readonly tickRate?: number;
1243
+ readonly sendRate?: number;
1244
+ readonly maxClients?: number;
1245
+ readonly maxCatchUpTicks?: number;
1246
+ readonly lifecycleTimeoutMs?: number;
1247
+ readonly budgets?: Partial<RoomBudgets>;
1248
+ readonly strategies?: RoomAuthoringStrategies<(S)["Type"]> | undefined;
1249
+ readonly reconnect?: {
1250
+ readonly graceMs: number;
1251
+ };
1252
+ readonly autoDispose?: {
1253
+ readonly afterEmptyMs: number;
1254
+ readonly hibernate?: boolean;
1255
+ };
1256
+ readonly snapshot?: Partial<RoomSnapshotPolicy<(S)["Type"]>>;
1257
+ /** Opt-in shared history; host must supply the actual common view/admission. */
1258
+ readonly spectator?: Partial<RoomSpectatorPolicy> | undefined;
1259
+ readonly messages?: Readonly<Record<string, RoomChannel>>;
1260
+ readonly view?: (context: RoomViewContext<(S)["Type"]>) => (S)["Type"];
1261
+ readonly viewBudgetMs?: number;
1262
+ /** How the Room appears in `rooms.list`, derived from its state: `private` takes it off the list
1263
+ * (it stays joinable by ID), `locked` refuses every new seat, `metadata` is shown to listers.
1264
+ * Omitted fields keep their current value. The Host writes a change with the next checkpoint,
1265
+ * which a change triggers at once. Synchronous and pure, like `view`. */
1266
+ readonly listing?: (context: RoomListingContext<(S)["Type"], (O)["Type"]>) => RoomListing;
1267
+ readonly extensions?: ReadonlyArray<RoomExtension<(S)["Type"], (I)["Type"]>>;
1268
+ readonly world?: RoomWorldHooks<(S)["Type"]> | undefined;
1269
+ readonly onCreate?: RoomSyncHook<Omit<RoomMemberContext<(S)["Type"], (O)["Type"]>, 'client'>>;
1270
+ readonly onRehydrate?: RoomSyncHook<Omit<RoomMemberContext<(S)["Type"], (O)["Type"]>, 'client'>>;
1271
+ readonly onJoin?: RoomLifecycleHook<RoomMemberContext<(S)["Type"], (O)["Type"]>>;
1272
+ readonly onLeave?: RoomLifecycleHook<RoomMemberContext<(S)["Type"], (O)["Type"]> & {
1273
+ readonly reason: RoomLeaveReason;
1274
+ }>;
1275
+ readonly onTick: RoomSyncHook<RoomTickContext<(S)["Type"], (I)["Type"]>>;
1276
+ readonly onSchedule?: RoomSyncHook<RoomTickContext<(S)["Type"], (I)["Type"]> & {
1277
+ readonly label: string;
1278
+ }>;
1279
+ readonly onDispose?: RoomLifecycleHook<{
1280
+ readonly state: RoomState<(S)["Type"]> | undefined;
1281
+ readonly app: RoomAppBridge;
1282
+ readonly geometry?: GeometryWorldView;
1283
+ }> | undefined;
1284
+ }
1285
+
1286
+ declare interface RoomDescriptor<S extends Schema.Codec<unknown, unknown>, I extends Schema.Codec<unknown, unknown>, O extends Schema.Codec<unknown, unknown>> extends RoomDefinition<S, I, O> {
1287
+ readonly _tag: 'RoomDescriptor';
1288
+ readonly auth: 'subject' | 'public';
1289
+ readonly guards: DeclaredAccess;
1290
+ readonly tickRate: number;
1291
+ readonly sendRate: number;
1292
+ readonly maxClients: number;
1293
+ readonly maxCatchUpTicks: number;
1294
+ readonly lifecycleTimeoutMs: number;
1295
+ readonly budgets: RoomBudgets;
1296
+ readonly view: (context: RoomViewContext<(S)["Type"]>) => (S)["Type"];
1297
+ readonly reconnect: {
1298
+ readonly graceMs: number;
1299
+ };
1300
+ readonly autoDispose: {
1301
+ readonly afterEmptyMs: number;
1302
+ readonly hibernate: boolean;
1303
+ };
1304
+ readonly snapshot: RoomSnapshotPolicy<(S)["Type"]>;
1305
+ readonly spectator?: RoomSpectatorPolicy | undefined;
1306
+ readonly messages: Readonly<Record<string, RoomChannel>>;
1307
+ readonly viewBudgetMs: number;
1308
+ readonly extensions: ReadonlyArray<RoomExtension<(S)["Type"], (I)["Type"]>>;
1309
+ }
1310
+
1311
+ /** Exact last committed boundary supplied by the quiesced local owner. No client RPC. */
1312
+ declare type RoomDrainHandoff = RoomDrainRoom & ({
1313
+ readonly mode: 'state-sync';
1314
+ readonly revision: number;
1315
+ } | {
1316
+ readonly mode: 'lockstep';
1317
+ readonly admissionDigest: string;
1318
+ readonly journalDigest: string | null;
1319
+ });
1320
+
1321
+ declare interface RoomDrainRoom {
1322
+ readonly roomId: string;
1323
+ readonly tenantId: string;
1324
+ readonly epoch: number;
1325
+ readonly tick: number;
1326
+ }
1327
+
1328
+ declare interface RoomErasureInput {
1329
+ readonly roomId: string;
1330
+ readonly tenantId: string;
1331
+ /** The caller retains this identity across uncertain outcomes and restart. */
1332
+ readonly requestId: string;
1333
+ }
1334
+
1335
+ /** Whole selected room, not a subject-selection/export policy. */
1336
+ declare class RoomErasurePort extends RoomErasurePort_base {
1337
+ }
1338
+
1339
+ declare const RoomErasurePort_base: Context.ServiceClass<RoomErasurePort, "@voltro/RoomErasurePort", {
1340
+ erase(input: RoomErasureInput): Effect.Effect<void, ProtocolError>;
1341
+ }>;
1342
+
1343
+ declare interface RoomExtension<S, I> {
1344
+ readonly name: string;
1345
+ readonly fields: ReadonlyArray<Extract<keyof S, string>>;
1346
+ readonly channel: string;
1347
+ readonly tickBudgetMs: number;
1348
+ readonly beforeTick?: RoomSyncHook<RoomExtensionContext<S, I>>;
1349
+ readonly afterTick?: RoomSyncHook<RoomExtensionContext<S, I>>;
1350
+ }
1351
+
1352
+ declare interface RoomExtensionContext<S, I> {
1353
+ /** Prepared native CPU queries only, installed before actor lifecycle. */
1354
+ readonly geometry?: GeometryWorldView | undefined;
1355
+ readonly state: RoomState<Partial<S>>;
1356
+ readonly tick: number;
1357
+ readonly dt: number;
1358
+ readonly inputs: ReadonlyArray<Omit<RoomInput<I>, 'client'> & {
1359
+ readonly client: Pick<RoomClient, 'sessionId' | 'subjectId' | 'tenantId' | 'isBot' | 'countsAsPlayer' | 'attributes'>;
1360
+ }>;
1361
+ readonly clock: RoomClock;
1362
+ send(sessionId: string, payload: unknown): void;
1363
+ }
1364
+
1365
+ declare interface RoomFault {
1366
+ readonly roomId: string;
1367
+ readonly tick: number;
1368
+ readonly cause: unknown;
1369
+ /** Ownership is transferred to the supervisor for snapshot/drain/disposal. */
1370
+ readonly room: HostedRoom;
1371
+ }
1372
+
1373
+ declare class RoomForbidden extends RoomForbidden_base {
1374
+ }
1375
+
1376
+ declare const RoomForbidden_base: Schema.Class<RoomForbidden, Schema.TaggedStruct<"RoomForbidden", {
1377
+ readonly roomId: Schema.String;
1378
+ }>, YieldableError>;
1379
+
1380
+ declare type RoomFrame = RoomWorldHandoffFrame | {
1381
+ readonly kind: 'Hello';
1382
+ readonly protocolVersion: number;
1383
+ readonly token: Uint8Array;
1384
+ readonly schemaHash: number;
1385
+ readonly resumeFromTick?: number;
1386
+ readonly transportCaps: number;
1387
+ } | {
1388
+ readonly kind: 'Input';
1389
+ readonly firstSeq: number;
1390
+ readonly inputs: ReadonlyArray<{
1391
+ readonly tickHint: number;
1392
+ readonly payload: Uint8Array;
1393
+ }>;
1394
+ readonly ackTick?: number;
1395
+ }
1396
+ /** `lossPermille`: the client's estimated loss of state datagrams (0–1000), once it has one. */
1397
+ | {
1398
+ readonly kind: 'Ack';
1399
+ readonly tick: number;
1400
+ readonly lossPermille?: number;
1401
+ } | {
1402
+ readonly kind: 'Ping';
1403
+ readonly clientTimeMs: number;
1404
+ } | {
1405
+ readonly kind: 'ClientMessage' | 'ServerMessage';
1406
+ readonly channelId: number;
1407
+ readonly payload: Uint8Array;
1408
+ } | {
1409
+ readonly kind: 'Leave';
1410
+ readonly reason: number;
1411
+ } | {
1412
+ readonly kind: 'Welcome';
1413
+ readonly sessionId: string;
1414
+ readonly tick: number;
1415
+ readonly serverTimeMs: number;
1416
+ readonly epoch: number;
1417
+ readonly baseline: Uint8Array;
1418
+ readonly transformRules: Uint8Array;
1419
+ } | {
1420
+ readonly kind: 'Delta';
1421
+ readonly tick: number;
1422
+ readonly baseTick: number;
1423
+ readonly patch: Uint8Array;
1424
+ readonly inputAck?: RoomFrameInputReceipt;
1425
+ } | {
1426
+ readonly kind: 'Full';
1427
+ readonly tick: number;
1428
+ readonly epoch: number;
1429
+ readonly baseline: Uint8Array;
1430
+ readonly inputAck?: RoomFrameInputReceipt;
1431
+ } | {
1432
+ readonly kind: 'InputAck';
1433
+ readonly lastAppliedSeq: number;
1434
+ readonly tick: number;
1435
+ readonly flags: number;
1436
+ }
1437
+ /** `deltaDatagramsSent`: state deltas this Session sent as datagrams so far, for the client's loss estimate. */
1438
+ | {
1439
+ readonly kind: 'Pong';
1440
+ readonly clientTimeMs: number;
1441
+ readonly serverTimeMs: number;
1442
+ readonly tick: number;
1443
+ readonly deltaDatagramsSent?: number;
1444
+ } | {
1445
+ readonly kind: 'Kick';
1446
+ readonly code: number;
1447
+ readonly reason: string;
1448
+ } | {
1449
+ readonly kind: 'Migrate';
1450
+ readonly address?: string;
1451
+ readonly graceMs: number;
1452
+ } | {
1453
+ readonly kind: 'Error';
1454
+ readonly code: number;
1455
+ readonly detail: string;
1456
+ } | {
1457
+ readonly kind: 'LsInput';
1458
+ readonly firstTick: number;
1459
+ readonly inputs: ReadonlyArray<Uint8Array>;
1460
+ } | {
1461
+ readonly kind: 'LsInputs';
1462
+ readonly firstTick: number;
1463
+ readonly matrices: ReadonlyArray<RoomLockstepInputMatrix>;
1464
+ } | {
1465
+ readonly kind: 'LsHash';
1466
+ readonly tick: number;
1467
+ readonly hi: number;
1468
+ readonly lo: number;
1469
+ } | {
1470
+ readonly kind: 'LsDesync';
1471
+ readonly tick: number;
1472
+ readonly action: 'resync';
1473
+ readonly snapshot: Uint8Array;
1474
+ } | {
1475
+ readonly kind: 'LsDesync';
1476
+ readonly tick: number;
1477
+ readonly action: 'end' | 'flag';
1478
+ readonly snapshot?: never;
1479
+ } | {
1480
+ readonly kind: 'LsStart';
1481
+ readonly startTick: number;
1482
+ readonly seed: number;
1483
+ readonly options: Uint8Array;
1484
+ readonly serverTimeMs: number;
1485
+ readonly localPlayerId: number;
1486
+ readonly roster: ReadonlyArray<RoomLockstepWirePlayer>;
1487
+ readonly history?: Uint8Array;
1488
+ readonly snapshot?: Uint8Array;
1489
+ } | {
1490
+ readonly kind: 'LsStall';
1491
+ readonly waitingFor: RoomLockstepPlayerMask;
1492
+ }
1493
+ /** A player admitted after Start: from `tick` on, every matrix carries its `slot`. */
1494
+ | {
1495
+ readonly kind: 'LsJoin';
1496
+ readonly tick: number;
1497
+ readonly slot: number;
1498
+ readonly playerId: number;
1499
+ };
1500
+
1501
+ declare interface RoomFrameInputReceipt {
1502
+ readonly lastAppliedSeq: number;
1503
+ readonly flags: number;
1504
+ }
1505
+
1506
+ declare interface RoomGeometryOwnerScope {
1507
+ readonly roomId: string;
1508
+ readonly tenantId: string;
1509
+ readonly hostId: string;
1510
+ readonly epoch: number;
1511
+ readonly name: string;
1512
+ }
1513
+
1514
+ declare interface RoomGeometryResource {
1515
+ readonly scope: RoomGeometryOwnerScope;
1516
+ readonly world: AnyWorldDescriptor;
1517
+ readonly inventory: GeometryActorInventory;
1518
+ readonly view: GeometryWorldView;
1519
+ /** Trusted local unsubmitted discard; never a global rejection/SQL receipt. */
1520
+ /** Trusted visibility/source invalidation, queued for the actual Host pump. */
1521
+ invalidateStreams(): void;
1522
+ discardUnsubmitted(target: GeometryPrivacyTarget): Promise<boolean>;
1523
+ /** Writer lifetime only; actual SQL/reader/content erasure stays on the selected source. */
1524
+ withdrawSubject(target: GeometryPrivacyTarget): Promise<void>;
1525
+ eraseSubject(target: GeometryPrivacyTarget): Promise<void>;
1526
+ /** Outside-Tick SQL publication/refresh after the actual Room boundary. */
1527
+ synchronize(): Promise<void>;
1528
+ /** Fence and join both channel graphs without closing the native CPU frame.
1529
+ * Retired graphs stay retired; this alone never installs a new version. */
1530
+ quiesce(): Promise<void>;
1531
+ close(): Promise<void>;
1532
+ }
1533
+
1534
+ /** Durable work/capacity is still owned; this is backpressure, not completion. */
1535
+ declare class RoomHibernatePending extends RoomHibernatePending_base {
1536
+ }
1537
+
1538
+ declare const RoomHibernatePending_base: Schema.Class<RoomHibernatePending, Schema.TaggedStruct<"RoomHibernatePending", {
1539
+ readonly roomId: Schema.String;
1540
+ }>, YieldableError>;
1541
+
1542
+ /** Drives all rooms once per host turn; an author's throw cannot stop peers. */
1543
+ declare class RoomHost {
1544
+ readonly capacity: number;
1545
+ private readonly rooms;
1546
+ private readonly pendingFaults;
1547
+ private readonly retired;
1548
+ private faults;
1549
+ private ticks;
1550
+ private disposed;
1551
+ private advancing;
1552
+ constructor(capacity: number);
1553
+ add(room: HostedRoom): void;
1554
+ advance(eligible?: (roomId: string) => boolean): number;
1555
+ drainFaults(): ReadonlyArray<RoomFault>;
1556
+ takeRetired(): ReadonlyArray<HostedRoom>;
1557
+ /** A detached inventory for supervision, never available during advance. */
1558
+ activeRooms(): ReadonlyArray<HostedRoom>;
1559
+ /** A supervisor transfers one revoked owner without stopping its peers. */
1560
+ take(roomId: string): HostedRoom | null;
1561
+ /** Shutdown transfers ownership without dropping pending commands. */
1562
+ takeAll(): ReadonlyArray<HostedRoom>;
1563
+ drainOutbox(): ReadonlyArray<{
1564
+ readonly roomId: string;
1565
+ readonly command: RoomOutboxCommand;
1566
+ }>;
1567
+ private outsideTick;
1568
+ metrics(): RoomHostMetrics;
1569
+ dispose(): void;
1570
+ }
1571
+
1572
+ /** Rolling host tick occupancy. Monotonic milliseconds, never simulation time. */
1573
+ declare interface RoomHostLoopSnapshot {
1574
+ readonly from: number;
1575
+ readonly until: number;
1576
+ readonly coverage: 'warming-up' | 'complete' | 'invalid';
1577
+ readonly tickSeconds: number;
1578
+ readonly loopUtilization: number | null;
1579
+ /** Fraction of the same window the Node event loop was busy: ticks plus networking, encoding
1580
+ * and storage callbacks. What a host's CPU headroom follows; `null` while warming up. */
1581
+ readonly eventLoopUtilization: number | null;
1582
+ readonly clockErrors: number;
1583
+ }
1584
+
1585
+ declare interface RoomHostMetrics {
1586
+ readonly rooms: number;
1587
+ readonly clients: number;
1588
+ readonly ticks: number;
1589
+ readonly droppedTicks: number;
1590
+ readonly faults: number;
1591
+ }
1592
+
1593
+ declare interface RoomInput<I> {
1594
+ readonly client: RoomClient;
1595
+ readonly seq: number;
1596
+ readonly tickHint: number;
1597
+ readonly input: I;
1598
+ }
1599
+
1600
+ /** Captured outside the tick and stored with the exact state it describes. */
1601
+ declare interface RoomInputReceipt {
1602
+ readonly sessionId: string;
1603
+ readonly subjectId: string | null;
1604
+ readonly lastAppliedSeq: number;
1605
+ /** Intentionally discarded pending World input; never an applied ACK. */
1606
+ readonly discardedThrough?: number;
1607
+ }
1608
+
1609
+ declare type RoomLeaveReason = 'left' | 'kicked' | 'reconnecting' | 'timeout' | 'disposed';
1610
+
1611
+ /** Lifecycle Effects are run by the host outside the synchronous tick. `void` admits block bodies;
1612
+ * a returned Promise is refused at runtime with an authoring error. */
1613
+ declare type RoomLifecycleHook<C> = (context: C) => void | Effect.Effect<void, unknown>;
1614
+
1615
+ /** A Room's own listing; scalar metadata only, at most 16 keys and 2 KiB. */
1616
+ declare interface RoomListing {
1617
+ readonly metadata?: Readonly<Record<string, RoomScalar>>;
1618
+ readonly private?: boolean;
1619
+ readonly locked?: boolean;
1620
+ }
1621
+
1622
+ declare interface RoomListingContext<S, O> {
1623
+ readonly state: S;
1624
+ readonly options: O;
1625
+ }
1626
+
1627
+ export declare interface RoomLockstepAdmission {
1628
+ readonly version: 1;
1629
+ readonly roomId: string;
1630
+ readonly tenantId: string;
1631
+ readonly ownerEpoch: number;
1632
+ readonly hostId: string;
1633
+ readonly initial: {
1634
+ readonly requestId: string;
1635
+ readonly creatorSubjectId: string;
1636
+ readonly name: string;
1637
+ readonly seed: number;
1638
+ readonly options: string;
1639
+ readonly stateSchemaHash: number;
1640
+ readonly inputSchemaHash: number;
1641
+ };
1642
+ readonly adoption: {
1643
+ readonly requestId: string;
1644
+ readonly priorEpoch: number;
1645
+ } | null;
1646
+ readonly digest: string;
1647
+ }
1648
+
1649
+ export declare const roomLockstepAdmissionLayer: <S extends Schema.Codec<unknown, unknown>, I extends Schema.Codec<unknown, unknown>, O extends Schema.Codec<unknown, unknown>>(store: DataStore, descriptor: RoomLockstepDescriptor<S, I, O>, options: RoomLockstepAdmissionStoreOptions) => Layer.Layer<RoomLockstepAdmissionPort>;
1650
+
1651
+ /** Trusted complete outside-tick SQL creation capability, never a player state RPC. */
1652
+ export declare class RoomLockstepAdmissionPort extends RoomLockstepAdmissionPort_base {
1653
+ }
1654
+
1655
+ declare const RoomLockstepAdmissionPort_base: Context.ServiceClass<RoomLockstepAdmissionPort, "@voltro/RoomLockstepAdmissionPort", {
1656
+ prepare(input: RoomLockstepCreation): Effect.Effect<RoomLockstepAdmission, ProtocolError>;
1657
+ publish(scope: RoomLockstepRosterScope): Effect.Effect<RoomLockstepAdmission, ProtocolError>;
1658
+ load(scope: RoomLockstepRosterScope): Effect.Effect<RoomLockstepAdmission | null, ProtocolError>;
1659
+ adopt(scope: RoomLockstepRosterScope, priorEpoch: number, requestId: string): Effect.Effect<RoomLockstepAdmission, ProtocolError>;
1660
+ exportSubject(scope: RoomLockstepRosterScope, subjectId: string): Effect.Effect<RoomLockstepCreationExport | null, ProtocolError>;
1661
+ erase(scope: RoomLockstepRosterScope, requestId: string): Effect.Effect<void, ProtocolError>;
1662
+ }>;
1663
+
1664
+ export declare interface RoomLockstepAdmissionStoreOptions {
1665
+ readonly hostId: string;
1666
+ readonly epochNow: () => number;
1667
+ readonly authorize: (scope: RoomLockstepRosterScope, operation: 'prepare' | 'publish' | 'load' | 'adopt' | 'export' | 'erase', subjectId?: string) => Effect.Effect<void, unknown>;
1668
+ readonly erasure: Context.Service.Shape<typeof RoomErasurePort>;
1669
+ readonly maxAdmissionBytes?: number;
1670
+ }
1671
+
1672
+ export declare interface RoomLockstepAuthorityRebuild<S extends Schema.Codec<unknown, unknown>, I extends Schema.Codec<unknown, unknown>, O extends Schema.Codec<unknown, unknown>> {
1673
+ readonly server: RoomLockstepServer<S, I, O>;
1674
+ readonly scope: RoomLockstepRosterScope;
1675
+ readonly journalDigest: string;
1676
+ readonly replayedTicks: number;
1677
+ readonly inputBytes: number;
1678
+ }
1679
+
1680
+ export declare interface RoomLockstepAuthorityRebuildOptions extends RoomLockstepJournalRebuildOptions {
1681
+ /** Actual newly/currently welcomed Sessions, explicitly paired with retained IDs. */
1682
+ readonly players: ReadonlyArray<{
1683
+ readonly playerId: number;
1684
+ readonly actualSession: unknown;
1685
+ }>;
1686
+ readonly serverOptions?: RoomLockstepServerOptions;
1687
+ }
1688
+
1689
+ export declare interface RoomLockstepCreation extends RoomLockstepRosterScope {
1690
+ readonly requestId: string;
1691
+ readonly creatorSubjectId: string;
1692
+ readonly seed: number;
1693
+ readonly options: unknown;
1694
+ }
1695
+
1696
+ export declare interface RoomLockstepCreationExport {
1697
+ readonly roomId: string;
1698
+ readonly name: string;
1699
+ readonly requestId: string;
1700
+ readonly seed: number;
1701
+ readonly stateSchemaHash: number;
1702
+ readonly inputSchemaHash: number;
1703
+ }
1704
+
1705
+ declare interface RoomLockstepDefinition<S extends Schema.Codec<unknown, unknown>, I extends Schema.Codec<unknown, unknown>, O extends Schema.Codec<unknown, unknown>> {
1706
+ readonly name: string;
1707
+ readonly mode: 'lockstep';
1708
+ readonly simulation: Simulation<S, I, O>;
1709
+ readonly lockstep?: RoomLockstepOptions<I> | undefined;
1710
+ readonly guards?: DeclaredAccess;
1711
+ readonly openAccess?: string | undefined;
1712
+ readonly auth?: 'subject';
1713
+ readonly tickRate?: number;
1714
+ readonly maxCatchUpTicks?: number;
1715
+ readonly lifecycleTimeoutMs?: number;
1716
+ readonly budgets?: Partial<RoomBudgets>;
1717
+ readonly reconnect?: {
1718
+ readonly graceMs: number;
1719
+ };
1720
+ readonly strategies?: Pick<RoomAuthoringStrategies, 'reconnectPolicy'> | undefined;
1721
+ readonly messages?: Readonly<Record<string, RoomChannel>>;
1722
+ readonly onMessage?: (context: RoomLockstepMessageContext) => undefined;
1723
+ }
1724
+
1725
+ declare interface RoomLockstepDescriptor<S extends Schema.Codec<unknown, unknown>, I extends Schema.Codec<unknown, unknown>, O extends Schema.Codec<unknown, unknown>> extends RoomLockstepDefinition<S, I, O> {
1726
+ readonly _tag: 'RoomDescriptor';
1727
+ /** Lockstep rooms never join a World; declared so mixed descriptor reads narrow on it. */
1728
+ readonly world?: undefined;
1729
+ readonly auth: 'subject';
1730
+ readonly state: S;
1731
+ readonly input: I;
1732
+ readonly options: O;
1733
+ readonly guards: DeclaredAccess;
1734
+ readonly tickRate: number;
1735
+ readonly maxCatchUpTicks: number;
1736
+ readonly lifecycleTimeoutMs: number;
1737
+ readonly maxClients: number;
1738
+ readonly budgets: RoomBudgets;
1739
+ readonly reconnect: {
1740
+ readonly graceMs: number;
1741
+ };
1742
+ readonly messages: Readonly<Record<string, RoomChannel>>;
1743
+ readonly lockstep: RoomLockstepOptions<I> & {
1744
+ readonly inputSchema: I;
1745
+ readonly inputDelayTicks: number;
1746
+ readonly rollbackHorizonTicks: number;
1747
+ readonly inputPrediction: LockstepInputPrediction<(I)["Type"]>;
1748
+ readonly maxPlayers: number;
1749
+ };
1750
+ /** State-sync lifecycle/spectators are never manufactured for a lockstep declaration. */
1751
+ readonly initialState?: never;
1752
+ readonly spectator?: never | undefined;
1753
+ }
1754
+
1755
+ export declare interface RoomLockstepDesync {
1756
+ readonly tick: number;
1757
+ readonly playerId: number;
1758
+ readonly expected: Uint64Words;
1759
+ readonly received: Uint64Words;
1760
+ }
1761
+
1762
+ export declare type RoomLockstepHashResult<S, I = unknown> = {
1763
+ readonly _tag: 'pending' | 'duplicate' | 'expired' | 'match';
1764
+ readonly tick: number;
1765
+ readonly playerId: number;
1766
+ } | {
1767
+ readonly _tag: 'desync';
1768
+ readonly incident: RoomLockstepDesync;
1769
+ readonly action: 'end' | 'flag';
1770
+ } | {
1771
+ readonly _tag: 'desync';
1772
+ readonly incident: RoomLockstepDesync;
1773
+ readonly action: 'resync';
1774
+ readonly snapshot: SimulationSnapshot<S>;
1775
+ readonly inputs: ReadonlyArray<SimulationPlayerInput<I>>;
1776
+ readonly continuation: ReadonlyArray<SimulationTickInputs<I>>;
1777
+ };
1778
+
1779
+ export declare type RoomLockstepHostDelivery<I> = Extract<RoomLockstepServerAdvance<I>, {
1780
+ readonly _tag: 'relayed';
1781
+ }> | Extract<LockstepStallDecision, {
1782
+ readonly _tag: 'action';
1783
+ }>;
1784
+
1785
+ /** Actual existing RoomHost HostedRoom consumer. Explicit owner drives one pure
1786
+ * role and retains delivery records for outside-tick transfer. This is no normal
1787
+ * SQL/Session Room-mode factory, native send, timer or borrowed-session disposer. */
1788
+ export declare class RoomLockstepHostLoop<S extends Schema.Codec<unknown, unknown>, I extends Schema.Codec<unknown, unknown>, O extends Schema.Codec<unknown, unknown>> implements HostedRoom {
1789
+ #private;
1790
+ readonly id: string;
1791
+ constructor(simulation: Simulation<S, I, O>, seed: number, options: (O)["Type"], scope: RoomLockstepRosterScope, now: () => number, serverOptions?: RoomLockstepServerOptions, offered?: RoomLockstepHostLoopOptions);
1792
+ private outside;
1793
+ private operation;
1794
+ private live;
1795
+ private clock;
1796
+ admit(playerId: number, actualSession: unknown): RoomLockstepRosterPlayer;
1797
+ rebind(actualSession: unknown): RoomLockstepRosterPlayer;
1798
+ seal(): readonly RoomLockstepRosterPlayer[];
1799
+ admitAt(player: RoomLockstepRosterPlayer, actualSession: unknown): RoomLockstepRosterPlayer;
1800
+ /** Late join after Start; the caller has journaled the join for `fromTick`. */
1801
+ join(player: RoomLockstepRosterPlayer, actualSession: unknown, fromTick: number): RoomLockstepRosterPlayer;
1802
+ /** Tick of the last complete matrix (the confirmed input frontier). */
1803
+ get inputTick(): number;
1804
+ /** Trusted pre-delivery rebuild over the same genuine sealed Sessions. Input
1805
+ * authority and referee lag use existing role paths, never a state snapshot. */
1806
+ replayMatrix(tick: number, sessions: ReadonlyArray<unknown>, payloads: ReadonlyArray<Uint8Array>): void;
1807
+ finishBootstrap(): void;
1808
+ submit(actualSession: unknown, firstTick: number, payloads: ReadonlyArray<Uint8Array>): RoomLockstepInputSubmission;
1809
+ submitHash(actualSession: unknown, tick: number, hash: Uint64Words): RoomLockstepHashResult<S["Type"], I["Type"]>;
1810
+ comparePendingHashes(maxClaims?: number): readonly RoomLockstepHashResult<S["Type"], I["Type"]>[];
1811
+ recovery(): SimulationRecovery<S["Type"], I["Type"]>;
1812
+ get serverRole(): RoomLockstepServerRole;
1813
+ advance(): number;
1814
+ drainDeliveries(): ReadonlyArray<RoomLockstepHostDelivery<(I)["Type"]>>;
1815
+ /** Outside-tick preparation may fail; retain the exact record until accepted. */
1816
+ nextDelivery(): RoomLockstepHostDelivery<(I)["Type"]> | null;
1817
+ consumeDelivery(expected: RoomLockstepHostDelivery<(I)["Type"]>): void;
1818
+ /** Only after the real supervisor takes this faulted owner and resolves its
1819
+ * delivery/author failure. No new actor or replayed SQL side effect. */
1820
+ retryFault(): void;
1821
+ drainOutbox(): ReadonlyArray<RoomOutboxCommand>;
1822
+ metrics(): RoomActorMetrics;
1823
+ roleMetrics(): Readonly<{
1824
+ observedTicks: number;
1825
+ faulted: boolean;
1826
+ pendingDeliveries: number;
1827
+ pendingInputRecordBytes: number;
1828
+ role: RoomLockstepServerRole;
1829
+ tick: number;
1830
+ refereeTick: number | null;
1831
+ withdrawn: boolean;
1832
+ refereeLagTicks: number;
1833
+ stallAfterTicks: number;
1834
+ stallAction: "pause" | "drop-player";
1835
+ players: number;
1836
+ pendingInputs: number;
1837
+ pendingInputBytes: number;
1838
+ queuedInputs: number;
1839
+ queuedTicks: number;
1840
+ queuedInputBytes: number;
1841
+ pendingHashes: number;
1842
+ retainedReplayTicks: number;
1843
+ retainedReplayInputBytes: number;
1844
+ comparedHashes: number;
1845
+ desyncs: number;
1846
+ }>;
1847
+ exportSubject(tenantId: string, subjectId: string): RoomLockstepSubjectExport<I["Type"]>;
1848
+ eraseSubject(tenantId: string, subjectId: string): number;
1849
+ dispose(): void;
1850
+ isDisposed(): boolean;
1851
+ }
1852
+
1853
+ export declare interface RoomLockstepHostLoopOptions {
1854
+ readonly tickRate?: number;
1855
+ readonly maxCatchUpTicks?: number;
1856
+ readonly maxPendingDeliveries?: number;
1857
+ readonly maxPendingInputRecordBytes?: number;
1858
+ }
1859
+
1860
+ declare interface RoomLockstepInitialPlayerContext extends RoomLockstepInitialRosterContext {
1861
+ /** Server-private current admitted identity, never projected to the roster wire. */
1862
+ readonly subjectId: string;
1863
+ readonly sessionId: string;
1864
+ }
1865
+
1866
+ declare interface RoomLockstepInitialRosterContext extends RoomLockstepRosterScope {
1867
+ readonly maxPlayers: number;
1868
+ readonly players: ReadonlyArray<RoomLockstepRosterPlayer>;
1869
+ }
1870
+
1871
+ declare interface RoomLockstepInitialStrategies {
1872
+ readonly playerId: (context: RoomLockstepInitialPlayerContext) => number;
1873
+ readonly start: (context: RoomLockstepInitialRosterContext) => boolean;
1874
+ }
1875
+
1876
+ declare interface RoomLockstepInputMatrix {
1877
+ readonly players: RoomLockstepPlayerMask;
1878
+ readonly inputs: ReadonlyArray<Uint8Array>;
1879
+ }
1880
+
1881
+ /** Server-only actor-memory input roster. Actual normal Seat/SQL/Welcome session
1882
+ * ownership is borrowed and rechecked; no new reservation or structural identity.
1883
+ * Host invokes this after its real connection/frame budgets. No transport listener,
1884
+ * store/read/write, timer, worker, signing material or default boot is acquired. */
1885
+ export declare class RoomLockstepInputRoster<I extends Schema.Codec<unknown, unknown>> {
1886
+ #private;
1887
+ constructor(schema: I, scope: RoomLockstepRosterScope, options?: RoomLockstepRosterOptions);
1888
+ get tick(): number;
1889
+ get sealed(): boolean;
1890
+ metrics(): {
1891
+ readonly pendingInputs: number;
1892
+ readonly pendingBytes: number;
1893
+ readonly players: number;
1894
+ };
1895
+ private work;
1896
+ admit(playerId: number, session: unknown): RoomLockstepRosterPlayer;
1897
+ /** Trusted server rebuild can retain a SQL-selected sparse slot; actual Session
1898
+ * scope/layout/uniqueness remain the same admission contract. */
1899
+ admitAt(player: RoomLockstepRosterPlayer, session: unknown): RoomLockstepRosterPlayer;
1900
+ /** Same-owner reconnect replaces a withdrawn genuine admission only. The
1901
+ * stable player/slot and all already accepted pending input bytes survive. */
1902
+ rebind(actualSession: unknown): RoomLockstepRosterPlayer;
1903
+ seal(): ReadonlyArray<RoomLockstepRosterPlayer>;
1904
+ /** Late join after seal: the player's input is part of every matrix from `fromTick`, which
1905
+ * must lie ahead of the consumed frontier so no delivered matrix changes. */
1906
+ join(player: RoomLockstepRosterPlayer, session: unknown, fromTick: number): RoomLockstepRosterPlayer;
1907
+ /** Slots whose input a tick's matrix carries, in slot order (the wire matrix order). */
1908
+ private activeAt;
1909
+ submit(session: unknown, firstTick: number, payloads: ReadonlyArray<Uint8Array>): RoomLockstepInputSubmission;
1910
+ next(): RoomLockstepTickInputs<(I)["Type"]>;
1911
+ consumeNext(): RoomLockstepTickInputs<(I)["Type"]>;
1912
+ eraseSubject(tenantId: string, subjectId: string): number;
1913
+ exportSubject(tenantId: string, subjectId: string): ReadonlyArray<{
1914
+ readonly tick: number;
1915
+ readonly playerId: number;
1916
+ readonly input: (I)["Type"];
1917
+ }>;
1918
+ /** Current actual Session-to-player lookup; no client-selected identity. */
1919
+ playerForSession(session: unknown): RoomLockstepRosterPlayer;
1920
+ playersForSubject(tenantId: string, subjectId: string): ReadonlyArray<RoomLockstepRosterPlayer>;
1921
+ /** Actor-memory withdrawal only. Borrowed sessions remain caller-owned. */
1922
+ withdraw(): void;
1923
+ private privacyScope;
1924
+ private current;
1925
+ private admitOwned;
1926
+ private sealOwned;
1927
+ /** Caller passes its actual constructed Session, never a client-chosen slot. */
1928
+ private submitOwned;
1929
+ private nextOwned;
1930
+ /** Consume only a complete current matrix. Referee/snapshot/replay ownership
1931
+ * must stage its own successful step before calling; no durable ACK here. */
1932
+ private consumeNextOwned;
1933
+ private removeSlot;
1934
+ /** Outside-tick privacy seam; actual Rooms erase orchestration must call it. */
1935
+ private eraseSubjectOwned;
1936
+ private exportSubjectOwned;
1937
+ }
1938
+
1939
+ export declare interface RoomLockstepInputSubmission {
1940
+ readonly accepted: number;
1941
+ readonly duplicates: number;
1942
+ readonly expired: number;
1943
+ }
1944
+
1945
+ export declare interface RoomLockstepJournal {
1946
+ /** 1: Start roster only. 2: adds `joins`; every tick's matrix covers the roster at that tick. */
1947
+ readonly version: 1 | 2;
1948
+ readonly roomId: string;
1949
+ readonly tenantId: string;
1950
+ readonly ownerEpoch: number;
1951
+ readonly hostId: string;
1952
+ readonly initial: {
1953
+ readonly requestId: string;
1954
+ readonly seed: number;
1955
+ readonly options: string;
1956
+ readonly stateSchemaHash: number;
1957
+ readonly inputSchemaHash: number;
1958
+ readonly players: ReadonlyArray<{
1959
+ readonly slot: number;
1960
+ readonly playerId: number;
1961
+ readonly subjectId: string;
1962
+ readonly sessionId: string;
1963
+ }>;
1964
+ };
1965
+ readonly adoption: {
1966
+ readonly requestId: string;
1967
+ readonly priorEpoch: number;
1968
+ } | null;
1969
+ readonly ticks: ReadonlyArray<{
1970
+ readonly tick: number;
1971
+ readonly requestId: string;
1972
+ readonly inputs: ReadonlyArray<string>;
1973
+ }>;
1974
+ readonly joins?: ReadonlyArray<RoomLockstepJournalJoin>;
1975
+ readonly digest: string;
1976
+ }
1977
+
1978
+ export declare interface RoomLockstepJournalAppend extends RoomLockstepRosterScope {
1979
+ readonly requestId: string;
1980
+ readonly tick: number;
1981
+ readonly inputs: ReadonlyArray<Uint8Array>;
1982
+ }
1983
+
1984
+ /** A player admitted after Start (late join), effective from `tick`. Version 2 journals only. */
1985
+ declare interface RoomLockstepJournalJoin {
1986
+ readonly tick: number;
1987
+ readonly requestId: string;
1988
+ readonly slot: number;
1989
+ readonly playerId: number;
1990
+ readonly subjectId: string;
1991
+ readonly sessionId: string;
1992
+ }
1993
+
1994
+ /** Admit a player after Start, effective from `tick` (ahead of every committed matrix). */
1995
+ declare interface RoomLockstepJournalJoinInput extends RoomLockstepRosterScope {
1996
+ readonly requestId: string;
1997
+ readonly tick: number;
1998
+ readonly player: RoomLockstepJournalPlayer;
1999
+ }
2000
+
2001
+ export declare const roomLockstepJournalLayer: <S extends Schema.Codec<unknown, unknown>, I extends Schema.Codec<unknown, unknown>, O extends Schema.Codec<unknown, unknown>>(store: DataStore, simulation: Simulation<S, I, O>, options: RoomLockstepJournalStoreOptions) => Layer.Layer<RoomLockstepJournalPort>;
2002
+
2003
+ declare interface RoomLockstepJournalPlayer {
2004
+ readonly slot: number;
2005
+ readonly playerId: number;
2006
+ readonly actualSession: unknown;
2007
+ }
2008
+
2009
+ /** Trusted server capability, not a player RPC or inspection authority. */
2010
+ export declare class RoomLockstepJournalPort extends RoomLockstepJournalPort_base {
2011
+ }
2012
+
2013
+ declare const RoomLockstepJournalPort_base: Context.ServiceClass<RoomLockstepJournalPort, "@voltro/RoomLockstepJournalPort", {
2014
+ initialize(input: RoomLockstepJournalStart): Effect.Effect<RoomLockstepJournal, ProtocolError>;
2015
+ append(input: RoomLockstepJournalAppend): Effect.Effect<RoomLockstepJournal, ProtocolError>;
2016
+ /** Late join (version-2 journal). Optional: a journal without it refuses late players. */
2017
+ readonly join?: (input: RoomLockstepJournalJoinInput) => Effect.Effect<RoomLockstepJournal, ProtocolError>;
2018
+ load(scope: RoomLockstepRosterScope): Effect.Effect<RoomLockstepJournal | null, ProtocolError>;
2019
+ adopt(scope: RoomLockstepRosterScope, priorEpoch: number, requestId: string): Effect.Effect<RoomLockstepJournal, ProtocolError>;
2020
+ exportSubject(scope: RoomLockstepRosterScope, subjectId: string): Effect.Effect<RoomLockstepJournalSubjectExport, ProtocolError>;
2021
+ erase(scope: RoomLockstepRosterScope, requestId: string): Effect.Effect<void, ProtocolError>;
2022
+ }>;
2023
+
2024
+ export declare interface RoomLockstepJournalRebuild<S, O> {
2025
+ readonly scope: RoomLockstepRosterScope;
2026
+ readonly seed: number;
2027
+ readonly options: O;
2028
+ readonly players: ReadonlyArray<{
2029
+ readonly slot: number;
2030
+ readonly playerId: number;
2031
+ readonly subjectId: string;
2032
+ readonly sessionId: string;
2033
+ }>;
2034
+ readonly journalDigest: string;
2035
+ readonly replayedTicks: number;
2036
+ readonly inputBytes: number;
2037
+ readonly snapshot: SimulationSnapshot<S>;
2038
+ }
2039
+
2040
+ export declare interface RoomLockstepJournalRebuildOptions {
2041
+ readonly hostId: string;
2042
+ readonly maxTicks?: number;
2043
+ readonly maxJournalBytes?: number;
2044
+ readonly maxInputBytes?: number;
2045
+ readonly maxPlayers?: number;
2046
+ readonly maxRejectionAttempts?: number;
2047
+ }
2048
+
2049
+ export declare interface RoomLockstepJournalStart extends RoomLockstepRosterScope {
2050
+ readonly requestId: string;
2051
+ readonly seed: number;
2052
+ readonly options: unknown;
2053
+ readonly players: ReadonlyArray<RoomLockstepJournalPlayer>;
2054
+ }
2055
+
2056
+ export declare interface RoomLockstepJournalStoreOptions {
2057
+ readonly hostId: string;
2058
+ readonly epochNow: () => number;
2059
+ readonly authorize: (scope: RoomLockstepRosterScope, operation: 'initialize' | 'append' | 'join' | 'load' | 'adopt' | 'export' | 'erase', subjectId?: string) => Effect.Effect<void, unknown>;
2060
+ readonly erasure: Context.Service.Shape<typeof RoomErasurePort>;
2061
+ readonly maxTicks?: number;
2062
+ readonly maxJournalBytes?: number;
2063
+ readonly maxPlayers?: number;
2064
+ }
2065
+
2066
+ export declare interface RoomLockstepJournalSubjectExport {
2067
+ readonly roomId: string;
2068
+ readonly inputs: ReadonlyArray<{
2069
+ readonly tick: number;
2070
+ readonly playerId: number;
2071
+ readonly input: unknown;
2072
+ }>;
2073
+ }
2074
+
2075
+ export declare interface RoomLockstepMemberIdentity {
2076
+ readonly sessionId: string;
2077
+ readonly subjectId: string;
2078
+ readonly tenantId: string;
2079
+ }
2080
+
2081
+ export declare interface RoomLockstepMemberOptions {
2082
+ readonly name: string;
2083
+ readonly maxClients?: number;
2084
+ readonly budgets?: Partial<RoomBudgets>;
2085
+ readonly messages?: Readonly<Record<string, RoomChannel>>;
2086
+ /** Admit new Sessions after the roster is sealed (the Room declares late join). */
2087
+ readonly lateJoin?: boolean;
2088
+ }
2089
+
2090
+ /** Real Session membership without simulation state/init/step or actor lifecycle.
2091
+ * Seat verification/consume/disconnect remain the existing Session's SQL work. */
2092
+ export declare class RoomLockstepMemberOwner<S extends Schema.Codec<unknown, unknown>, I extends Schema.Codec<unknown, unknown>, O extends Schema.Codec<unknown, unknown>> {
2093
+ #private;
2094
+ readonly id: string;
2095
+ readonly tenantId: string;
2096
+ readonly epoch: number;
2097
+ readonly descriptor: {
2098
+ readonly name: string;
2099
+ readonly state: S;
2100
+ readonly input: I;
2101
+ readonly auth: 'subject';
2102
+ readonly budgets: RoomBudgets;
2103
+ readonly maxClients: number;
2104
+ readonly messages: Readonly<Record<string, RoomChannel>>;
2105
+ };
2106
+ constructor(simulation: Simulation<S, I, O>, scope: RoomLockstepRosterScope, offered: RoomLockstepMemberOptions);
2107
+ isDisposed(): boolean;
2108
+ isFaulted(): boolean;
2109
+ isRetiring(): boolean;
2110
+ private live;
2111
+ joinReservedAsync(offered: RoomClient, consumed: RoomConsumedSeat, signal?: AbortSignal): Promise<void>;
2112
+ leaveAsync(sessionId: string, _reason?: RoomLeaveReason): Promise<void>;
2113
+ /** First activation captures the genuine complete roster. Later activation can
2114
+ * restore only the same retained Seat/Subject, never extend a sealed game. */
2115
+ seal(): void;
2116
+ isCurrent(sessionId: string, subjectId: string | null): boolean;
2117
+ roster(): ReadonlyArray<RoomLockstepMemberIdentity>;
2118
+ exportSubject(tenantId: string, subjectId: string): ReadonlyArray<RoomLockstepMemberIdentity>;
2119
+ eraseSubject(tenantId: string, subjectId: string): number;
2120
+ /** Pure immediate admission withdrawal; containing host joins native resources. */
2121
+ withdraw(): void;
2122
+ disposeAsync(): Promise<void>;
2123
+ }
2124
+
2125
+ declare interface RoomLockstepMessageContext {
2126
+ readonly roomId: string;
2127
+ readonly tenantId: string;
2128
+ readonly epoch: number;
2129
+ readonly client: {
2130
+ readonly sessionId: string;
2131
+ readonly subjectId: string;
2132
+ readonly tenantId: string;
2133
+ };
2134
+ readonly channel: string;
2135
+ readonly payload: unknown;
2136
+ /** Stage an ephemeral reply to the same current native Session. */
2137
+ reply(channel: string, payload: unknown): void;
2138
+ /** Stage an ephemeral message to the currently activated player Sessions. */
2139
+ broadcast(channel: string, payload: unknown): void;
2140
+ }
2141
+
2142
+ declare interface RoomLockstepOptions<I extends Schema.Codec<unknown, unknown>> extends RoomLockstepServerOptions {
2143
+ readonly inputSchema?: I;
2144
+ readonly inputDelayTicks?: number;
2145
+ readonly rollbackHorizonTicks?: number;
2146
+ readonly inputPrediction?: LockstepInputPrediction<(I)["Type"]>;
2147
+ /** Admit players after Start (late join). Each joins at a tick chosen by the Host, ahead of
2148
+ * the confirmed frontier by the input delay; every simulation sees it at that tick. */
2149
+ readonly lateJoin?: boolean;
2150
+ }
2151
+
2152
+ /** Declared lockstep composition over real pre-seat metadata and genuine Sessions.
2153
+ * Implements the existing HostedRoom seam. SQL, encoding and native work occur
2154
+ * only in create/start/flush/close supervision, never in advance. */
2155
+ export declare class RoomLockstepOwnedRoom<S extends Schema.Codec<unknown, unknown>, I extends Schema.Codec<unknown, unknown>, O extends Schema.Codec<unknown, unknown>> implements HostedRoom {
2156
+ #private;
2157
+ readonly id: string;
2158
+ readonly tenantId: string;
2159
+ readonly hostId: string;
2160
+ readonly epoch: number;
2161
+ readonly descriptor: RoomLockstepDescriptor<S, I, O>;
2162
+ private constructor();
2163
+ static create<S extends Schema.Codec<unknown, unknown>, I extends Schema.Codec<unknown, unknown>, O extends Schema.Codec<unknown, unknown>>(offeredDescriptor: RoomLockstepDescriptor<S, I, O>, offered: RoomLockstepCreation, provided: RoomLockstepOwnedRoomDependencies): Promise<RoomLockstepOwnedRoom<S, I, O>>;
2164
+ /** Install only the actual retained successor metadata. Native admission and
2165
+ * publication remain fenced until real roster/input bootstrap is bound. */
2166
+ static restore<S extends Schema.Codec<unknown, unknown>, I extends Schema.Codec<unknown, unknown>, O extends Schema.Codec<unknown, unknown>>(offeredDescriptor: RoomLockstepDescriptor<S, I, O>, offeredScope: RoomLockstepRosterScope, offeredTruth: RoomLockstepRecoveryTruth, provided: RoomLockstepOwnedRoomDependencies): Promise<RoomLockstepOwnedRoom<S, I, O>>;
2167
+ private static build;
2168
+ /** Called only after successful installation in the containing Host/Runtime. SQL
2169
+ * publication and its exact current receipt are required before native transfer. */
2170
+ publishAsync(): Promise<void>;
2171
+ /** Server-private staged truth grants no wire/native input admission. */
2172
+ recoveryTruth(): RoomLockstepRecoveryTruth | null;
2173
+ rosterOpen(): boolean;
2174
+ isPublished(): boolean;
2175
+ private outside;
2176
+ private live;
2177
+ private admitWork;
2178
+ /** On success this owner takes the actual Session/native close lifetime. */
2179
+ connect(transport: RoomTransport): RoomServerSession<S, I, O>;
2180
+ /** Server chooses opaque player IDs only for current genuine owned Sessions. */
2181
+ admit(playerId: number, actualSession: RoomServerSession<S, I, O>): RoomLockstepRosterPlayer;
2182
+ roster(): ReadonlyArray<RoomLockstepRosterPlayer>;
2183
+ /** Normal supervision: only actual current Welcomed owned Sessions can be bound.
2184
+ * A retained durable Start attempt retries exactly without rerunning strategies. */
2185
+ prepareInitialRoster(offered?: Partial<RoomLockstepInitialStrategies>): Promise<ReadonlyArray<RoomLockstepRosterPlayer>>;
2186
+ startAsync(): Promise<ReadonlyArray<RoomLockstepRosterPlayer>>;
2187
+ private startAccepted;
2188
+ advance(): number;
2189
+ private messageTargets;
2190
+ private captureMessage;
2191
+ private admitMessages;
2192
+ /** Non-authoritative app supervision, never simulation input or SQL truth. */
2193
+ broadcast(channel: string, payload: unknown): void;
2194
+ private receiveMessage;
2195
+ private flushMessages;
2196
+ messageMetrics(): {
2197
+ readonly pendingCommands: number;
2198
+ readonly pendingBytes: number;
2199
+ };
2200
+ flush(): Promise<{
2201
+ readonly writes: number;
2202
+ readonly pending: boolean;
2203
+ }>;
2204
+ private flushAccepted;
2205
+ private releaseSession;
2206
+ /** Outside-tick cleanup; a failed close retains the exact owned Session. */
2207
+ maintenance(): Promise<void>;
2208
+ metrics(): Readonly<{
2209
+ clients: number;
2210
+ tick: number;
2211
+ droppedTicks: number;
2212
+ queuedInputs: number;
2213
+ outboxCommands: number;
2214
+ extensionDurationMs: Readonly<Record<string, number>>;
2215
+ extensionOverruns: Readonly<Record<string, number>>;
2216
+ }>;
2217
+ /** One bounded flush pass per attempt. Retain exact native/journal retries;
2218
+ * never advance simulation or invent a state-sync checkpoint for Lockstep. */
2219
+ prepareDrain(): Promise<RoomDrainHandoff>;
2220
+ transportMetrics(): Readonly<{
2221
+ started: boolean;
2222
+ disposed: boolean;
2223
+ pendingWireBytes: number;
2224
+ pendingTargets: number;
2225
+ redundancyTicks: number;
2226
+ redundancyWireBytes: number;
2227
+ pendingHashResults: number;
2228
+ pendingHashSources: number;
2229
+ reconnecting: boolean;
2230
+ joining: boolean;
2231
+ queuedFrames: number;
2232
+ flushing: boolean;
2233
+ journaled: boolean;
2234
+ journalTick: number;
2235
+ initializing: boolean;
2236
+ observedTicks: number;
2237
+ faulted: boolean;
2238
+ pendingDeliveries: number;
2239
+ pendingInputRecordBytes: number;
2240
+ role: RoomLockstepServerRole;
2241
+ tick: number;
2242
+ refereeTick: number | null;
2243
+ withdrawn: boolean;
2244
+ refereeLagTicks: number;
2245
+ stallAfterTicks: number;
2246
+ stallAction: "pause" | "drop-player";
2247
+ players: number;
2248
+ pendingInputs: number;
2249
+ pendingInputBytes: number;
2250
+ queuedInputs: number;
2251
+ queuedTicks: number;
2252
+ queuedInputBytes: number;
2253
+ pendingHashes: number;
2254
+ retainedReplayTicks: number;
2255
+ retainedReplayInputBytes: number;
2256
+ comparedHashes: number;
2257
+ desyncs: number;
2258
+ }>;
2259
+ drainOutbox(): readonly RoomOutboxCommand[];
2260
+ isDisposed(): boolean;
2261
+ dispose(): void;
2262
+ /** revoked=true is trusted supervision after real SQL fencing. SQL/native
2263
+ * failures remain failures; borrowed SQL services/resources are never closed. */
2264
+ disposeAsync(revoked?: boolean): Promise<void>;
2265
+ }
2266
+
2267
+ export declare interface RoomLockstepOwnedRoomDependencies {
2268
+ /** Host scheduling policy only; does not change simulation or journal identity. */
2269
+ readonly maxCatchUpTicks?: number;
2270
+ readonly hostId: string;
2271
+ readonly admission: Context.Service.Shape<typeof RoomLockstepAdmissionPort>;
2272
+ readonly journal: Context.Service.Shape<typeof RoomLockstepJournalPort>;
2273
+ readonly runEffect: RoomSnapshotEffectRunner;
2274
+ readonly clock: RoomClock;
2275
+ readonly seats: RoomSeatAdmission;
2276
+ readonly sessionOptions: Omit<RoomServerSessionOptions, 'epoch' | 'onClientMessage' | 'spectatorHistory'>;
2277
+ readonly transport?: Omit<RoomLockstepTransportOptions, 'journal'> | undefined;
2278
+ }
2279
+
2280
+ /** Bits identify server-assigned roster slots 0..63, not Subject or player IDs. */
2281
+ declare type RoomLockstepPlayerMask = Uint64Words;
2282
+
2283
+ declare interface RoomLockstepRecoveryTruth {
2284
+ readonly admission: RoomLockstepAdmission;
2285
+ readonly journal: RoomLockstepJournal | null;
2286
+ readonly options: unknown;
2287
+ }
2288
+
2289
+ export declare interface RoomLockstepReplay<S, I, O> {
2290
+ readonly seed: number;
2291
+ readonly options: O;
2292
+ readonly base: SimulationSnapshot<S>;
2293
+ readonly inputs: ReadonlyArray<{
2294
+ readonly tick: number;
2295
+ readonly inputs: ReadonlyArray<SimulationPlayerInput<I>>;
2296
+ readonly hash: Uint64Words;
2297
+ }>;
2298
+ /** The matrix used at the base tick (absent at tick 0), so a `join` hook replays exactly. */
2299
+ readonly baseInputs?: ReadonlyArray<SimulationPlayerInput<I>>;
2300
+ }
2301
+
2302
+ export declare interface RoomLockstepRosterOptions {
2303
+ readonly initialTick?: number;
2304
+ readonly maxPlayers?: number;
2305
+ readonly maxFutureTicks?: number;
2306
+ readonly maxBatchInputs?: number;
2307
+ readonly maxPendingInputs?: number;
2308
+ readonly maxPendingBytes?: number | undefined;
2309
+ }
2310
+
2311
+ export declare interface RoomLockstepRosterPlayer {
2312
+ readonly slot: number;
2313
+ readonly playerId: number;
2314
+ }
2315
+
2316
+ export declare interface RoomLockstepRosterScope {
2317
+ readonly roomId: string;
2318
+ readonly tenantId: string;
2319
+ readonly epoch: number;
2320
+ }
2321
+
2322
+ /** Explicit CPU-only server role owner over genuine current Seat/Welcome input
2323
+ * admission. Host drives advance and delayed pump. No scheduler, listener,
2324
+ * SQL/HotStore command, sanction write or Room-mode/default boot installation. */
2325
+ export declare class RoomLockstepServer<S extends Schema.Codec<unknown, unknown>, I extends Schema.Codec<unknown, unknown>, O extends Schema.Codec<unknown, unknown>> {
2326
+ #private;
2327
+ constructor(simulation: Simulation<S, I, O>, seed: number, options: (O)["Type"], scope: RoomLockstepRosterScope, offered?: RoomLockstepServerOptions);
2328
+ get role(): RoomLockstepServerRole;
2329
+ get tick(): number;
2330
+ get refereeTick(): number | null;
2331
+ get withdrawn(): boolean;
2332
+ private work;
2333
+ admit(playerId: number, actualSession: unknown): RoomLockstepRosterPlayer;
2334
+ admitAt(player: RoomLockstepRosterPlayer, actualSession: unknown): RoomLockstepRosterPlayer;
2335
+ rebind(actualSession: unknown): RoomLockstepRosterPlayer;
2336
+ seal(): ReadonlyArray<RoomLockstepRosterPlayer>;
2337
+ /** Late join: the referee sees the player's input from `fromTick` on. */
2338
+ join(player: RoomLockstepRosterPlayer, actualSession: unknown, fromTick: number): RoomLockstepRosterPlayer;
2339
+ playerForSession(actualSession: unknown): RoomLockstepRosterPlayer;
2340
+ submit(actualSession: unknown, firstTick: number, payloads: ReadonlyArray<Uint8Array>): RoomLockstepInputSubmission;
2341
+ private copyInputs;
2342
+ /** Input authority is independent of referee execution. Prepare all authored
2343
+ * captures/encoding/budgets before consuming a genuine complete matrix. */
2344
+ advance(maxInputRecordBytes?: number): RoomLockstepServerAdvance<(I)["Type"]>;
2345
+ /** Bounded delayed referee work; each successful tick commits separately.
2346
+ * Failed step retains that exact queued tick and original RNG for retry. */
2347
+ pumpReferee(maxSteps?: number): {
2348
+ readonly steps: number;
2349
+ readonly tick: number;
2350
+ };
2351
+ /** Host supplies its actual monotonically observed logical tick, not a
2352
+ * client timestamp or wall clock. Repeated polls do not increase stall age. */
2353
+ observeStall(observationTick: number): LockstepStallDecision | {
2354
+ readonly _tag: 'ready' | 'empty';
2355
+ readonly tick: number;
2356
+ };
2357
+ snapshot(): SimulationSnapshot<(S)["Type"]>;
2358
+ /** Actual current referee state and contiguous authority, also used by desync.
2359
+ * No client hash claim is manufactured for ordinary bootstrap. */
2360
+ recovery(): SimulationRecovery<(S)["Type"], (I)["Type"]>;
2361
+ private recoveryOwned;
2362
+ private incident;
2363
+ private currentPlayer;
2364
+ submitHash(actualSession: unknown, tick: number, offered: Uint64Words): RoomLockstepHashResult<(S)["Type"], (I)["Type"]>;
2365
+ /** Separate bounded comparison pass. Incident publication/sanction writes and
2366
+ * resync encoding/delivery belong outside this CPU-only owner. */
2367
+ comparePendingHashes(maxClaims?: number): ReadonlyArray<RoomLockstepHashResult<(S)["Type"], (I)["Type"]>>;
2368
+ replay(): RoomLockstepReplay<(S)["Type"], (I)["Type"], (O)["Type"]>;
2369
+ private copySnapshot;
2370
+ exportSubject(tenantId: string, subjectId: string): RoomLockstepSubjectExport<(I)["Type"]>;
2371
+ /** Shared state cannot be safely scrubbed by deleting one field. If this
2372
+ * subject participates, withdraw and release every private simulation/replay/
2373
+ * pending claim/input reference. Real host must join workers/transport/SQL. */
2374
+ eraseSubject(tenantId: string, subjectId: string): number;
2375
+ withdraw(): void;
2376
+ private withdrawOwned;
2377
+ metrics(): Readonly<{
2378
+ role: RoomLockstepServerRole;
2379
+ tick: number;
2380
+ refereeTick: number | null;
2381
+ withdrawn: boolean;
2382
+ refereeLagTicks: number;
2383
+ stallAfterTicks: number;
2384
+ stallAction: "pause" | "drop-player";
2385
+ players: number;
2386
+ pendingInputs: number;
2387
+ pendingInputBytes: number;
2388
+ queuedInputs: number;
2389
+ queuedTicks: number;
2390
+ queuedInputBytes: number;
2391
+ pendingHashes: number;
2392
+ retainedReplayTicks: number;
2393
+ retainedReplayInputBytes: number;
2394
+ comparedHashes: number;
2395
+ desyncs: number;
2396
+ }>;
2397
+ }
2398
+
2399
+ export declare type RoomLockstepServerAdvance<I> = {
2400
+ readonly _tag: 'relayed';
2401
+ readonly tick: number;
2402
+ readonly inputRecordBytes: number;
2403
+ readonly players: RoomLockstepPlayerMask;
2404
+ readonly inputs: ReadonlyArray<SimulationPlayerInput<I>>;
2405
+ } | {
2406
+ readonly _tag: 'waiting';
2407
+ readonly tick: number;
2408
+ readonly waitingFor: RoomLockstepPlayerMask;
2409
+ } | {
2410
+ readonly _tag: 'empty';
2411
+ readonly tick: number;
2412
+ };
2413
+
2414
+ export declare interface RoomLockstepServerOptions extends Omit<RoomLockstepRosterOptions, 'initialTick'> {
2415
+ readonly strategies?: LockstepPolicyStrategies | undefined;
2416
+ readonly stallPolicy?: LockstepStallPolicyOptions;
2417
+ readonly serverRole?: RoomLockstepServerRole;
2418
+ readonly refereeLagTicks?: number;
2419
+ readonly hashEvery?: number;
2420
+ readonly hashHistoryTicks?: number;
2421
+ readonly maxQueuedTicks?: number;
2422
+ readonly maxQueuedInputBytes?: number;
2423
+ readonly maxPendingHashes?: number;
2424
+ readonly maxRefereeSteps?: number;
2425
+ readonly maxReplayTicks?: number;
2426
+ readonly maxReplayInputBytes?: number;
2427
+ readonly maxSnapshotBudgetBytes?: number;
2428
+ readonly maxRejectionAttempts?: number;
2429
+ readonly onDesync?: 'resync' | 'end' | 'flag' | ((incident: RoomLockstepDesync) => 'resync' | 'end' | 'flag');
2430
+ }
2431
+
2432
+ export declare type RoomLockstepServerRole = 'relay' | 'referee' | 'full';
2433
+
2434
+ export declare interface RoomLockstepSubjectExport<I> {
2435
+ readonly inputs: ReadonlyArray<{
2436
+ readonly tick: number;
2437
+ readonly playerId: number;
2438
+ readonly input: I;
2439
+ }>;
2440
+ readonly hashClaims: ReadonlyArray<{
2441
+ readonly tick: number;
2442
+ readonly playerId: number;
2443
+ readonly hash: Uint64Words;
2444
+ }>;
2445
+ }
2446
+
2447
+ export declare interface RoomLockstepTerminal extends RoomLockstepRosterScope {
2448
+ readonly disposition: 'faulted' | 'disposed';
2449
+ }
2450
+
2451
+ export declare const roomLockstepTerminalLayer: <S extends Schema.Codec<unknown, unknown>, I extends Schema.Codec<unknown, unknown>, O extends Schema.Codec<unknown, unknown>>(store: DataStore, descriptor: RoomLockstepDescriptor<S, I, O>, options: RoomLockstepTerminalStoreOptions) => Layer.Layer<RoomLockstepTerminalPort, never, never>;
2452
+
2453
+ /** Outside-tick lifecycle commit after actual Session/native withdrawal. Retains
2454
+ * SQL creation and input truth; this is neither a checkpoint nor an erase. */
2455
+ export declare class RoomLockstepTerminalPort extends RoomLockstepTerminalPort_base {
2456
+ }
2457
+
2458
+ declare const RoomLockstepTerminalPort_base: Context.ServiceClass<RoomLockstepTerminalPort, "@voltro/RoomLockstepTerminalPort", {
2459
+ terminate(input: RoomLockstepTerminal): Effect.Effect<RoomLockstepTerminalReceipt, ProtocolError>;
2460
+ }>;
2461
+
2462
+ export declare interface RoomLockstepTerminalReceipt extends RoomLockstepTerminal {
2463
+ readonly hostId: string;
2464
+ }
2465
+
2466
+ export declare interface RoomLockstepTerminalStoreOptions {
2467
+ readonly hostId: string;
2468
+ readonly epochNow: () => number;
2469
+ readonly authorize: (input: RoomLockstepTerminal) => Effect.Effect<void, unknown>;
2470
+ }
2471
+
2472
+ export declare type RoomLockstepTickInputs<I> = {
2473
+ readonly _tag: 'complete';
2474
+ readonly tick: number;
2475
+ readonly players: RoomLockstepPlayerMask;
2476
+ readonly inputs: ReadonlyArray<SimulationPlayerInput<I>>;
2477
+ } | {
2478
+ readonly _tag: 'waiting';
2479
+ readonly tick: number;
2480
+ readonly waitingFor: RoomLockstepPlayerMask;
2481
+ } | {
2482
+ readonly _tag: 'empty';
2483
+ readonly tick: number;
2484
+ };
2485
+
2486
+ export declare interface RoomLockstepTransportJournal {
2487
+ readonly service: Context.Service.Shape<typeof RoomLockstepJournalPort>;
2488
+ readonly runEffect: RoomSnapshotEffectRunner;
2489
+ readonly startRequestId: string;
2490
+ }
2491
+
2492
+ declare interface RoomLockstepTransportLimits {
2493
+ readonly redundantTicks?: number;
2494
+ readonly maxFlushWork?: number;
2495
+ readonly maxPendingWireBytes?: number;
2496
+ readonly maxRedundancyWireBytes?: number;
2497
+ readonly maxPendingHashResults?: number;
2498
+ }
2499
+
2500
+ export declare interface RoomLockstepTransportOptions extends RoomLockstepTransportLimits {
2501
+ readonly journal?: RoomLockstepTransportJournal;
2502
+ }
2503
+
2504
+ /** Explicit supervised bridge over genuine SQL/Seat/Welcome Sessions. Owns the
2505
+ * actual HostedRoom loop; all encoding/writes happen in flush(), outside advance.
2506
+ * Normal defineRoom/runtime mode selection and the lockstep client are separate. */
2507
+ export declare class RoomLockstepTransportOwner<S extends Schema.Codec<unknown, unknown>, I extends Schema.Codec<unknown, unknown>, O extends Schema.Codec<unknown, unknown>> implements HostedRoom {
2508
+ #private;
2509
+ readonly id: string;
2510
+ constructor(simulation: Simulation<S, I, O>, seed: number, options: (O)["Type"], scope: RoomLockstepRosterScope, now: () => number, serverOptions?: RoomLockstepServerOptions, loopOptions?: RoomLockstepHostLoopOptions, offered?: RoomLockstepTransportOptions);
2511
+ private live;
2512
+ private operation;
2513
+ private current;
2514
+ private deliverable;
2515
+ private frameBytes;
2516
+ admit(playerId: number, actualSession: unknown): RoomLockstepRosterPlayer;
2517
+ /** Actual canonical successor truth, staged before any native admission. */
2518
+ stageRecovery(saved: RoomLockstepJournal): void;
2519
+ admitRecovered(actualSession: unknown): RoomLockstepRosterPlayer;
2520
+ /** Reconnect uses current SQL truth and a new actual Welcome. The running
2521
+ * authority is retained; only its withdrawn Session capability is replaced. */
2522
+ rebindAsync(actualSession: unknown): Promise<RoomLockstepRosterPlayer>;
2523
+ private inputHistory;
2524
+ /** Joins journaled ahead of the frontier: a bootstrapped Session learns them as LsJoin frames. */
2525
+ private futureJoins;
2526
+ /** One current producer for genuine same-owner and elected-successor Start.
2527
+ * Actual authority/input state is read only in outside-tick supervision. */
2528
+ private bootstrap;
2529
+ /** Queues LsStart; the explicit outside-tick flush must complete its writes. */
2530
+ start(): ReadonlyArray<RoomLockstepRosterPlayer>;
2531
+ private queueStart;
2532
+ /** Durable start retains the exact roster/request across unknown commit replies.
2533
+ * No seal, simulation tick, binding or LsStart before a captured SQL receipt. */
2534
+ startAsync(): Promise<ReadonlyArray<RoomLockstepRosterPlayer>>;
2535
+ private startRecovered;
2536
+ /** Whether a Session belongs to a retained player (reconnect) rather than a new one. */
2537
+ retains(actualSession: unknown): boolean;
2538
+ /** A late join can start now: durable frontier confirmed, nothing in flight, and a snapshot
2539
+ * bootstrap (referee/full) does not straddle an earlier join. */
2540
+ lateJoinReady(): boolean;
2541
+ /** Late join: journal the player for `frontier + leadTicks`, then bootstrap it (Start at the
2542
+ * frontier, earlier joins in its history or snapshot) and announce it to every Session before
2543
+ * any matrix of that tick. Needs a fully confirmed durable frontier, like reconnect. */
2544
+ joinAsync(actualSession: unknown, playerId: number, leadTicks: number): Promise<RoomLockstepRosterPlayer>;
2545
+ private runJournal;
2546
+ private receive;
2547
+ advance(): number;
2548
+ private prepareNext;
2549
+ private commitPrepared;
2550
+ /** Actual tracked reliable completions, one bounded pass. Retry retains exactly
2551
+ * the failed target/frame; fulfilled targets are never resent by a retry. */
2552
+ flush(): Promise<{
2553
+ readonly writes: number;
2554
+ readonly pending: boolean;
2555
+ }>;
2556
+ retryFault(): void;
2557
+ drainOutbox(): ReadonlyArray<RoomOutboxCommand>;
2558
+ metrics(): RoomActorMetrics;
2559
+ /** Local retained durable frontier, only after accepted supervision drained.
2560
+ * The containing owner must compare it with a fresh actual SQL load. */
2561
+ journalBoundary(): {
2562
+ readonly digest: string | null;
2563
+ readonly tick: number;
2564
+ };
2565
+ transportMetrics(): Readonly<{
2566
+ started: boolean;
2567
+ disposed: boolean;
2568
+ pendingWireBytes: number;
2569
+ pendingTargets: number;
2570
+ redundancyTicks: number;
2571
+ redundancyWireBytes: number;
2572
+ pendingHashResults: number;
2573
+ pendingHashSources: number;
2574
+ reconnecting: boolean;
2575
+ joining: boolean;
2576
+ queuedFrames: number;
2577
+ flushing: boolean;
2578
+ journaled: boolean;
2579
+ journalTick: number;
2580
+ initializing: boolean;
2581
+ observedTicks: number;
2582
+ faulted: boolean;
2583
+ pendingDeliveries: number;
2584
+ pendingInputRecordBytes: number;
2585
+ role: RoomLockstepServerRole;
2586
+ tick: number;
2587
+ refereeTick: number | null;
2588
+ withdrawn: boolean;
2589
+ refereeLagTicks: number;
2590
+ stallAfterTicks: number;
2591
+ stallAction: "pause" | "drop-player";
2592
+ players: number;
2593
+ pendingInputs: number;
2594
+ pendingInputBytes: number;
2595
+ queuedInputs: number;
2596
+ queuedTicks: number;
2597
+ queuedInputBytes: number;
2598
+ pendingHashes: number;
2599
+ retainedReplayTicks: number;
2600
+ retainedReplayInputBytes: number;
2601
+ comparedHashes: number;
2602
+ desyncs: number;
2603
+ }>;
2604
+ exportSubject(tenantId: string, subjectId: string): RoomLockstepSubjectExport<I["Type"]>;
2605
+ eraseSubject(tenantId: string, subjectId: string): Promise<number>;
2606
+ private release;
2607
+ dispose(): void;
2608
+ /** Joins this owner's real in-flight delivery. Borrowed Sessions/SQL/native
2609
+ * transport close still belong to the containing host. Rejections stay red. */
2610
+ disposeAsync(): Promise<void>;
2611
+ isDisposed(): boolean;
2612
+ }
2613
+
2614
+ /** Public opaque simulation identities, never Subjects or Session credentials. */
2615
+ declare interface RoomLockstepWirePlayer {
2616
+ readonly slot: number;
2617
+ readonly playerId: number;
2618
+ }
2619
+
2620
+ declare interface RoomMemberContext<S, O> {
2621
+ /** Prepared native CPU queries only, installed before actor lifecycle. */
2622
+ readonly geometry?: GeometryWorldView | undefined;
2623
+ readonly state: RoomState<S>;
2624
+ readonly options: O;
2625
+ readonly client: RoomClient;
2626
+ readonly app: RoomAppBridge;
2627
+ readonly clock: RoomClock;
2628
+ readonly scheduler: RoomScheduler;
2629
+ /** World Rooms, ordinary player join: the server-owned entity this Session controls and
2630
+ * its last persisted `persistEntity` data. Build the state entity from it when absent. */
2631
+ readonly world?: RoomWorldMember | undefined;
2632
+ }
2633
+
2634
+ declare interface RoomOutboxCommand {
2635
+ readonly requestId: string;
2636
+ readonly kind: 'publish' | 'run';
2637
+ readonly name: string;
2638
+ readonly payload: unknown;
2639
+ readonly key?: string;
2640
+ }
2641
+
2642
+ declare interface RoomPoolRuntimeDefaults {
2643
+ /** Maximum state-sync catch-up ticks per host turn; never changes simulation Hz. */
2644
+ readonly maxCatchUpTicks: number;
2645
+ readonly snapshotEveryMs: number;
2646
+ readonly hibernate: boolean;
2647
+ }
2648
+
2649
+ declare interface RoomReliableLane {
2650
+ send(frame: Uint8Array): Promise<void>;
2651
+ onFrame(listener: (frame: Uint8Array, receivedAt: number) => void): () => void;
2652
+ }
2653
+
2654
+ declare interface RoomReplayLimits {
2655
+ readonly maxBytes: number;
2656
+ readonly maxFrameBytes: number;
2657
+ readonly maxFrames: number;
2658
+ readonly maxHighlights: number;
2659
+ readonly maxSchemaBytes: number;
2660
+ readonly maxDurationMs: number;
2661
+ readonly checkpointEveryMs: number;
2662
+ }
2663
+
2664
+ /** Browser-safe trusted server contract. No player mutation or storage adapter
2665
+ * is imported at value level; replacement services use this exact Tag. */
2666
+ declare class RoomReplayPort extends RoomReplayPort_base {
2667
+ }
2668
+
2669
+ declare const RoomReplayPort_base: Context.ServiceClass<RoomReplayPort, "@voltro/RoomReplayPort", {
2670
+ publish(input: RoomReplayPublish): Effect.Effect<RoomStoredReplay, ProtocolError>;
2671
+ load(scope: RoomReplayScope): Effect.Effect<Uint8Array, ProtocolError>;
2672
+ erase(scope: RoomReplayScope, requestId: string): Effect.Effect<void, ProtocolError>;
2673
+ expire(scope: RoomReplayScope, requestId: string): Effect.Effect<void, ProtocolError>;
2674
+ subjectRooms(request: PluginPrivacyRequest): Effect.Effect<ReadonlyArray<string>, ProtocolError>;
2675
+ eraseSubject(request: PluginPrivacyRequest): Effect.Effect<void, ProtocolError>;
2676
+ exportSubject(request: PluginPrivacyRequest, roomId?: string): Effect.Effect<ReadonlyArray<RoomStoredReplay>, ProtocolError>;
2677
+ }>;
2678
+
2679
+ declare type RoomReplayPublicationMetadata = Omit<RoomReplayPublish, 'bytes'>;
2680
+
2681
+ declare interface RoomReplayPublish extends RoomReplayScope {
2682
+ readonly roomId: string;
2683
+ readonly roomName: string;
2684
+ readonly matchId: string;
2685
+ readonly participants: ReadonlyArray<string>;
2686
+ readonly visibility: 'private' | 'unlisted' | 'public';
2687
+ readonly expiresAtMs: number | null;
2688
+ readonly bytes: Uint8Array;
2689
+ }
2690
+
2691
+ declare interface RoomReplayRecordingBinding {
2692
+ readonly port: Context.Service.Shape<typeof RoomReplayPort>;
2693
+ readonly metadata: RoomReplayPublicationMetadata;
2694
+ /** Actual app Effect runtime/ConfigProvider; never open another runtime. */
2695
+ readonly runEffect: RoomSnapshotEffectRunner;
2696
+ readonly limits?: Partial<RoomReplayLimits>;
2697
+ }
2698
+
2699
+ declare interface RoomReplayScope {
2700
+ readonly tenantId: string;
2701
+ readonly replayId: string;
2702
+ }
2703
+
2704
+ /** One host driver composes the actual actor and binary server session. There
2705
+ * are no autonomous actor timers. Its caller owns cadence and shutdown; each
2706
+ * turn is synchronous simulation followed by awaited checkpoint I/O. */
2707
+ export declare class RoomRuntime {
2708
+ readonly capacity: number;
2709
+ readonly clock: RoomClock;
2710
+ private readonly checkpoints;
2711
+ readonly host: RoomHost;
2712
+ private readonly loopObservation;
2713
+ private readonly rooms;
2714
+ private readonly pending;
2715
+ private readonly heldPublication;
2716
+ private readonly terminal;
2717
+ private readonly withdrawn;
2718
+ private readonly drains;
2719
+ private readonly migrationNotified;
2720
+ private turning;
2721
+ private closed;
2722
+ private checkpointCommits;
2723
+ private checkpointStateBytes;
2724
+ private unchangedSnapshotsSkipped;
2725
+ private readonly poolDefaults;
2726
+ private readonly snapshotBudget;
2727
+ private lastPeriodicRoom;
2728
+ constructor(capacity: number, clock: RoomClock, checkpoints: Context.Service.Shape<typeof RoomCheckpointPort>, options?: RoomRuntimeSnapshotOptions);
2729
+ create<S extends Schema.Codec<unknown, unknown>, I extends Schema.Codec<unknown, unknown>, O extends Schema.Codec<unknown, unknown>>(id: string, tenantId: string, descriptor: RoomDescriptor<S, I, O>, options: unknown, epoch: number, admission: RoomSeatAdmission, sessionOptions: RoomRuntimeSessionOptions): RoomActor<S, I, O>;
2730
+ add<S extends Schema.Codec<unknown, unknown>, I extends Schema.Codec<unknown, unknown>, O extends Schema.Codec<unknown, unknown>>(id: string, tenantId: string, descriptor: RoomDescriptor<S, I, O>, state: (S)["Type"], options: (O)["Type"], recovery: RoomActorRecovery & {
2731
+ readonly revision: number;
2732
+ readonly publicationHeld?: boolean;
2733
+ readonly worldRecoveryEpoch?: number | undefined;
2734
+ }, admission: RoomSeatAdmission, sessionOptions: RoomRuntimeSessionOptions): RoomActor<S, I, O>;
2735
+ activateWorldMembers(roomId: string, tenantId: string, epoch: number, binding: WorldTargetSeatBinding, authorize: () => Promise<void>): Promise<void>;
2736
+ /** One actor draft and receipt replacement; caller persists the result. */
2737
+ replaceWorldGhostProjection(roomId: string, tenantId: string, input: RoomWorldHookInput, previous: RoomWorldHookInput, maxBytes: number, authorize: () => Promise<void>): Promise<void>;
2738
+ cancelWorldGhost(roomId: string, tenantId: string, input: RoomWorldHookInput, maxBytes: number, authorize: () => Promise<void>): Promise<void>;
2739
+ cancelWorldPreview(roomId: string, tenantId: string, epoch: number, requestId: string, authorize: () => Promise<void>): Promise<void>;
2740
+ previewWorldEnter(roomId: string, tenantId: string, input: RoomWorldHookInput, maxBytes: number, signal?: AbortSignal): Promise<void>;
2741
+ /** Await bounded real authentication/lifecycle work before privileged Session
2742
+ * withdrawal; an in-flight Hello must not escape by lacking a published id. */
2743
+ settleSessions(roomId: string, tenantId: string, epoch: number): Promise<void>;
2744
+ /** False while the actor runs lifecycle work (join, leave, World hooks); receipt reads wait. */
2745
+ worldLifecycleQuiet(roomId: string): boolean;
2746
+ worldReceiptSnapshot(roomId: string, tenantId: string, epoch: number): ReadonlyArray<RoomWorldReceipt>;
2747
+ retireWorldReceipt(roomId: string, tenantId: string, epoch: number, requestId: string, operation: 'enter' | 'exit' | 'ghost'): Promise<void>;
2748
+ /** Trusted lifecycle mutation only. Controller callers persist its state and
2749
+ * receipt before acknowledging; this method alone grants no SQL ownership. */
2750
+ hasWorldReceipt(roomId: string, tenantId: string, epoch: number, requestId: string, operation: 'enter' | 'exit' | 'ghost'): boolean;
2751
+ applyWorldHook(roomId: string, tenantId: string, operation: 'enter' | 'exit' | 'ghost', input: RoomWorldHookInput, maxBytes: number, signal?: AbortSignal, authorizeCommit?: () => Promise<void>, replaceExitReceipt?: boolean, previousGhost?: RoomWorldHookInput, retainGhostProjection?: boolean, promoteGhosts?: ReadonlyArray<RoomWorldHookInput>): Promise<void>;
2752
+ finalizeWorldExit(roomId: string, tenantId: string, input: RoomWorldExitInput, maxBytes: number, retain: (capture: {
2753
+ readonly entity: unknown;
2754
+ readonly data: unknown;
2755
+ }) => Promise<void>, authorize: () => Promise<void>, expectedEntity?: unknown, signal?: AbortSignal): Promise<void>;
2756
+ worldFinalizationAfterglow(roomId: string, tenantId: string, epoch: number): RoomWorldExitInput['afterglow'];
2757
+ worldFinalizationRequest(roomId: string, tenantId: string, epoch: number): string | null;
2758
+ notifyWorldHandoff(roomId: string, tenantId: string, input: Omit<RoomWorldHandoffFrame, 'tick'>, authorize: () => Promise<void>): Promise<void>;
2759
+ completeWorldFinalization(roomId: string, tenantId: string, epoch: number, requestId: string, authorize: () => Promise<void>): Promise<void>;
2760
+ reconcileWorldSource(roomId: string, tenantId: string, input: RoomWorldHookInput & {
2761
+ readonly requestId: string;
2762
+ }, maxBytes: number, authorize: () => Promise<void>, signal?: AbortSignal): Promise<void>;
2763
+ /** Actual owned actor capture under the same exclusion as a host turn.
2764
+ * This reads no replacement entity payload and grants no transition permission. */
2765
+ configureWorldCellMovement(roomId: string, tenantId: string, epoch: number, bounds?: WorldBounds, marginUnits?: number): Promise<void>;
2766
+ captureWorldMovement(roomId: string, tenantId: string, epoch: number): Promise<WorldMovementObservation>;
2767
+ worldMovementSnapshot(roomId: string, tenantId: string, epoch: number): {
2768
+ readonly bound: boolean;
2769
+ readonly clamped: number;
2770
+ };
2771
+ listWorldEntityIds(roomId: string, tenantId: string, epoch: number, maximum: number, maxBytes: number): Promise<ReadonlyArray<string>>;
2772
+ captureWorldProjection(roomId: string, tenantId: string, epoch: number, entityId: string, maxBytes: number): Promise<{
2773
+ readonly entity: unknown;
2774
+ readonly data: unknown;
2775
+ readonly tick: number;
2776
+ }>;
2777
+ captureWorldEntity(roomId: string, tenantId: string, epoch: number, entityId: string, maxBytes: number): Promise<{
2778
+ readonly entity: unknown;
2779
+ readonly data: unknown;
2780
+ }>;
2781
+ /** Actual geometry resource only, before/after the CPU turn. No absent-room
2782
+ * SQL acquisition; a synchronization failure retains publication for retry. */
2783
+ synchronizeGeometry(roomId: string): Promise<void>;
2784
+ /** Trusted outside-Tick drain. Holds the same exclusion as a Host turn,
2785
+ * joins both accepted graphs and leaves the native CPU inventory readable.
2786
+ * Failure retains fences and exact cleanup; no version/reopen is implied. */
2787
+ quiesceGeometry(roomId: string): Promise<void>;
2788
+ /** Trusted confirmed CPU version activation +fresh original graphs. Actual
2789
+ * migration/lease preparation happens outside the Tick. A failed activation
2790
+ * retains its exact token and closed admission; retry cannot roll SQL back. */
2791
+ activateGeometryVersion(roomId: string, token: GeometryVersionActivation): Promise<void>;
2792
+ /** Same-version administrative change uses the actual Host exclusion and
2793
+ * original graph readmission. SQL/lease preparation remains outside Tick. */
2794
+ activateGeometryChange(roomId: string, token: GeometryActivation): Promise<void>;
2795
+ /** Explicit installed mode in the same Host/map/session lookup and turn. The
2796
+ * factory has already committed real pre-seat SQL metadata; no state checkpoint. */
2797
+ addLockstep<S extends Schema.Codec<unknown, unknown>, I extends Schema.Codec<unknown, unknown>, O extends Schema.Codec<unknown, unknown>>(owner: RoomLockstepOwnedRoom<S, I, O>, offered: RoomRuntimeLockstepBinding): void;
2798
+ publishLockstep(roomId: string): Promise<void>;
2799
+ lockstepRosterOpen(roomId: string): boolean;
2800
+ admitLockstep(roomId: string, playerId: number, actualSession: RoomServerSessionHandle): RoomLockstepRosterPlayer;
2801
+ prepareLockstepInitialRoster(roomId: string, strategies?: Partial< RoomLockstepInitialStrategies>): Promise<ReadonlyArray<RoomLockstepRosterPlayer>>;
2802
+ startLockstep(roomId: string): Promise<ReadonlyArray<RoomLockstepRosterPlayer>>;
2803
+ private assertAdmission;
2804
+ /** Initial state is persisted before a staged SQL room becomes discoverable.
2805
+ * This is supervision, never a simulated tick. Retained failures are retryable. */
2806
+ holdPublication(roomId: string): void;
2807
+ isPublicationHeld(roomId: string): boolean;
2808
+ publishHeld(roomId: string, complete?: () => Promise<void>): Promise<void>;
2809
+ persist(roomId: string): Promise<void>;
2810
+ private persistRoom;
2811
+ connect(roomId: string, transport: RoomTransport): RoomServerSessionHandle;
2812
+ /** Synchronous host-private identity lookup. A turn awaiting checkpoint I/O
2813
+ * does not withdraw an already welcomed Session. This reads no actor state,
2814
+ * SQL or registry and grants no durable lease; all lifecycle fences still apply. */
2815
+ readSessionAdmission(roomId: string, sessionId: string): RoomSessionAdmissionEvidence | null;
2816
+ /** Ownership is checked by the controller before asking for socket teardown.
2817
+ * A cancelled admission that has not consumed the seat will fail its SQL CAS. */
2818
+ leaveSession(roomId: string, sessionId: string): Promise<void>;
2819
+ /** Host operator kick of every admitted session of one subject. The controller
2820
+ * checks ownership first; a `kicked` close releases each seat (no reconnect grace). */
2821
+ kickSubject(roomId: string, tenantId: string, subjectId: string | null, reason: string): Promise<number>;
2822
+ /** Trusted controller supplies the exact revoked tuple after SQL observation.
2823
+ * Only local resources are removed: no checkpoint/seat/command write or ACK.
2824
+ * Pending old-epoch payloads remain retained until cleanup actually completes. */
2825
+ withdrawOwnership(roomId: string, tenantId: string, epoch: number): Promise<void>;
2826
+ /** Actual local pre-handoff boundary. The controller must first fence SQL
2827
+ * admission and later commit handoff before invoking withdrawOwnership.
2828
+ * A failed preparation stays removed from the host loop and retains payloads. */
2829
+ prepareDrain(roomId: string): Promise<RoomDrainHandoff>;
2830
+ /** Trusted supervisor only, after matching durable handoff. Successful writes
2831
+ * are remembered individually; failed native writes keep their retry lifetime. */
2832
+ notifyDrainMigration(roomId: string, graceMs: number): Promise<void>;
2833
+ private finishWithdrawal;
2834
+ restore<S extends Schema.Codec<unknown, unknown>, I extends Schema.Codec<unknown, unknown>, O extends Schema.Codec<unknown, unknown>>(checkpoint: RoomCheckpoint, descriptor: RoomDescriptor<S, I, O>, options: (O)["Type"], epoch: number, admission: RoomSeatAdmission, sessionOptions: RoomRuntimeSessionOptions, publicationHeld?: boolean): RoomActor<S, I, O>;
2835
+ private capture;
2836
+ private commitPending;
2837
+ private retire;
2838
+ private captureTerminal;
2839
+ /** Resolve already accepted creation/retirement without advancing a Room.
2840
+ * Terminal and hibernate jobs retain their original snapshot/command receipts.
2841
+ * A failure in another Room cannot block this Room's pending commit. */
2842
+ settleForDrain(roomId: string): Promise<'active' | 'retired'>;
2843
+ private collectTerminal;
2844
+ turn(): Promise<number>;
2845
+ close(): Promise<void>;
2846
+ retains(roomId: string): boolean;
2847
+ isHibernating(roomId: string): boolean;
2848
+ hasPendingCheckpoint(roomId: string): boolean;
2849
+ metrics(): {
2850
+ readonly loop: RoomHostLoopSnapshot;
2851
+ readonly ownedRooms: number;
2852
+ readonly pendingCheckpoints: number;
2853
+ readonly sessions: number;
2854
+ readonly checkpointCommits: number;
2855
+ readonly checkpointStateBytes: number;
2856
+ readonly unchangedSnapshotsSkipped: number;
2857
+ readonly snapshotDeferred: number;
2858
+ readonly snapshotForcedBytes: number;
2859
+ readonly snapshotPeriodicBytes: number;
2860
+ readonly snapshotDebtBytes: number;
2861
+ /** Connected sessions whose state rate is reduced now, and how often their rates were halved. */
2862
+ readonly throttledSessions: number;
2863
+ readonly clientThrottles: number;
2864
+ /** Inputs of connected sessions dropped for arriving later than the input latency budget. */
2865
+ readonly staleInputsDropped: number;
2866
+ /** Highest datagram loss a connected client reports (permille; null when none reported), and how many report 10 % or more. */
2867
+ readonly maxReportedLossPermille: number | null;
2868
+ readonly lossySessions: number;
2869
+ };
2870
+ }
2871
+
2872
+ export declare interface RoomRuntimeLockstepBinding {
2873
+ readonly terminal: Context.Service.Shape<typeof RoomLockstepTerminalPort>;
2874
+ readonly runEffect: RoomSnapshotEffectRunner;
2875
+ }
2876
+
2877
+ declare interface RoomRuntimeSessionOptions extends Omit<RoomServerSessionOptions, 'epoch'> {
2878
+ readonly spectatorGroup?: RoomSpectatorGroup | undefined;
2879
+ readonly replayRecording?: RoomReplayRecordingBinding | undefined;
2880
+ readonly geometry?: RoomGeometryResource | undefined;
2881
+ }
2882
+
2883
+ declare interface RoomRuntimeSnapshotOptions {
2884
+ readonly poolDefaults?: RoomPoolRuntimeDefaults | undefined;
2885
+ readonly snapshotBudget?: RoomSnapshotBudgetOptions | undefined;
2886
+ readonly snapshotBudgetFactory?: RoomSnapshotBudgetFactory;
2887
+ }
2888
+
2889
+ declare type RoomScalar = string | number | boolean | null;
2890
+
2891
+ declare interface RoomScheduler {
2892
+ after(milliseconds: number, label: string): void;
2893
+ every(milliseconds: number, label: string): void;
2894
+ cancel(label: string): void;
2895
+ }
2896
+
2897
+ declare interface RoomScheduleSnapshot {
2898
+ readonly label: string;
2899
+ readonly remainingMs: number;
2900
+ readonly intervalMs: number | null;
2901
+ }
2902
+
2903
+ /** SQL-backed implementations must compare identity/epoch/expiry and transition
2904
+ * reserved -> connected atomically. A Redis-only consumed flag is insufficient:
2905
+ * clearing hot data must never make a used credential reusable. */
2906
+ declare interface RoomSeatAdmission {
2907
+ /** Actual SQL implementations recheck inside the Actor admission lifecycle. */
2908
+ revalidate?(claims: RoomSeatClaims, credentialDigest: string): Effect.Effect<void, ProtocolError>;
2909
+ consume(claims: RoomSeatClaims, credentialDigest: string): Effect.Effect<RoomConsumedSeat, SeatExpired | RoomForbidden | ProtocolError>;
2910
+ disconnect(claims: RoomSeatClaims, reason: RoomLeaveReason, credentialDigest: string): Effect.Effect<void, ProtocolError>;
2911
+ }
2912
+
2913
+ /** App data for one seat, resolved by the API when the seat is reserved (`seatAttributes`) and signed
2914
+ * into it; scalars only, at most 16 keys and 2 KiB. */
2915
+ declare type RoomSeatAttributes = Readonly<Record<string, RoomScalar>>;
2916
+
2917
+ declare type RoomSeatClaims = Omit<(typeof SeatClaimsSchema)["Type"], 'purpose'>;
2918
+
2919
+ declare interface RoomSeatTokenStrategies {
2920
+ readonly sign: typeof signRoomSeat;
2921
+ readonly verify: typeof verifiedRoomSeatClaims;
2922
+ }
2923
+
2924
+ /** Gateway-facing authority boundary. Every transport/seat operation happens
2925
+ * outside RoomActor.advance; the actor receives memory-only client callbacks. */
2926
+ declare class RoomServerSession<S extends Schema.Codec<unknown, unknown>, I extends Schema.Codec<unknown, unknown>, O extends Schema.Codec<unknown, unknown>> {
2927
+ private readonly owner;
2928
+ readonly transport: RoomTransport;
2929
+ readonly clock: RoomClock;
2930
+ readonly seats: RoomSeatAdmission;
2931
+ readonly options: RoomServerSessionOptions;
2932
+ private readonly codecs;
2933
+ private readonly baselines;
2934
+ private readonly detach;
2935
+ private readonly writes;
2936
+ private readonly maxPendingWrites;
2937
+ private readonly maxFramesPerSecond;
2938
+ private phase;
2939
+ private claims;
2940
+ private credentialDigest;
2941
+ private memberJoined;
2942
+ private welcomeDelivered;
2943
+ private datagramsAdmitted;
2944
+ private resync;
2945
+ private readonly worldNotices;
2946
+ private worldNoticeStateFence;
2947
+ private lastSentTick;
2948
+ private lastSentAt;
2949
+ private repairedTick;
2950
+ private lastAckSeq;
2951
+ private lastAckTick;
2952
+ private sendLevel;
2953
+ private sendSkip;
2954
+ private sendThrottles;
2955
+ private deltaDatagramsSent;
2956
+ private reportedLossPermille;
2957
+ private staleInputsDropped;
2958
+ private closeTask;
2959
+ private closeFailure;
2960
+ private readonly localCleanupFailures;
2961
+ private ownershipLost;
2962
+ private drainRequested;
2963
+ private drainTask;
2964
+ private drainSettled;
2965
+ private deferredClose;
2966
+ private authTask;
2967
+ private terminalError;
2968
+ private frameTokens;
2969
+ private byteTokens;
2970
+ private replenishedAt;
2971
+ private viewDurationMs;
2972
+ private viewOverruns;
2973
+ private readonly lifecycleAbort;
2974
+ private readonly helloTimeoutMs;
2975
+ private readonly authTimeoutMs;
2976
+ private readonly idleTimeoutMs;
2977
+ private readonly connectedAt;
2978
+ private lastReceivedAt;
2979
+ private authenticatingAt;
2980
+ private authSettled;
2981
+ private closeSettled;
2982
+ private readonly seatToken;
2983
+ private readonly spectatorHistory;
2984
+ private delayedCursor;
2985
+ private delayedTask;
2986
+ private readonly authorizeWorldPlayer;
2987
+ private readonly authorizeWorldTarget;
2988
+ private readonly revalidateSeat;
2989
+ private readonly onClientMessage;
2990
+ private lockstepBinding;
2991
+ private lockstepActivated;
2992
+ constructor(owner: RoomActor<S, I, O> | RoomLockstepMemberOwner<S, I, O>, transport: RoomTransport, clock: RoomClock, seats: RoomSeatAdmission, options: RoomServerSessionOptions);
2993
+ get actor(): RoomActor<S, I, O>;
2994
+ get membershipMode(): 'state-sync' | 'lockstep';
2995
+ get status(): 'awaitingHello' | 'authenticating' | 'joined' | 'closed';
2996
+ get failure(): unknown;
2997
+ teardownReady(): boolean;
2998
+ /** The ordinary token gateway consumes Hello before installing listeners.
2999
+ * Its verified frame is replayed once into this same admission path. */
3000
+ admitFirstFrame(bytes: Uint8Array): void;
3001
+ /** Called by the one host driver, outside actor.advance. No per-session timer. */
3002
+ maintenance(): void;
3003
+ metrics(): {
3004
+ readonly viewDurationMs: number;
3005
+ readonly viewOverruns: number;
3006
+ readonly pendingWrites: number;
3007
+ };
3008
+ private snapshot;
3009
+ private write;
3010
+ private writeEncoded;
3011
+ private send;
3012
+ private backgroundClose;
3013
+ private authenticate;
3014
+ private receive;
3015
+ private acknowledgeBaseline;
3016
+ /** Invoke after the host's synchronous advance, at the configured send rate.
3017
+ * Unacknowledged/stale baselines always fall back to a reliable full state. */
3018
+ /** A room that stops changing publishes nothing newer, so a lost datagram carrying its last
3019
+ * state would never be replaced. Once that state stays unacknowledged past the repair delay,
3020
+ * it goes once more on the reliable stream. */
3021
+ private repairUnacknowledgedState;
3022
+ publishState(): void;
3023
+ /** One slow client never slows the Room: while its unsent bytes exceed four frames of the
3024
+ * Room's byte budget (`budgets.bytesPerSecond / sendRate × 4`), its state rate halves, down
3025
+ * to every 8th frame; once they fall to half of that, it climbs back one step per frame
3026
+ * sent. Skipped deltas fold into the next one, which still builds on an acknowledged
3027
+ * baseline. */
3028
+ private backpressured;
3029
+ /** Input age: `tickHint` is the newest tick the client had when it acted. Measured against
3030
+ * the newest state this Host sent that client (not the Room clock), so an idle Room or a
3031
+ * throttled client never ages its inputs; only inputs that arrived after more than
3032
+ * `budgets.inputLatencyBudgetMs` of newer state was already on its way are dropped. On the
3033
+ * datagram lane a sent state may never arrive, so the age counts from the newest state the
3034
+ * client acknowledged: a lost datagram does not make its inputs late, while a client that
3035
+ * acknowledged newer state and claims an older one still is. */
3036
+ private staleInput;
3037
+ /** Inputs dropped for arriving later than `budgets.inputLatencyBudgetMs`. */
3038
+ staleInputs(): number;
3039
+ /** Adaptive send rate: the current level (0 = every frame, 3 = every 8th) and how often it rose. */
3040
+ sendThrottle(): {
3041
+ readonly level: number;
3042
+ readonly throttles: number;
3043
+ };
3044
+ /** The client's last reported loss of state datagrams in permille, or null before its first report. */
3045
+ reportedLoss(): number | null;
3046
+ get id(): string | null;
3047
+ /* Excluded from this release type: canSendLockstepMessages */
3048
+ /* Excluded from this release type: sendLockstepMessage */
3049
+ /* Excluded from this release type: writeReliableChannel */
3050
+ /** Host-private observation after real token/SQL/member/Welcome admission.
3051
+ * Native buffer drain is not a remote asset ACK or application authorization. */
3052
+ /** Host operator kick: the Kick frame, then a `kicked` close that releases the seat instead of holding reconnect grace. */
3053
+ kick(reason: string): Promise<void>;
3054
+ admittedIdentity(): RoomSessionAdmissionEvidence | null;
3055
+ /** Server-private compiled input layout, only while the same real admission is current. */
3056
+ admittedInputSchemaHash(): number | null;
3057
+ /* Excluded from this release type: installLockstep */
3058
+ /* Excluded from this release type: canInstallLockstep */
3059
+ /* Excluded from this release type: writeLockstep */
3060
+ /* Excluded from this release type: withdrawLockstep */
3061
+ private observerNow;
3062
+ private publishDelayedState;
3063
+ close(reason?: RoomLeaveReason): Promise<void>;
3064
+ /** Stop new frames immediately; retain native connection and SQL Seats.
3065
+ * Accepted auth/lifecycle/writes settle before a final snapshot may be taken.
3066
+ * Only post-revocation closeFenced or explicit terminal disposal releases it. */
3067
+ quiesceForDrain(): Promise<void>;
3068
+ /** Trusted supervisor only, after the matching SQL handoff. */
3069
+ /** Enqueue only; transport failures use the existing owned teardown path. */
3070
+ notifyWorldHandoff(frame: RoomWorldHandoffFrame): void;
3071
+ notifyMigration(graceMs: number, address?: string): Promise<void>;
3072
+ /** Native fixtures/host shutdown can await all owned asynchronous work. */
3073
+ settled(): Promise<void>;
3074
+ /** Trusted supervisor only, after durable ownership revocation. It does not
3075
+ * release/rotate a successor's SQL seat. Accepted auth and writes still await
3076
+ * real completion; author, detach and transport failures remain failures. */
3077
+ closeFenced(): Promise<void>;
3078
+ }
3079
+
3080
+ declare interface RoomServerSessionHandle {
3081
+ /** Optional provider capability; missing refuses readiness, never substitutes
3082
+ * a sessionId/status-only success. Native RoomServerSession supplies it. */
3083
+ admittedIdentity?(): RoomSessionAdmissionEvidence | null;
3084
+ /** Optional provider capability for Host operator kicks; missing refuses the kick. */
3085
+ kick?(reason: string): Promise<void>;
3086
+ readonly id: string | null;
3087
+ readonly status: 'awaitingHello' | 'authenticating' | 'joined' | 'closed';
3088
+ readonly failure: unknown;
3089
+ maintenance(): void;
3090
+ teardownReady(): boolean;
3091
+ admitFirstFrame(bytes: Uint8Array): void;
3092
+ publishState(): void;
3093
+ /** Optional: adaptive send-rate observation (native RoomServerSession supplies it). */
3094
+ sendThrottle?(): {
3095
+ readonly level: number;
3096
+ readonly throttles: number;
3097
+ };
3098
+ /** Optional: inputs dropped for arriving later than the Room's input latency budget. */
3099
+ staleInputs?(): number;
3100
+ /** Optional: the client's last reported loss of state datagrams in permille (null before a report). */
3101
+ reportedLoss?(): number | null;
3102
+ close(reason?: 'left' | 'kicked' | 'reconnecting' | 'timeout' | 'disposed'): Promise<void>;
3103
+ closeFenced(): Promise<void>;
3104
+ quiesceForDrain?(): Promise<void>;
3105
+ notifyWorldHandoff?(frame: RoomWorldHandoffFrame): void;
3106
+ notifyMigration?(graceMs: number, address?: string): Promise<void>;
3107
+ settled(): Promise<void>;
3108
+ }
3109
+
3110
+ declare interface RoomServerSessionOptions {
3111
+ /** Ordinary World player admission; returns the entity this Session controls for `onJoin`. */
3112
+ readonly authorizeWorldPlayer?: (claims: RoomSeatClaims) => Effect.Effect<RoomWorldMember | undefined, ProtocolError>;
3113
+ readonly authorizeWorldTarget?: (claims: RoomSeatClaims, binding: WorldTargetSeatBinding, credentialDigest: string) => Effect.Effect<'pending' | 'committed' | 'settled', ProtocolError>;
3114
+ readonly epoch: number;
3115
+ readonly secrets: SessionSecrets;
3116
+ readonly epochNow: () => number;
3117
+ readonly seatToken?: Partial<RoomSeatTokenStrategies>;
3118
+ readonly maxPendingWrites?: number | undefined;
3119
+ readonly maxFramesPerSecond?: number | undefined;
3120
+ readonly baselineCapacity?: number | undefined;
3121
+ readonly maxBaselineAgeMs?: number | undefined;
3122
+ readonly helloTimeoutMs?: number;
3123
+ readonly authTimeoutMs?: number;
3124
+ readonly idleTimeoutMs?: number;
3125
+ readonly onClientMessage?: (channel: string, payload: unknown, claims: RoomSeatClaims) => undefined;
3126
+ readonly spectatorHistory?: RoomSpectatorHistory | undefined;
3127
+ }
3128
+
3129
+ /** Server-private admitted player identity. It grants no application authority
3130
+ * and must never appear in inspection, logs, exports or client payloads. */
3131
+ declare interface RoomSessionAdmissionEvidence {
3132
+ readonly tenantId: string;
3133
+ readonly subjectId: string;
3134
+ readonly roomId: string;
3135
+ readonly sessionId: string;
3136
+ readonly epoch: number;
3137
+ readonly role: 'player';
3138
+ readonly nonce: string;
3139
+ readonly credentialDigest: string;
3140
+ }
3141
+
3142
+ declare type RoomSnapshotBudgetFactory = (options: Readonly<RoomSnapshotBudgetOptions>) => RoomSnapshotBudgetService;
3143
+
3144
+ declare interface RoomSnapshotBudgetOptions {
3145
+ readonly budgetBytesPerSec?: number;
3146
+ readonly burstBytes?: number;
3147
+ }
3148
+
3149
+ declare interface RoomSnapshotBudgetService {
3150
+ /** Account a durable boundary without dropping commands/initial/terminal
3151
+ * state. Its debt defers subsequent periodic snapshots. */
3152
+ forced(bytes: number, now: number): void;
3153
+ periodic(roomId: string, bytes: number, now: number): boolean;
3154
+ /** A blocked periodic head cannot be bypassed by smaller periodic payloads. */
3155
+ blocked(roomId: string): boolean;
3156
+ forget(roomId: string): void;
3157
+ metrics(): {
3158
+ readonly deferred: number;
3159
+ readonly forcedBytes: number;
3160
+ readonly periodicBytes: number;
3161
+ readonly debtBytes: number;
3162
+ };
3163
+ }
3164
+
3165
+ declare type RoomSnapshotEffectRunner = <A, E>(effect: Effect.Effect<A, E>) => Promise<A>;
3166
+
3167
+ declare interface RoomSnapshotPolicy<S> {
3168
+ readonly everyMs: number;
3169
+ readonly onlyIfChanged: boolean;
3170
+ readonly mode: 'full' | 'delta';
3171
+ readonly fullEvery: number;
3172
+ readonly keepFulls: number;
3173
+ readonly store: 'auto';
3174
+ /** Maximum inline codec payload; the host may impose a smaller cutoff. */
3175
+ readonly maxInlineBytes: number;
3176
+ /** Full-schema projection of volatile data; never a partial-state format. */
3177
+ readonly pick: (state: S) => S;
3178
+ }
3179
+
3180
+ /** One trusted common view, deliberately without a fabricated player identity.
3181
+ * The app must authorize every reader to this entire view and withdraw it on
3182
+ * privacy changes. No player-supplied group ID, view or clock is accepted. */
3183
+ declare interface RoomSpectatorGroup<S extends Schema.Codec<unknown, unknown> = Schema.Codec<unknown, unknown>> {
3184
+ readonly view: (context: RoomSpectatorViewContext<(S)["Type"]>) => (S)["Type"];
3185
+ readonly authorize: RoomSpectatorHistory['authorize'];
3186
+ }
3187
+
3188
+ declare interface RoomSpectatorHistory {
3189
+ readonly roomId: string;
3190
+ readonly tenantId: string;
3191
+ readonly history: SpectatorDelayBuffer<Schema.Codec<unknown, unknown>>;
3192
+ /** Current author-owned admission to this exact view group, outside ticks. */
3193
+ readonly authorize: (claims: RoomSeatClaims) => Effect.Effect<void, ProtocolError | RoomForbidden>;
3194
+ }
3195
+
3196
+ declare interface RoomSpectatorPolicy {
3197
+ readonly delayMs: number;
3198
+ readonly retentionMs: number;
3199
+ readonly maxFrames: number;
3200
+ readonly maxBytes: number;
3201
+ readonly maxFrameBytes: number;
3202
+ readonly checkpointEveryMs: number;
3203
+ readonly maxDeliveryFrames: number;
3204
+ }
3205
+
3206
+ declare interface RoomSpectatorViewContext<A> {
3207
+ readonly roomId: string;
3208
+ readonly tenantId: string;
3209
+ readonly epoch: number;
3210
+ readonly tick: number;
3211
+ readonly state: A;
3212
+ }
3213
+
3214
+ /** Plain mutable state; the author receives no store or database capability. */
3215
+ declare type RoomState<A> = A extends ReadonlyArray<infer V> ? Array<RoomState<V>> : A extends object ? {
3216
+ -readonly [K in keyof A]: RoomState<A[K]>;
3217
+ } : A;
3218
+
3219
+ /** Input and channel schemas are not state schemas: sorted field names derive
3220
+ * their binary order, while server state always requires explicit field IDs. */
3221
+ declare class RoomStateCodec<S extends Schema.Codec<unknown, unknown>> {
3222
+ readonly schema: S;
3223
+ private readonly codec;
3224
+ constructor(schema: S, config?: Partial<RoomCodecLimits>);
3225
+ get schemaHash(): number;
3226
+ get limits(): RoomCodecLimits;
3227
+ /** Canonical binary layout, including quantization and static movement rules.
3228
+ * This is descriptive data; it grants neither authority nor a schema loader. */
3229
+ schemaDescription(): string;
3230
+ fieldManifest(): ReadonlyArray<RoomStateField>;
3231
+ transformRulesManifest(): ReadonlyArray<RoomStateTransformRules>;
3232
+ full(state: (S)["Type"]): Result.Result<Uint8Array, ProtocolError>;
3233
+ decodeFull(bytes: Uint8Array): Result.Result<(S)["Type"], ProtocolError>;
3234
+ delta(state: (S)["Type"], baseline: (S)["Type"], includeUnchanged?: boolean): Result.Result<Uint8Array | null, ProtocolError>;
3235
+ decodeDelta(bytes: Uint8Array, baseline: (S)["Type"]): Result.Result<(S)["Type"], ProtocolError>;
3236
+ }
3237
+
3238
+ declare interface RoomStateField {
3239
+ /** Parent scope is formed from field IDs, not mutable author field names. */
3240
+ readonly scope: string;
3241
+ readonly id: number;
3242
+ readonly name: string;
3243
+ }
3244
+
3245
+ declare interface RoomStateTransformRules {
3246
+ readonly scope: string;
3247
+ readonly rules: TransformRules;
3248
+ }
3249
+
3250
+ declare interface RoomStoredReplay {
3251
+ readonly replayId: string;
3252
+ readonly roomId: string;
3253
+ readonly roomName: string;
3254
+ readonly matchId: string;
3255
+ readonly visibility: RoomReplayPublish['visibility'];
3256
+ readonly expiresAtMs: number | null;
3257
+ readonly durationMs: number;
3258
+ readonly size: number;
3259
+ readonly schemaHash: number;
3260
+ }
3261
+
3262
+ /** Synchronous hook. `void` admits parameterless block bodies (TypeScript cannot narrow those to
3263
+ * `undefined`); any returned value, a Promise included, is refused at runtime with an authoring error. */
3264
+ declare type RoomSyncHook<C> = (context: C) => void;
3265
+
3266
+ declare interface RoomTickContext<S, I> {
3267
+ /** Prepared native CPU queries only, installed before actor lifecycle. */
3268
+ readonly geometry?: GeometryWorldView | undefined;
3269
+ readonly state: RoomState<S>;
3270
+ readonly tick: number;
3271
+ readonly dt: number;
3272
+ readonly inputs: ReadonlyArray<RoomInput<I>>;
3273
+ readonly app: RoomAppBridge;
3274
+ readonly clock: RoomClock;
3275
+ readonly scheduler: RoomScheduler;
3276
+ broadcast(channel: string, payload: unknown): void;
3277
+ }
3278
+
3279
+ declare interface RoomTransport {
3280
+ readonly name: 'ws' | 'wt';
3281
+ readonly reliable: RoomReliableLane;
3282
+ readonly unreliable?: RoomDatagramLane | undefined;
3283
+ readonly signal: AbortSignal;
3284
+ stats(): {
3285
+ readonly rttMs: number | null;
3286
+ readonly queuedBytes: number;
3287
+ readonly droppedDatagrams: number;
3288
+ };
3289
+ close(code: number, reason: string): void;
3290
+ /** When provided, joins actual parent/stream withdrawal and permits retry.
3291
+ * Synchronous close alone does not establish native terminal evidence. */
3292
+ closeAsync?(code: number, reason: string): Promise<void>;
3293
+ }
3294
+
3295
+ declare interface RoomViewContext<S> {
3296
+ readonly state: S;
3297
+ readonly client: Pick<RoomClient, 'sessionId' | 'subjectId' | 'tenantId' | 'isBot' | 'countsAsPlayer' | 'attributes'>;
3298
+ readonly role: 'player' | 'spectator';
3299
+ readonly tick: number;
3300
+ }
3301
+
3302
+ /** World Rooms keep their authored entities in the declared state record. */
3303
+ declare type RoomWorldEntity<S> = S extends {
3304
+ readonly entities: Readonly<Record<string, infer E>>;
3305
+ } ? RoomState<E> & {
3306
+ readonly id: string;
3307
+ } : never;
3308
+
3309
+ /** Internal source handoff identity; caller data never replaces the live entity. */
3310
+ declare interface RoomWorldExitInput {
3311
+ readonly afterglow?: {
3312
+ readonly requestId: string;
3313
+ readonly expiresAt: number;
3314
+ };
3315
+ readonly subjectId?: string;
3316
+ readonly epoch: number;
3317
+ readonly entityId: string;
3318
+ readonly requestId: string;
3319
+ readonly location: WorldEntityLocation;
3320
+ }
3321
+
3322
+ /** Render/connection coordination only: no token and no ownership assertion. */
3323
+ declare interface RoomWorldHandoffFrame {
3324
+ readonly kind: 'WorldHandoff';
3325
+ readonly phase: 'departed' | 'cancelled';
3326
+ readonly transitionId: string;
3327
+ readonly entityId: string;
3328
+ readonly tick: number;
3329
+ readonly sourceEpoch: number;
3330
+ readonly targetRoomId: string;
3331
+ readonly targetEpoch: number;
3332
+ readonly holdMs: number;
3333
+ }
3334
+
3335
+ declare interface RoomWorldHookContext<S> {
3336
+ readonly state: RoomState<S>;
3337
+ readonly phase: 'prepare' | 'commit' | 'rollback';
3338
+ readonly requestId?: string | undefined;
3339
+ readonly entity: RoomWorldEntity<S>;
3340
+ }
3341
+
3342
+ declare interface RoomWorldHookInput<E = unknown> {
3343
+ /** Actual target placement, distinct from the source location. Only guarded
3344
+ * target entry uses it; source rollback must restore its exact snapshot. */
3345
+ readonly arrival?: WorldEntityLocation;
3346
+ readonly epoch: number;
3347
+ readonly entity: E;
3348
+ readonly location: WorldEntityLocation;
3349
+ readonly requestId?: string | undefined;
3350
+ }
3351
+
3352
+ declare interface RoomWorldHooks<S> {
3353
+ /** Opt-in cell movement: synchronous author projection/write, no I/O. */
3354
+ readonly movement?: RoomWorldMovement<S>;
3355
+ /** Retained checkpoint receipts awaiting confirmed transition retirement. */
3356
+ readonly maxPendingTransitions?: number;
3357
+ readonly onEnter: RoomLifecycleHook<RoomWorldHookContext<S> & {
3358
+ readonly from: WorldEntityLocation;
3359
+ readonly to?: WorldEntityLocation;
3360
+ }>;
3361
+ readonly onExit: RoomLifecycleHook<RoomWorldHookContext<S> & {
3362
+ readonly to: WorldEntityLocation;
3363
+ }>;
3364
+ /** Publish a projection on commit; remove that projection on rollback. Never
3365
+ * promote it into authoritative entities. Rollback may retry after failure. */
3366
+ readonly onGhost: RoomLifecycleHook<RoomWorldHookContext<S>>;
3367
+ /** Synchronous, bounded JSON projection; no SQL or asynchronous effect here. */
3368
+ readonly persistEntity: (context: {
3369
+ readonly entity: RoomWorldEntity<S>;
3370
+ }) => unknown;
3371
+ /** A player who arrived by a World transition is now an active member. `onJoin` does not run for
3372
+ * such arrivals (the entity came with `onEnter`); this is where the Room sees the arriving client,
3373
+ * e.g. its seat attributes (`client.attributes`). */
3374
+ readonly onMemberEnter?: RoomLifecycleHook<{
3375
+ readonly state: RoomState<S>;
3376
+ readonly client: RoomClient;
3377
+ readonly entityId: string;
3378
+ }>;
3379
+ }
3380
+
3381
+ /** The server-owned entity an ordinary World player Session controls, as last persisted.
3382
+ * The Room's `onJoin` receives it as `world` and builds the state entity when absent. */
3383
+ declare interface RoomWorldMember {
3384
+ readonly entityId: string;
3385
+ readonly worldId: string;
3386
+ readonly zoneId: string;
3387
+ readonly cellId: string;
3388
+ readonly layer: number;
3389
+ readonly revision: number;
3390
+ /** The Room's `persistEntity` projection from the entity's last write. */
3391
+ readonly data: unknown;
3392
+ }
3393
+
3394
+ declare interface RoomWorldMovement<S> {
3395
+ readonly maxEntities: number;
3396
+ readonly maxBytesPerTick: number;
3397
+ readonly position: (entity: RoomWorldEntity<S>) => WorldPoint;
3398
+ readonly move: (entity: RoomWorldEntity<S>, at: WorldPoint) => void;
3399
+ }
3400
+
3401
+ declare interface RoomWorldReceipt {
3402
+ readonly requestId: string;
3403
+ readonly operation: 'enter' | 'exit' | 'ghost';
3404
+ readonly fingerprint: string;
3405
+ readonly projection?: {
3406
+ readonly entity: unknown;
3407
+ readonly location: WorldEntityLocation;
3408
+ readonly expiresAt?: number;
3409
+ };
3410
+ }
3411
+
3412
+ declare const SeatClaimsSchema: Schema.Struct<{
3413
+ readonly purpose: Schema.Literal<"voltro.rooms.seat.v1">;
3414
+ readonly roomId: Schema.NonEmptyString;
3415
+ readonly sessionId: Schema.NonEmptyString;
3416
+ readonly subjectId: Schema.NullOr<Schema.NonEmptyString>;
3417
+ readonly subjectType: Schema.optionalKey<Schema.Literals<readonly ["user", "apiKey", "serviceAccount"]>>;
3418
+ readonly subjectKind: Schema.optionalKey<Schema.Literal<"guest">>;
3419
+ readonly tenantId: Schema.NonEmptyString;
3420
+ readonly epoch: Schema.Int;
3421
+ readonly nonce: Schema.NonEmptyString;
3422
+ readonly expiresAt: Schema.Number;
3423
+ readonly role: Schema.Literals<readonly ["player", "spectator"]>;
3424
+ readonly attributes: Schema.optionalKey<Schema.$Record<Schema.String, Schema.Union<readonly [Schema.String, Schema.Number, Schema.Boolean, Schema.Null]>>>;
3425
+ }>;
3426
+
3427
+ declare class SeatExpired extends SeatExpired_base {
3428
+ }
3429
+
3430
+ declare const SeatExpired_base: Schema.Class<SeatExpired, Schema.TaggedStruct<"SeatExpired", {
3431
+ readonly sessionId: Schema.String;
3432
+ }>, YieldableError>;
3433
+
3434
+ /** The caller supplies project-owned Rooms keys, never API-session keys.
3435
+ * This is the ordinary framework HMAC primitive with a dedicated purpose and
3436
+ * identity carrier, not an additional signature implementation. */
3437
+ declare const signRoomSeat: (claims: RoomSeatClaims, secrets: SessionSecrets, nowMs: number) => Uint8Array;
3438
+
3439
+ declare interface Simulation<S extends Schema.Codec<unknown, unknown>, I extends Schema.Codec<unknown, unknown>, O extends Schema.Codec<unknown, unknown>> {
3440
+ readonly definition: SimulationDefinition<S, I, O>;
3441
+ readonly stateCodec: SimulationStateCodec<S>;
3442
+ readonly inputCodec: SimulationStateCodec<I>;
3443
+ readonly optionsCodec: SimulationStateCodec<O>;
3444
+ }
3445
+
3446
+ declare interface SimulationDefinition<S extends Schema.Codec<unknown, unknown>, I extends Schema.Codec<unknown, unknown>, O extends Schema.Codec<unknown, unknown>> {
3447
+ readonly state: S;
3448
+ readonly input: I;
3449
+ readonly options: O;
3450
+ readonly init: (seed: number, options: (O)["Type"]) => (S)["Type"];
3451
+ readonly step: (state: RoomState<(S)["Type"]>, inputs: ReadonlyArray<SimulationPlayerInput<(I)["Type"]>>, tick: number, rng: Pcg32) => (S)["Type"];
3452
+ readonly hash?: (state: (S)["Type"]) => Uint64Words;
3453
+ /** Late join: runs before `step` at the tick a player's input first appears (it was absent
3454
+ * from the previous tick's inputs), in player-ID order, e.g. to spawn the player. Pure and
3455
+ * deterministic like `step`. Start players are `init`'s job: tick 1 runs no join. */
3456
+ readonly join?: (state: RoomState<(S)["Type"]>, playerId: number, tick: number, rng: Pcg32) => (S)["Type"];
3457
+ readonly limits?: Partial<SimulationValueLimits>;
3458
+ }
3459
+
3460
+ declare interface SimulationPlayerInput<I> {
3461
+ readonly playerId: number;
3462
+ readonly input: I;
3463
+ }
3464
+
3465
+ declare interface SimulationRecovery<S, I> {
3466
+ readonly snapshot: SimulationSnapshot<S>;
3467
+ readonly inputs: ReadonlyArray<SimulationPlayerInput<I>>;
3468
+ readonly continuation?: ReadonlyArray<SimulationTickInputs<I>> | undefined;
3469
+ }
3470
+
3471
+ declare interface SimulationSnapshot<S> {
3472
+ readonly tick: number;
3473
+ readonly state: S;
3474
+ readonly rng: Pcg32Snapshot;
3475
+ readonly hash: Uint64Words;
3476
+ }
3477
+
3478
+ declare interface SimulationStateCodec<S extends Schema.Codec<unknown, unknown>> {
3479
+ readonly limits: SimulationValueLimits;
3480
+ /** Admitted capture/hash plan, not a binary Room wire schema. */
3481
+ schemaDescription?(): string;
3482
+ capture(value: unknown): (S)["Type"];
3483
+ hash(value: (S)["Type"]): Uint64Words;
3484
+ }
3485
+
3486
+ declare interface SimulationTickInputs<I> {
3487
+ readonly tick: number;
3488
+ readonly inputs: ReadonlyArray<SimulationPlayerInput<I>>;
3489
+ }
3490
+
3491
+ declare interface SimulationValueLimits extends RoomCodecLimits {
3492
+ readonly maxNodes: number;
3493
+ }
3494
+
3495
+ /** One already-authorized view group's contiguous Full/Delta history. Feed and
3496
+ * delivery happen outside ticks. This does not install a spectator or timer. */
3497
+ declare class SpectatorDelayBuffer<S extends Schema.Codec<unknown, unknown>> {
3498
+ private readonly codec;
3499
+ readonly limits: SpectatorDelayLimits;
3500
+ private records;
3501
+ private previous;
3502
+ private checkpointAt;
3503
+ private sequence;
3504
+ private observedNow;
3505
+ private cached;
3506
+ constructor(codec: RoomStateCodec<S>, limits?: Partial<SpectatorDelayLimits>);
3507
+ /** Exact selected-view layout; it grants no group/seat authority. */
3508
+ schemaDescription(): string;
3509
+ append(atMs: number, input: Uint8Array): Result.Result<void, ProtocolError>;
3510
+ delivery(nowMs: number, after?: SpectatorDelayCursor): Result.Result<SpectatorDelayDelivery, ProtocolError>;
3511
+ /** No previously returned frame or external peer is erased by this call. */
3512
+ clear(): void;
3513
+ }
3514
+
3515
+ /** Opaque history position only; never a seat, credential or authorization. */
3516
+ declare interface SpectatorDelayCursor {
3517
+ readonly sequence: number;
3518
+ readonly tick: number;
3519
+ readonly epoch: number;
3520
+ }
3521
+
3522
+ declare type SpectatorDelayDelivery = {
3523
+ readonly kind: 'unavailable';
3524
+ } | {
3525
+ readonly kind: 'unchanged';
3526
+ readonly cursor: SpectatorDelayCursor;
3527
+ readonly atMs: number;
3528
+ } | {
3529
+ readonly kind: 'full';
3530
+ readonly cursor: SpectatorDelayCursor;
3531
+ readonly atMs: number;
3532
+ readonly bytes: Uint8Array;
3533
+ } | {
3534
+ readonly kind: 'deltas';
3535
+ readonly cursor: SpectatorDelayCursor;
3536
+ readonly atMs: number;
3537
+ readonly frames: ReadonlyArray<{
3538
+ readonly atMs: number;
3539
+ readonly bytes: Uint8Array;
3540
+ }>;
3541
+ };
3542
+
3543
+ declare type SpectatorDelayLimits = RoomSpectatorPolicy;
3544
+
3545
+ declare const Transform2D: Schema.Struct<{
3546
+ readonly x: Schema.Number;
3547
+ readonly y: Schema.Number;
3548
+ readonly rot: Schema.Number;
3549
+ readonly vx: Schema.optional<Schema.Number>;
3550
+ readonly vy: Schema.optional<Schema.Number>;
3551
+ }>;
3552
+
3553
+ declare type Transform2D = (typeof Transform2D)["Type"];
3554
+
3555
+ declare type TransformRules = TransformRules2D | TransformRules3D;
3556
+
3557
+ declare interface TransformRules2D {
3558
+ readonly bounds: {
3559
+ readonly min: readonly [number, number];
3560
+ readonly max: readonly [number, number];
3561
+ };
3562
+ readonly maxSpeed: number;
3563
+ readonly maxAccel: number;
3564
+ readonly precision: number;
3565
+ readonly rotation?: {
3566
+ readonly bits: number;
3567
+ } | undefined;
3568
+ readonly velocity?: 'send' | 'derive' | 'none' | undefined;
3569
+ readonly interpolation: 'linear' | 'hermite' | 'none';
3570
+ readonly extrapolateMs: number;
3571
+ readonly teleportThreshold: number;
3572
+ }
3573
+
3574
+ declare interface TransformRules3D {
3575
+ readonly bounds: {
3576
+ readonly min: readonly [number, number, number];
3577
+ readonly max: readonly [number, number, number];
3578
+ };
3579
+ readonly maxSpeed: number;
3580
+ readonly maxAccel: number;
3581
+ readonly precision: number;
3582
+ readonly rotation?: {
3583
+ readonly bits: number;
3584
+ } | undefined;
3585
+ readonly interpolation: 'linear' | 'hermite' | 'none';
3586
+ readonly extrapolateMs: number;
3587
+ readonly teleportThreshold: number;
3588
+ }
3589
+
3590
+ /** Exact unsigned 64-bit integer as independent 32-bit words. */
3591
+ declare interface Uint64Words {
3592
+ readonly hi: number;
3593
+ readonly lo: number;
3594
+ }
3595
+
3596
+ /** Signature, purpose and exact millisecond expiry are checked before any
3597
+ * durable seat operation. A valid token grants no application scopes. */
3598
+ declare const verifiedRoomSeatClaims: (token: Uint8Array, secrets: SessionSecrets, nowMs: number) => RoomSeatClaims;
3599
+
3600
+ declare type WorldBounds = readonly [minimum: WorldPoint, maximum: WorldPoint];
3601
+
3602
+ declare interface WorldDefinition<Player> {
3603
+ readonly name: string;
3604
+ readonly map: {
3605
+ readonly bounds: WorldBounds;
3606
+ };
3607
+ readonly zones: ReadonlyArray<WorldZone>;
3608
+ readonly instances?: ReadonlyArray<WorldInstance>;
3609
+ readonly persistence: {
3610
+ readonly entities: 'world';
3611
+ readonly snapshotEveryMs: number;
3612
+ readonly journal: boolean;
3613
+ };
3614
+ readonly handoff: {
3615
+ readonly marginUnits: number;
3616
+ readonly ghostUnits: number;
3617
+ };
3618
+ readonly spawn: (context: {
3619
+ readonly player: Player;
3620
+ }) => WorldPosition;
3621
+ readonly geometry?: WorldGeometryDefinition | undefined;
3622
+ readonly hosts?: {
3623
+ readonly pool: string;
3624
+ };
3625
+ readonly characters?: 'shared' | 'per-world';
3626
+ readonly transitionCooldownMs?: number;
3627
+ /** Authoring inventory bounds, not measured runtime capacity. */
3628
+ readonly budgets?: {
3629
+ readonly maxZones?: number;
3630
+ readonly maxCells?: number | undefined;
3631
+ readonly maxInstances?: number;
3632
+ };
3633
+ readonly strategies?: {
3634
+ readonly layerPolicy?: WorldLayerPolicy | undefined;
3635
+ readonly transitionPolicy?: WorldTransitionPolicy;
3636
+ readonly onWorldChange?: WorldOnWorldChange;
3637
+ };
3638
+ }
3639
+
3640
+ declare interface WorldDescriptor<Player> extends Omit<WorldDefinition<Player>, 'instances' | 'budgets' | 'characters' | 'transitionCooldownMs' | 'strategies' | 'geometry'> {
3641
+ readonly geometry?: WorldGeometryDescriptor | undefined;
3642
+ readonly _tag: 'WorldDescriptor';
3643
+ readonly instances: ReadonlyArray<Omit<WorldInstance, 'ttl'> & {
3644
+ readonly ttlMs: number;
3645
+ }>;
3646
+ readonly budgets: {
3647
+ readonly maxZones: number;
3648
+ readonly maxCells: number;
3649
+ readonly maxInstances: number;
3650
+ };
3651
+ readonly characters: 'shared' | 'per-world';
3652
+ readonly transitionCooldownMs: number;
3653
+ readonly cellCount: number;
3654
+ readonly strategies: {
3655
+ readonly layerPolicy: WorldLayerPolicy;
3656
+ readonly transitionPolicy: WorldTransitionPolicy;
3657
+ readonly onWorldChange: WorldOnWorldChange;
3658
+ };
3659
+ }
3660
+
3661
+ declare interface WorldEntityLocation {
3662
+ readonly worldId: string;
3663
+ readonly zoneId: string;
3664
+ readonly at: WorldPoint;
3665
+ readonly layer: number;
3666
+ readonly roomId: string;
3667
+ readonly epoch: number;
3668
+ }
3669
+
3670
+ declare interface WorldGeometryDefinition {
3671
+ readonly strategies?: WorldGeometryStrategies | undefined;
3672
+ readonly kind: GeometryKind;
3673
+ readonly static: GeometrySource;
3674
+ readonly chunkSize?: number;
3675
+ readonly dynamic?: {
3676
+ readonly enabled?: boolean | undefined;
3677
+ readonly maxDeltaBytesPerChunk?: number;
3678
+ readonly persist?: {
3679
+ readonly everyMs?: number;
3680
+ readonly onUnload?: boolean;
3681
+ };
3682
+ };
3683
+ readonly collision?: {
3684
+ readonly derive?: 'bitgrid' | 'heightfield' | 'shapes';
3685
+ readonly resolution?: number;
3686
+ };
3687
+ readonly nav?: {
3688
+ readonly derive?: 'grid' | 'none';
3689
+ readonly navBudgetMs?: number;
3690
+ readonly maxAdvanceSteps?: number;
3691
+ };
3692
+ readonly streaming?: {
3693
+ readonly client?: {
3694
+ readonly radiusChunks?: number;
3695
+ readonly prefetchChunks?: number;
3696
+ readonly maxConcurrent?: number | undefined;
3697
+ readonly maxCachedChunks?: number;
3698
+ };
3699
+ readonly cell?: {
3700
+ readonly marginChunks?: number;
3701
+ };
3702
+ };
3703
+ readonly lod?: ReadonlyArray<{
3704
+ readonly beyondChunks: number;
3705
+ readonly fields: ReadonlyArray<string>;
3706
+ }>;
3707
+ readonly budgets?: {
3708
+ readonly maxPreparedChunks?: number;
3709
+ readonly maxPreparedBytes?: number;
3710
+ readonly maxLodLevels?: number;
3711
+ readonly maxRayCells?: number | undefined;
3712
+ readonly maxOverlapTests?: number | undefined;
3713
+ };
3714
+ }
3715
+
3716
+ declare interface WorldGeometryDescriptor {
3717
+ readonly strategies: GeometryEditStrategies & GeometryDerivationStrategies & GeometryCompactionStrategies & {
3718
+ readonly migrateDelta: GeometryMigrateDelta;
3719
+ };
3720
+ readonly _tag: 'WorldGeometry';
3721
+ readonly kind: GeometryKind;
3722
+ readonly static: GeometrySource;
3723
+ readonly chunkSize: number;
3724
+ readonly chunkSizeRaw: number;
3725
+ readonly dynamic: {
3726
+ readonly enabled: boolean;
3727
+ readonly maxDeltaBytesPerChunk: number;
3728
+ readonly persist: {
3729
+ readonly everyMs: number;
3730
+ readonly onUnload: boolean;
3731
+ };
3732
+ };
3733
+ readonly collision: {
3734
+ readonly derive: 'bitgrid' | 'heightfield' | 'shapes';
3735
+ readonly resolution: number;
3736
+ readonly resolutionRaw: number;
3737
+ };
3738
+ readonly nav: {
3739
+ readonly derive: 'grid' | 'none';
3740
+ readonly navBudgetMs: number;
3741
+ readonly maxAdvanceSteps: number;
3742
+ };
3743
+ readonly streaming: {
3744
+ readonly client: {
3745
+ readonly radiusChunks: number;
3746
+ readonly prefetchChunks: number;
3747
+ readonly maxConcurrent: number;
3748
+ readonly maxCachedChunks: number;
3749
+ };
3750
+ readonly cell: {
3751
+ readonly marginChunks: number;
3752
+ };
3753
+ };
3754
+ readonly lod: ReadonlyArray<{
3755
+ readonly beyondChunks: number;
3756
+ readonly fields: ReadonlyArray<string>;
3757
+ }>;
3758
+ readonly budgets: {
3759
+ readonly maxPreparedChunks: number;
3760
+ readonly maxPreparedBytes: number;
3761
+ readonly maxLodLevels: number;
3762
+ readonly maxRayCells: number;
3763
+ readonly maxOverlapTests: number;
3764
+ };
3765
+ }
3766
+
3767
+ declare interface WorldGeometryStrategies extends GeometryVersionMigrationStrategies, Partial<GeometryEditStrategies>, Partial<GeometryDerivationStrategies>, Partial<GeometryCompactionStrategies> {
3768
+ }
3769
+
3770
+ declare interface WorldInstance {
3771
+ readonly id: string;
3772
+ readonly room: string;
3773
+ readonly maxGroups: number;
3774
+ readonly ttl: Duration.Input;
3775
+ }
3776
+
3777
+ declare type WorldLayerDecision = {
3778
+ readonly kind: 'use';
3779
+ readonly layer: number;
3780
+ readonly wake: boolean;
3781
+ } | {
3782
+ readonly kind: 'create';
3783
+ readonly layer: number;
3784
+ } | {
3785
+ readonly kind: 'blocked';
3786
+ readonly reason: 'affinity-unavailable' | 'capacity' | 'layer-budget';
3787
+ };
3788
+
3789
+ declare interface WorldLayering {
3790
+ readonly maxPlayers: number;
3791
+ readonly splitAt: number;
3792
+ readonly mergeBelow: number;
3793
+ }
3794
+
3795
+ declare interface WorldLayerInput {
3796
+ readonly policy: WorldLayering;
3797
+ readonly layers: ReadonlyArray<WorldLayerObservation>;
3798
+ readonly groupSize: number;
3799
+ /** Actual server-owned party affinity; never silently choose a different layer. */
3800
+ readonly affinity: number | null;
3801
+ readonly maxLayers: number;
3802
+ }
3803
+
3804
+ declare interface WorldLayerObservation {
3805
+ readonly layer: number;
3806
+ readonly players: number;
3807
+ readonly state: 'live' | 'hibernated' | 'splitting' | 'merging';
3808
+ }
3809
+
3810
+ declare type WorldLayerPolicy = (input: WorldLayerInput) => WorldLayerDecision;
3811
+
3812
+ declare interface WorldMovementIntent {
3813
+ readonly entityId: string;
3814
+ readonly sourceAt: WorldPoint;
3815
+ readonly targetAt: WorldPoint;
3816
+ readonly crossing: boolean;
3817
+ }
3818
+
3819
+ declare interface WorldMovementObservation {
3820
+ readonly epoch: number;
3821
+ readonly tick: number;
3822
+ readonly intents: ReadonlyArray<WorldMovementIntent>;
3823
+ }
3824
+
3825
+ declare type WorldOnWorldChange = (input: WorldOnWorldChangeInput) => unknown;
3826
+
3827
+ declare interface WorldOnWorldChangeInput {
3828
+ readonly sourceWorldId: string;
3829
+ readonly targetWorldId: string;
3830
+ /** Current server-captured character data, never a player's wire state. */
3831
+ readonly sourceData: unknown;
3832
+ /** Actual server-selected target data before this policy. */
3833
+ readonly targetData: unknown;
3834
+ }
3835
+
3836
+ declare type WorldPoint = readonly [x: number, y: number];
3837
+
3838
+ declare interface WorldPosition {
3839
+ readonly zone: string;
3840
+ readonly at: WorldPoint;
3841
+ }
3842
+
3843
+ /** Private durable restriction, never a bearer or a grant of transition authority.
3844
+ * The enclosing Seat supplies tenant, target Room, Subject and ownership epoch. */
3845
+ declare interface WorldTargetSeatBinding {
3846
+ readonly transitionId: string;
3847
+ readonly sourceRoomId: string;
3848
+ readonly requestId: string;
3849
+ readonly entityId: string;
3850
+ }
3851
+
3852
+ declare type WorldTransitionKind = 'cell' | 'layer' | 'zone' | 'world' | 'instance' | 'return' | 'recover';
3853
+
3854
+ declare interface WorldTransitionLocation extends WorldPosition {
3855
+ readonly world: string;
3856
+ readonly pool: string;
3857
+ readonly layer: number;
3858
+ readonly instance: string | null;
3859
+ }
3860
+
3861
+ declare type WorldTransitionMode = 'seamless' | 'portal' | 'recover';
3862
+
3863
+ declare interface WorldTransitionPlan {
3864
+ readonly kind: WorldTransitionKind;
3865
+ readonly mode: WorldTransitionMode;
3866
+ readonly crossPool: boolean;
3867
+ readonly persistBeforeRelease: boolean;
3868
+ readonly sourceCell: string;
3869
+ readonly targetCell: string;
3870
+ }
3871
+
3872
+ declare type WorldTransitionPolicy = (input: WorldTransitionPolicyInput) => WorldTransitionPlan;
3873
+
3874
+ declare interface WorldTransitionPolicyInput {
3875
+ readonly kind: WorldTransitionKind;
3876
+ readonly sourceWorld: AnyWorldDescriptor;
3877
+ readonly targetWorld: AnyWorldDescriptor;
3878
+ readonly source: WorldTransitionLocation;
3879
+ readonly target: WorldTransitionLocation;
3880
+ readonly mode: WorldTransitionMode | 'auto';
3881
+ readonly crossPool: boolean;
3882
+ /** Trusted server recovery classification, not a player intention field. */
3883
+ readonly recovery: boolean;
3884
+ }
3885
+
3886
+ declare interface WorldZone {
3887
+ readonly id: string;
3888
+ readonly bounds: WorldBounds;
3889
+ readonly room: string;
3890
+ readonly neighbors: ReadonlyArray<string>;
3891
+ readonly cells?: {
3892
+ readonly size: number;
3893
+ } | undefined;
3894
+ readonly layering?: WorldLayering;
3895
+ }
3896
+
3897
+ export { }