@hology/core 0.0.210 → 0.0.212

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 (129) hide show
  1. package/dist/effects/sequence/sequence-player.js +1 -1
  2. package/dist/effects/vfx/initializsers.d.ts +8 -1
  3. package/dist/effects/vfx/initializsers.js +1 -1
  4. package/dist/effects/vfx/vfx-collision-behaviour.js +1 -1
  5. package/dist/effects/vfx/vfx-defs.d.ts +10 -1
  6. package/dist/effects/vfx/vfx-defs.js +1 -1
  7. package/dist/effects/vfx/vfx-materializer.js +1 -1
  8. package/dist/effects/vfx/vfx-renderers.d.ts +1 -0
  9. package/dist/effects/vfx/vfx-renderers.js +1 -1
  10. package/dist/gameplay/actors/actor.d.ts +23 -1
  11. package/dist/gameplay/actors/actor.js +1 -1
  12. package/dist/gameplay/actors/builtin/components/character/character-animation.js +1 -1
  13. package/dist/gameplay/actors/builtin/components/character/character-movement-like.d.ts +23 -0
  14. package/dist/gameplay/actors/builtin/components/character/character-movement-like.js +4 -0
  15. package/dist/gameplay/actors/builtin/components/character/character-movement-policy.d.ts +26 -0
  16. package/dist/gameplay/actors/builtin/components/character/character-movement-policy.js +4 -0
  17. package/dist/gameplay/actors/builtin/components/character/character-movement.d.ts +145 -55
  18. package/dist/gameplay/actors/builtin/components/character/character-movement.js +1 -1
  19. package/dist/gameplay/actors/builtin/components/character/net-character-movement-protocol.d.ts +125 -0
  20. package/dist/gameplay/actors/builtin/components/character/net-character-movement-protocol.js +4 -0
  21. package/dist/gameplay/actors/builtin/components/character/old-character-movement.d.ts +100 -0
  22. package/dist/gameplay/actors/builtin/components/character/old-character-movement.js +4 -0
  23. package/dist/gameplay/actors/builtin/components/index.d.ts +2 -0
  24. package/dist/gameplay/actors/builtin/components/index.js +1 -1
  25. package/dist/gameplay/actors/builtin/navmesh-actor.js +1 -1
  26. package/dist/gameplay/actors/camera/third-person-camera-component.d.ts +3 -0
  27. package/dist/gameplay/actors/camera/third-person-camera-component.js +1 -1
  28. package/dist/gameplay/actors/component.js +1 -1
  29. package/dist/gameplay/actors/controller/actor-controller.d.ts +16 -0
  30. package/dist/gameplay/actors/controller/actor-controller.js +4 -0
  31. package/dist/gameplay/actors/factory.d.ts +3 -0
  32. package/dist/gameplay/actors/factory.js +1 -1
  33. package/dist/gameplay/actors/index.d.ts +4 -0
  34. package/dist/gameplay/actors/index.js +1 -1
  35. package/dist/gameplay/actors/internal/component-init.js +1 -1
  36. package/dist/gameplay/ai/behavior-tree/move.d.ts +2 -2
  37. package/dist/gameplay/index.d.ts +3 -1
  38. package/dist/gameplay/index.js +1 -1
  39. package/dist/gameplay/initiate.d.ts +4 -0
  40. package/dist/gameplay/initiate.js +1 -1
  41. package/dist/gameplay/net/browser/index.d.ts +147 -0
  42. package/dist/gameplay/net/browser/index.js +4 -0
  43. package/dist/gameplay/net/index.d.ts +7 -0
  44. package/dist/gameplay/net/index.js +4 -0
  45. package/dist/gameplay/net/net-connection.d.ts +25 -0
  46. package/dist/gameplay/net/net-connection.js +4 -0
  47. package/dist/gameplay/net/net-session.d.ts +70 -0
  48. package/dist/gameplay/net/net-session.js +4 -0
  49. package/dist/gameplay/net/service/net-actor-role.d.ts +12 -0
  50. package/dist/gameplay/net/service/net-actor-role.js +4 -0
  51. package/dist/gameplay/net/service/net-decorator.d.ts +29 -0
  52. package/dist/gameplay/net/service/net-decorator.js +4 -0
  53. package/dist/gameplay/net/service/net-serializer.d.ts +15 -0
  54. package/dist/gameplay/net/service/net-serializer.js +4 -0
  55. package/dist/gameplay/net/service/net-service.d.ts +171 -0
  56. package/dist/gameplay/net/service/net-service.js +4 -0
  57. package/dist/gameplay/net/service/net-utils.d.ts +8 -0
  58. package/dist/gameplay/net/service/net-utils.js +4 -0
  59. package/dist/gameplay/net/service/replication.d.ts +31 -0
  60. package/dist/gameplay/net/service/replication.js +4 -0
  61. package/dist/gameplay/net/service/rpc-decorator.d.ts +21 -0
  62. package/dist/gameplay/net/service/rpc-decorator.js +4 -0
  63. package/dist/gameplay/net/service/rpc.d.ts +35 -0
  64. package/dist/gameplay/net/service/rpc.js +4 -0
  65. package/dist/gameplay/services/asset-loader.d.ts +3 -2
  66. package/dist/gameplay/services/asset-loader.js +1 -1
  67. package/dist/gameplay/services/physics/abstract-physics-system.d.ts +1 -1
  68. package/dist/gameplay/services/physics/physics-system.d.ts +4 -2
  69. package/dist/gameplay/services/physics/physics-system.js +1 -1
  70. package/dist/gameplay/services/world.d.ts +13 -2
  71. package/dist/gameplay/services/world.js +1 -1
  72. package/dist/rendering/color-pass.js +1 -1
  73. package/dist/rendering.d.ts +2 -0
  74. package/dist/rendering.js +1 -1
  75. package/dist/scene/asset-resource-loader.js +1 -1
  76. package/dist/scene/batched-mesh-2.d.ts +9 -0
  77. package/dist/scene/batched-mesh-2.js +1 -1
  78. package/dist/scene/bootstrap.d.ts +2 -0
  79. package/dist/scene/bootstrap.js +1 -1
  80. package/dist/scene/custom-param-runtime-types.js +1 -1
  81. package/dist/scene/landscape/landscape-manager.d.ts +2 -1
  82. package/dist/scene/landscape/landscape-manager.js +1 -1
  83. package/dist/scene/materializer.d.ts +50 -1
  84. package/dist/scene/materializer.js +1 -1
  85. package/dist/scene/model.d.ts +2 -0
  86. package/dist/scene/scatter/painted-scatter-manager.d.ts +45 -0
  87. package/dist/scene/scatter/painted-scatter-manager.js +4 -0
  88. package/dist/scene/scatter/scatter-limits.d.ts +2 -0
  89. package/dist/scene/scatter/scatter-limits.js +4 -0
  90. package/dist/scene/scatter/surface-scatter-manager.js +1 -1
  91. package/dist/scene/storage/storage.d.ts +1 -1
  92. package/dist/scene/storage/storage.js +1 -1
  93. package/dist/shader/builtin/standard-shader.js +1 -1
  94. package/dist/shader/builtin/toon-shader.js +1 -1
  95. package/dist/shader/builtin/unlit-shader.js +1 -1
  96. package/dist/shader/color-layer.js +1 -1
  97. package/dist/shader/graph/compiler.d.ts +7 -4
  98. package/dist/shader/graph/compiler.js +1 -1
  99. package/dist/shader/graph/model.d.ts +1 -1
  100. package/dist/shader/graph/model.js +1 -1
  101. package/dist/shader/graph/parameters.js +1 -1
  102. package/dist/shader/parameter.d.ts +1 -1
  103. package/dist/shader/parameter.js +1 -1
  104. package/dist/shader/sprite-shader.js +1 -1
  105. package/dist/shader-nodes/depth.js +1 -1
  106. package/dist/shader-nodes/scene-sample.js +1 -1
  107. package/dist/test/batched-mesh-2.test.d.ts +2 -0
  108. package/dist/test/batched-mesh-2.test.js +4 -0
  109. package/dist/test/browser-net-session.test.d.ts +2 -0
  110. package/dist/test/browser-net-session.test.js +4 -0
  111. package/dist/test/first-person-camera-component.test.js +1 -1
  112. package/dist/test/net-character-movement.test.d.ts +2 -0
  113. package/dist/test/net-character-movement.test.js +4 -0
  114. package/dist/test/net-property-snapshot.test.d.ts +2 -0
  115. package/dist/test/net-property-snapshot.test.js +4 -0
  116. package/dist/test/painted-scatter-manager.test.d.ts +2 -0
  117. package/dist/test/painted-scatter-manager.test.js +4 -0
  118. package/dist/test/runtime-param-type-inference.test.js +1 -1
  119. package/dist/test/sequence-animation-retiming.test.js +1 -1
  120. package/dist/test/sequence-post-process.test.js +1 -1
  121. package/dist/test/shader-graph.test.js +1 -1
  122. package/dist/test/vfx-random-color-initializer.test.d.ts +2 -0
  123. package/dist/test/vfx-random-color-initializer.test.js +4 -0
  124. package/dist/test/world-prefab-spawn.test.d.ts +2 -0
  125. package/dist/test/world-prefab-spawn.test.js +4 -0
  126. package/dist/utils/three/placeholder-texture.d.ts +3 -0
  127. package/dist/utils/three/placeholder-texture.js +4 -0
  128. package/package.json +10 -2
  129. package/tsconfig.tsbuildinfo +1 -1
@@ -1,4 +1,4 @@
1
- import{ActorComponent as n}from"../component.js";const o=new WeakMap;export async function initComponents(n,c,s=!1){const i=[];for(const e of t(n,c,s)){if(o.has(e))continue;o.set(e,!0);const n=(async()=>{await e.onInit(),await initComponents(e,c,s)})();i.push(n)}return Promise.all(i)}export function initComponentsSync(n,c,s=!1){for(const i of t(n,c,s))o.has(i)||(o.set(i,!0),i.onInit(),initComponentsSync(i,c,s))}function t(o,t,c=!1){const s=[...Object.values(o)];o===t&&t.attachedComponents.forEach(n=>s.push(n));const i=[];for(const o of s)if(o instanceof n||null!=o?.constructor&&!0===o.constructor.__isActorComponent){const n=o;if(!isComponentEnabledInEnvironment(n,c))continue;n.actor=t,i.push(n)}return i}export function isComponentEnabledInEnvironment(n,o=!1){return!(o&&!n.constructor.__inEditor)&&!(!o&&n.constructor.__onlyEditor)}/*
1
+ import{ActorComponent as n}from"../component.js";const o=new WeakMap;export const $actorComponents=Symbol("actor_components");export async function initComponents(n,s,e=!1){const r=[];for(const i of c(n,s,e)){if(o.has(i))continue;t(s,i),o.set(i,!0);const n=(async()=>{await i.onInit(),await initComponents(i,s,e)})();r.push(n)}return Promise.all(r)}export function initComponentsSync(n,s,e=!1){for(const r of c(n,s,e))o.has(r)||(t(s,r),o.set(r,!0),r.onInit(),initComponentsSync(r,s,e))}function t(n,o){null==n[$actorComponents]&&(n[$actorComponents]=[]),n[$actorComponents].push(o),o.__netid=n[$actorComponents].length}function c(o,t,c=!1){const s=[...Object.values(o)];o===t&&t.attachedComponents.forEach(n=>s.push(n));const e=[];for(const o of s)if(o instanceof n||null!=o?.constructor&&!0===o.constructor.__isActorComponent){const n=o;if(!isComponentEnabledInEnvironment(n,c))continue;n.actor=t,e.push(n)}return e}export function isComponentEnabledInEnvironment(n,o=!1){return!(o&&!n.constructor.__inEditor)&&!(!o&&n.constructor.__onlyEditor)}/*
2
2
  * Copyright (©) 2026 Hology Interactive AB. All rights reserved.
3
3
  * See the LICENSE.md file for details.
4
4
  */
@@ -1,5 +1,5 @@
1
1
  import { Vector3 } from "three";
2
- import { CharacterMovementComponent } from "../../../gameplay/actors";
2
+ import type { CharacterMovementLike } from "../../../gameplay/actors";
3
3
  import { Navigation } from "../navigation";
4
4
  import { LeafNode, NodeState } from "./bt";
5
5
  export declare class CharacterMoveToNode extends LeafNode {
@@ -8,7 +8,7 @@ export declare class CharacterMoveToNode extends LeafNode {
8
8
  /** At what distance from the target movement should stop */
9
9
  distanceFrom: number;
10
10
  target: () => Vector3 | null | undefined;
11
- constructor(navigation: Navigation, movement: CharacterMovementComponent);
11
+ constructor(navigation: Navigation, movement: CharacterMovementLike);
12
12
  tick(dt: number): NodeState;
13
13
  }
14
14
  //# sourceMappingURL=move.d.ts.map
@@ -4,7 +4,7 @@ export * from './initiate.js';
4
4
  export * from './inject.js';
5
5
  export { Service, Inject } from 'typedi';
6
6
  export { ActorFactory } from './actors/factory.js';
7
- export { Actor, BaseActor } from './actors/actor.js';
7
+ export { Actor, BaseActor, getActorClassById } from './actors/actor.js';
8
8
  export { Component, ActorComponent, type ComponentOptions, attach, Attach } from './actors/component.js';
9
9
  export * from './services/world.js';
10
10
  export * from './services/game-time-scheduler.js';
@@ -21,4 +21,6 @@ export * from '../shader/parameter.js';
21
21
  export * from './ai/index.js';
22
22
  export * from '../effects/vfx/index.js';
23
23
  export * from './services/shader-provider.js';
24
+ export * from './net/net-connection.js';
25
+ export * from './net/net-session.js';
24
26
  //# sourceMappingURL=index.d.ts.map
@@ -1,4 +1,4 @@
1
- import"reflect-metadata";export{Container as DIContainer}from"typedi";export*from"./initiate.js";export*from"./inject.js";export{Service,Inject}from"typedi";export{ActorFactory}from"./actors/factory.js";export{Actor,BaseActor}from"./actors/actor.js";export{Component,ActorComponent,attach,Attach}from"./actors/component.js";export*from"./services/world.js";export*from"./services/game-time-scheduler.js";export*from"./services/camera-shake.js";export*from"./services/render.js";export*from"./services/physics/physics-system.js";export*from"./animation/anim-sm.js";export*from"./animation/root-motion.js";export*from"./services/asset-loader.js";export*from"./services/pointer-events.js";export{VisualEffect}from"../effects/vfx/vfx-param.js";export{DataAssetRef}from"../scene/objects/data-asset.js";export*from"../shader/parameter.js";export*from"./ai/index.js";export*from"../effects/vfx/index.js";export*from"./services/shader-provider.js";/*
1
+ import"reflect-metadata";export{Container as DIContainer}from"typedi";export*from"./initiate.js";export*from"./inject.js";export{Service,Inject}from"typedi";export{ActorFactory}from"./actors/factory.js";export{Actor,BaseActor,getActorClassById}from"./actors/actor.js";export{Component,ActorComponent,attach,Attach}from"./actors/component.js";export*from"./services/world.js";export*from"./services/game-time-scheduler.js";export*from"./services/camera-shake.js";export*from"./services/render.js";export*from"./services/physics/physics-system.js";export*from"./animation/anim-sm.js";export*from"./animation/root-motion.js";export*from"./services/asset-loader.js";export*from"./services/pointer-events.js";export{VisualEffect}from"../effects/vfx/vfx-param.js";export{DataAssetRef}from"../scene/objects/data-asset.js";export*from"../shader/parameter.js";export*from"./ai/index.js";export*from"../effects/vfx/index.js";export*from"./services/shader-provider.js";export*from"./net/net-connection.js";export*from"./net/net-session.js";/*
2
2
  * Copyright (©) 2026 Hology Interactive AB. All rights reserved.
3
3
  * See the LICENSE.md file for details.
4
4
  */
@@ -4,6 +4,7 @@ import { World } from './services/world.js';
4
4
  import { type DynamicResolutionOptions, type UpscalingOptions } from '../rendering.js';
5
5
  import { Observable } from 'rxjs';
6
6
  import { DetailTier } from "../scene/model.js";
7
+ import { NetSession } from "./net/net-session.js";
7
8
  import type { ParameterType } from "../shader/parameter.js";
8
9
  type GameClass<T> = Constructable<T>;
9
10
  export type InitiateGameConfig = {
@@ -51,6 +52,9 @@ export type InitiateGameConfig = {
51
52
  enabled?: boolean;
52
53
  };
53
54
  }>;
55
+ multi?: {
56
+ session: NetSession;
57
+ };
54
58
  };
55
59
  export declare function initiateGame<T_Game>(gameClass: GameClass<T_Game>, config: InitiateGameConfig): HologyRuntime<T_Game>;
56
60
  export declare abstract class GameInstance {
@@ -1,4 +1,4 @@
1
- import e from"typedi";import{loadScene as t}from"../scene/bootstrap.js";import{ActorFactory as s}from"./actors/factory.js";import{World as n}from"./services/world.js";import{SceneMaterializer as r}from"../scene/materializer.js";import{ViewController as o}from"./services/render.js";import{RenderingView as i}from"../rendering.js";import{PhysicsSystem as a}from"./services/physics/physics-system.js";import{MeshComponent as c}from"./actors/builtin/components/mesh-component.js";import{builtInComponents as d}from"./actors/builtin/components/index.js";import{activeContainerInstance as m}from"./actors/internal/container-map.js";import{InputService as l}from"./input/index.js";import{RuntimeAssetsService as p}from"../scene/runtime-asset-service.js";import{AssetResourceLoader as h}from"../scene/asset-resource-loader.js";import{AssetLoader as u}from"./services/asset-loader.js";import{polyfillClient as f}from"./polyfill.js";import{Subject as g}from"rxjs";import{PointerEvents as w}from"./services/pointer-events.js";import{RuntimeBundledBackendService as b}from"../scene/runtime-bundled-backend-service.js";import{Scene as j}from"three";import{ShaderProvider as v}from"./services/shader-provider.js";import{SceneDataService as y}from"../scene/scene-data-service.js";import{AssetsProvider as S}from"../scene/assets-provider.js";export function initiateGame(g,x){if(f(),0!=x.element.childNodes.length)return console.error("Can not initialize the game with a non-empty html element"),null;e.has(o);const I=e.of("default"),R=new HologyRuntime(I),P=new s(I,{inEditor:!1});var D;P.classes=x.actors,e.set(s,P),D=x.element,Object.assign(D.style,{position:"absolute",top:"0",left:"0",width:"100%",height:"100%",overflow:"hidden"});const A=new i(x.element,{enableXR:!0===x.xr?.enabled,maxPixelRatio:x.rendering?.maxPixelRatio,resolutionScale:x.rendering?.resolutionScale,dynamicResolution:x.rendering?.dynamicResolution,upscaling:x.rendering?.upscaling,msaa:x.rendering?.msaa,fpsCap:x.rendering?.fpsCap,depthPrepass:{enabled:!0===x.rendering?.depthPrepass?.enabled},bloom:{enabled:!1!==x?.rendering?.bloom?.enabled},reflection:{enabled:!1!==x?.rendering?.reflection?.enabled},shadows:{cascadeUpdateIntervals:[22,40,60,120]}});A.renderer.shadowMap.enabled=x.rendering?.shadows?.enabled??!0,A.renderer.shadowMap.autoUpdate=x.rendering?.shadows?.autoUpdate??!0,A.renderer.debug.checkShaderErrors=!1,e.set(i,A);const E=new o(A);e.set(o,E);const G=new b,O=new p(G),z=new h;z.setDataDir(x.dataDir),z.initKtx2(A.renderer);const C=Object.entries(x.shaders).map(([e,t])=>({name:e,type:t})),H=Object.entries(x.actors).map(([e,t])=>({name:e,type:t})),M={...d,...x.components??{}},T=Object.entries(M).map(([e,t])=>({name:e,type:t})),U=new v(C);e.set(v,U);const W=new u(z,O,C);e.set(S,O),e.set(h,z),e.set(u,W);const k=new j,F=new r(k,new y,O,z,A,C,H,P,T);e.set(r,F);const N=e.get(n);return e.set(n,N),N.materializer=F,(async()=>{const s=e.get(a);if(await s.start(),R.isShutdown)return;if(await G.preloadData(),R.isShutdown)return;N.scene=k;const{scene:n,actors:r}=await t(A,x.sceneName,x.dataDir,x.shaders,x.actors,M,P,G,O,z,{detailTier:x.detailTier});N.scene=n,s.scene=N.scene;for(const e of k.children)N.scene.add(e);if(R.isShutdown)return void A.stop();e.import([c]);for(const e of r)N.addActor(e);s.addFromScene(n),console.log("Start compile shaders"),console.time("compile shaders"),await A.compileAsync(),console.timeEnd("compile shaders"),console.log("Finished compile shaders. Programs: ",A.renderer.info.programs?.length??0),console.log("Start init scene textures"),console.time("init scene textures"),A.initTextures(),console.timeEnd("init scene textures");const o=I.get(l);A.loop(e=>{o.update(e)}),R.status=5,R.shutdownStarted.subscribe(()=>{z.disposeAll()}),m.value=I,I.remove(g),I.set({id:g,type:g});const i=I.get(g);m.value=null,R.gameInstance=i,I.get(w).start(),i instanceof GameInstance&&await i.onStart(),R._resolver(!0)})(),R}export class GameInstance{onStart(){}onShutdown(){}}export function createHologyScene(){}export class HologyRuntime{constructor(e){this.containerInstance=e,this.status=0,this.isShutdown=!1,this.shutdownStarted=new g,this.ready=new Promise(e=>{this._resolver=e})}getWorld(){return this.containerInstance.get(n)}getService(e){return this.containerInstance.get(e)}shutdown(){this.isShutdown=!0;const e=this.shutdownStarted;e.next(),e.complete(),this.gameInstance instanceof GameInstance&&this.gameInstance.onShutdown(),this.containerInstance.get(l).stop();const t=this.containerInstance.get(i);t?.stop();const s=this.containerInstance.get(o);s.setMuted(!0),s.dispose();for(const e of this.getWorld().actors)this.getWorld().removeActor(e);this.containerInstance.get(a).stop(),this.containerInstance.get(r).dispose(),this.containerInstance.get(w).stop(),this.containerInstance.reset()}}/*
1
+ import e from"typedi";import{loadScene as t}from"../scene/bootstrap.js";import{ActorFactory as s}from"./actors/factory.js";import{World as n}from"./services/world.js";import{SceneMaterializer as o}from"../scene/materializer.js";import{ViewController as r}from"./services/render.js";import{RenderingView as i}from"../rendering.js";import{PhysicsSystem as a}from"./services/physics/physics-system.js";import{MeshComponent as c}from"./actors/builtin/components/mesh-component.js";import{builtInComponents as d}from"./actors/builtin/components/index.js";import{activeContainerInstance as m}from"./actors/internal/container-map.js";import{InputService as l}from"./input/index.js";import{RuntimeAssetsService as p}from"../scene/runtime-asset-service.js";import{AssetResourceLoader as h}from"../scene/asset-resource-loader.js";import{AssetLoader as u}from"./services/asset-loader.js";import{polyfillClient as f}from"./polyfill.js";import{Subject as g}from"rxjs";import{PointerEvents as w}from"./services/pointer-events.js";import{RuntimeBundledBackendService as b}from"../scene/runtime-bundled-backend-service.js";import{Scene as j}from"three";import{ShaderProvider as v}from"./services/shader-provider.js";import{SceneDataService as S}from"../scene/scene-data-service.js";import{NetMode as y}from"./net/net-session.js";import{AssetsProvider as x}from"../scene/assets-provider.js";export function initiateGame(g,I){if(f(),0!=I.element.childNodes.length)return console.error("Can not initialize the game with a non-empty html element"),null;e.has(r);const R=e.of("default"),P=new HologyRuntime(R),D=new s(R,{inEditor:!1});var E;D.classes=I.actors,e.set(s,D),E=I.element,Object.assign(E.style,{position:"absolute",top:"0",left:"0",width:"100%",height:"100%",overflow:"hidden"});const M=new i(I.element,{enableXR:!0===I.xr?.enabled,maxPixelRatio:I.rendering?.maxPixelRatio,resolutionScale:I.rendering?.resolutionScale,dynamicResolution:I.rendering?.dynamicResolution,upscaling:I.rendering?.upscaling,msaa:I.rendering?.msaa,fpsCap:I.rendering?.fpsCap,depthPrepass:{enabled:!0===I.rendering?.depthPrepass?.enabled},bloom:{enabled:!1!==I?.rendering?.bloom?.enabled},reflection:{enabled:!1!==I?.rendering?.reflection?.enabled},shadows:{cascadeUpdateIntervals:[22,40,60,120]}});M.renderer.shadowMap.enabled=I.rendering?.shadows?.enabled??!0,M.renderer.shadowMap.autoUpdate=I.rendering?.shadows?.autoUpdate??!0,M.renderer.debug.checkShaderErrors=!1,e.set(i,M);const A=new r(M);e.set(r,A);const G=new b,O=new p(G),z=new h;z.setDataDir(I.dataDir),z.initKtx2(M.renderer);const C=Object.entries(I.shaders).map(([e,t])=>({name:e,type:t})),H=Object.entries(I.actors).map(([e,t])=>({name:e,type:t})),N={...d,...I.components??{}},T=Object.entries(N).map(([e,t])=>({name:e,type:t})),U=new v(C);e.set(v,U);const W=new u(z,O,C);e.set(x,O),e.set(h,z),e.set(u,W);const k=new j,F=new o(k,new S,O,z,M,C,H,D,T);F.inEditor=!1,F.netMode=I.multi?.session?.mode??y.none,e.set(o,F);const _=e.get(n);return e.set(n,_),_.materializer=F,(async()=>{const s=e.get(a);if(await s.start(),P.isShutdown)return;if(await G.preloadData(),P.isShutdown)return;if(_.scene=k,null!=I.multi?.session){const{NetService:e}=await import("./net/service/net-service.js"),t=R.get(e);t.session=I.multi.session,t.start(),P.shutdownStarted.subscribe(()=>t.stop())}const{scene:n,actors:o}=await t(M,I.sceneName,I.dataDir,I.shaders,I.actors,N,D,G,O,z,{detailTier:I.detailTier,nodeMode:I.multi?.session?.mode??y.none});_.scene=n,s.scene=_.scene;for(const e of k.children)_.scene.add(e);if(P.isShutdown)return void M.stop();e.import([c]);for(const e of o)_.addActor(e);s.addFromScene(n),console.log("Start compile shaders"),console.time("compile shaders"),await M.compileAsync(),console.timeEnd("compile shaders"),console.log("Finished compile shaders. Programs: ",M.renderer.info.programs?.length??0),console.log("Start init scene textures"),console.time("init scene textures"),M.initTextures(),console.timeEnd("init scene textures");const r=R.get(l);M.loop(e=>{r.update(e)}),P.status=5,P.shutdownStarted.subscribe(()=>{z.disposeAll()}),m.value=R,R.remove(g),R.set({id:g,type:g});const i=R.get(g);m.value=null,P.gameInstance=i,R.get(w).start(),i instanceof GameInstance&&await i.onStart(),P._resolver(!0)})(),P}export class GameInstance{onStart(){}onShutdown(){}}export function createHologyScene(){}export class HologyRuntime{constructor(e){this.containerInstance=e,this.status=0,this.isShutdown=!1,this.shutdownStarted=new g,this.ready=new Promise(e=>{this._resolver=e})}getWorld(){return this.containerInstance.get(n)}getService(e){return this.containerInstance.get(e)}shutdown(){this.isShutdown=!0;const e=this.shutdownStarted;e.next(),e.complete(),this.gameInstance instanceof GameInstance&&this.gameInstance.onShutdown(),this.containerInstance.get(l).stop();const t=this.containerInstance.get(i);t?.stop();const s=this.containerInstance.get(r);s.setMuted(!0),s.dispose();for(const e of this.getWorld().actors)this.getWorld().removeActor(e);this.containerInstance.get(a).stop(),this.containerInstance.get(o).dispose(),this.containerInstance.get(w).stop(),this.containerInstance.reset(),this.shutdownStarted.complete()}}/*
2
2
  * Copyright (©) 2026 Hology Interactive AB. All rights reserved.
3
3
  * See the LICENSE.md file for details.
4
4
  */
@@ -0,0 +1,147 @@
1
+ import { BehaviorSubject, Subject } from 'rxjs';
2
+ import { NetReceivedMessage, NetSession, NetMode } from '../net-session';
3
+ import { NetConnection } from '../net-connection';
4
+ export type BrowserNetSimulationOptions = {
5
+ /**
6
+ * Fixed one-way latency applied to outgoing messages from this session.
7
+ */
8
+ latencyMs?: number;
9
+ /**
10
+ * Random +/- latency added on top of latencyMs.
11
+ */
12
+ jitterMs?: number;
13
+ /**
14
+ * Drop chance for unreliable messages, from 0 to 1.
15
+ */
16
+ packetLoss?: number;
17
+ /**
18
+ * Optional drop chance for reliable messages. Defaults to 0 so reliable
19
+ * traffic remains reliable unless a test deliberately breaks it.
20
+ */
21
+ reliablePacketLoss?: number;
22
+ };
23
+ export type BrowserNetSessionOptions = BrowserNetSimulationOptions & {
24
+ /**
25
+ * How often this tab refreshes its membership entry. Set to 0 to disable.
26
+ */
27
+ heartbeatIntervalMs?: number;
28
+ /**
29
+ * Members without a recent heartbeat are removed from the local view.
30
+ */
31
+ memberTimeoutMs?: number;
32
+ /**
33
+ * Prevents a paused consumer from growing the inbound queue forever.
34
+ */
35
+ maxQueuedMessages?: number;
36
+ };
37
+ export declare class BrowserNetSession implements NetSession {
38
+ /** The id of the session */
39
+ private sessionId;
40
+ /** The ID used by this node. */
41
+ private localId;
42
+ /**
43
+ * A unique ID for this sessions
44
+ */
45
+ id: string;
46
+ /**
47
+ * The network mode from this player's point of view.
48
+ */
49
+ readonly mode: NetMode;
50
+ /**
51
+ * Convenience function to check if mode === NetworkRole.client
52
+ */
53
+ get isClient(): boolean;
54
+ /**
55
+ * Convenience function to check if you are authoritative
56
+ */
57
+ get isServer(): boolean;
58
+ /**
59
+ * Convenience function to check if mode === NetworkRole.dedicatedServer
60
+ */
61
+ get isDedicatedServer(): boolean;
62
+ /**
63
+ * The server holds connections to all other clients.
64
+ */
65
+ get clients(): NetConnection[];
66
+ /**
67
+ * Clients hold a connection to the server
68
+ */
69
+ get server(): NetConnection;
70
+ readonly playerLeft: Subject<NetConnection>;
71
+ readonly playerJoined: Subject<NetConnection>;
72
+ readonly receivedMessageCount: BehaviorSubject<number>;
73
+ constructor(
74
+ /** Initialize with a specific role */
75
+ mode: NetMode,
76
+ /** The id of the session */
77
+ sessionId: string,
78
+ /** The ID used by this node. */
79
+ localId: number, options?: BrowserNetSessionOptions);
80
+ /**
81
+ * Adjust local network simulation at runtime. The settings only affect
82
+ * messages sent by this BrowserNetSession instance.
83
+ */
84
+ configureNetworkSimulation(options: BrowserNetSimulationOptions): void;
85
+ /**
86
+ * Attempt to reconnect back to a session.
87
+ */
88
+ reconnect(): void;
89
+ /**
90
+ * Leave the session and disonnect from other clients/server
91
+ */
92
+ disconnect(): void;
93
+ sendMessage(receiver: NetConnection, reliable: boolean, buffer: ArrayBufferLike): void;
94
+ /**
95
+ * Use this method to check if there is any messages to read.
96
+ * Returns the number of messages available.
97
+ */
98
+ hasMessage(): number;
99
+ /**
100
+ * Consumes a received message and removes it
101
+ */
102
+ readMessage(): NetReceivedMessage | null;
103
+ connect(): void;
104
+ private readonly storageKey;
105
+ private readonly channelName;
106
+ private readonly heartbeatIntervalMs;
107
+ private readonly memberTimeoutMs;
108
+ private readonly maxQueuedMessages;
109
+ private simulation;
110
+ private connected;
111
+ private storage;
112
+ private channel;
113
+ private heartbeatTimer;
114
+ private receivedMessages;
115
+ private readonly knownMemberIds;
116
+ private readonly pendingDeliveryTimers;
117
+ private readonly reliableQueues;
118
+ private messageSequence;
119
+ private readonly onStorage;
120
+ private readonly onChannelMessage;
121
+ private readonly onBeforeUnload;
122
+ private readonly onUnload;
123
+ private sendOrSimulateMessage;
124
+ private deliverMessage;
125
+ private enqueueReceivedMessage;
126
+ private consumeMessage;
127
+ private connectionForMessage;
128
+ private enqueueReliableDelivery;
129
+ private scheduleReliableDelivery;
130
+ private flushReliableDelivery;
131
+ private shouldDropMessage;
132
+ private simulatedDelayMs;
133
+ private startHeartbeat;
134
+ private stopHeartbeat;
135
+ private cancelPendingDeliveries;
136
+ private mergeMember;
137
+ private removeMember;
138
+ private setMembers;
139
+ private currentMembers;
140
+ private activeMembers;
141
+ private createLocalMember;
142
+ private createMessageId;
143
+ private broadcast;
144
+ private getLocalStorage;
145
+ private writeLocalStorage;
146
+ }
147
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,4 @@
1
+ import{BehaviorSubject as e,Subject as s}from"rxjs";import{NetMode as t}from"../net-session";const n=0,i=0,r=0,o=0;export class BrowserNetSession{get isClient(){return this.mode===t.client}get isServer(){return this.mode<t.client}get isDedicatedServer(){return this.mode===t.dedicatedServer}get clients(){return this.isServer?this.currentMembers().filter(e=>e.mode===t.client).map(e=>a(e)):[]}get server(){if(!this.isServer){const e=this.currentMembers().find(e=>e.mode<t.client);if(null!=e)return a(e)}return null}constructor(t,n,i,r={}){this.sessionId=n,this.localId=i,this.playerLeft=new s,this.playerJoined=new s,this.receivedMessageCount=new e(0),this.storageKey=`net_session_${this.sessionId}`,this.channelName=`net_session_${this.sessionId}`,this.connected=!1,this.storage=null,this.channel=null,this.heartbeatTimer=null,this.receivedMessages=[],this.knownMemberIds=new Set,this.pendingDeliveryTimers=new Set,this.reliableQueues=new Map,this.messageSequence=0,this.onStorage=e=>{if(e.key!==this.storageKey)return;const s=this.getLocalStorage();this.setMembers(s?.members??[],!0)},this.onChannelMessage=e=>{const s=e.data;if(function(e){if(null==e||"object"!=typeof e)return!1;const s=e.kind;return"join"===s||"leave"===s||"heartbeat"===s||"members-request"===s||"members"===s||"message"===s}(s)&&s.sessionId===this.sessionId&&s.sourceConnectionId!==this.localId)switch(s.kind){case"join":case"heartbeat":this.mergeMember(s.member,!0);break;case"leave":this.removeMember(s.member.connectionId,!0);break;case"members-request":this.broadcast({kind:"members",sessionId:this.sessionId,sourceConnectionId:this.localId,members:this.currentMembers()});break;case"members":this.setMembers([...this.currentMembers(),...s.members],!0);break;case"message":this.mergeMember(s.fromMember,!0),s.message.toConnectionId===this.localId&&this.enqueueReceivedMessage(s.message)}},this.onBeforeUnload=()=>{this.disconnect()},this.onUnload=()=>{this.disconnect()},this.mode=t,this.id=n,this.simulation=l(r),this.heartbeatIntervalMs=Math.max(0,r.heartbeatIntervalMs??2e3),this.memberTimeoutMs=Math.max(1,r.memberTimeoutMs??1e4),this.maxQueuedMessages=Math.max(1,r.maxQueuedMessages??1e4)}configureNetworkSimulation(e){this.simulation=l({...this.simulation,...e})}reconnect(){this.disconnect(),this.connect()}disconnect(){this.connected&&this.broadcast({kind:"leave",sessionId:this.sessionId,sourceConnectionId:this.localId,member:this.createLocalMember()}),this.stopHeartbeat(),this.cancelPendingDeliveries(),this.connected&&(window.removeEventListener("storage",this.onStorage),window.removeEventListener("beforeunload",this.onBeforeUnload),window.removeEventListener("unload",this.onUnload),this.channel?.removeEventListener("message",this.onChannelMessage),this.channel?.close(),this.channel=null,this.connected=!1);const e=this.getLocalStorage(),s=(e?.members??this.storage?.members??[]).filter(e=>e.connectionId!==this.localId);this.writeLocalStorage({members:this.activeMembers(s)}),this.storage=null,this.knownMemberIds.clear(),this.receivedMessages=[],this.receivedMessageCount.next(0)}sendMessage(e,s,t){const n=function(e){const s=(e.id,Number(e.id));return Number.isFinite(s)?s:null}(e);if(null==n)return void console.error(`BrowserNetSession can only send to numeric connection ids. Received ${e.id}`);const i={id:this.createMessageId(),fromConnectionId:this.localId,toConnectionId:n,reliable:s,sentAt:Date.now(),buffer:c(t)};this.sendOrSimulateMessage(i,s)}hasMessage(){return this.receivedMessages.length}readMessage(){const e=this.consumeMessage();if(null!=e){const s=this.connectionForMessage(e);return null==s?(console.error(`No connection found with id ${e.fromConnectionId}`),null):{from:s,buffer:e.buffer}}return null}connect(){if(this.connected)return;if("undefined"==typeof BroadcastChannel)throw new Error("BrowserNetSession requires BroadcastChannel support");this.channel=new BroadcastChannel(this.channelName),this.channel.addEventListener("message",this.onChannelMessage),window.addEventListener("storage",this.onStorage),window.addEventListener("beforeunload",this.onBeforeUnload),window.addEventListener("unload",this.onUnload),this.connected=!0;const e=this.getLocalStorage()??{members:[]},s=this.activeMembers([...e.members,this.createLocalMember()]);this.setMembers(s,!1),this.writeLocalStorage({members:s}),this.broadcast({kind:"join",sessionId:this.sessionId,sourceConnectionId:this.localId,member:this.createLocalMember()}),this.broadcast({kind:"members-request",sessionId:this.sessionId,sourceConnectionId:this.localId}),this.startHeartbeat()}sendOrSimulateMessage(e,s){if(this.shouldDropMessage(s))return;if(s)return void this.enqueueReliableDelivery(e);const t=this.simulatedDelayMs();if(t<=0)return void this.deliverMessage(e);const n=window.setTimeout(()=>{this.pendingDeliveryTimers.delete(n),this.deliverMessage(e)},t);this.pendingDeliveryTimers.add(n)}deliverMessage(e){e.toConnectionId!==this.localId?this.broadcast({kind:"message",sessionId:this.sessionId,sourceConnectionId:this.localId,fromMember:this.createLocalMember(),message:e}):this.enqueueReceivedMessage(e)}enqueueReceivedMessage(e){this.receivedMessages.length>=this.maxQueuedMessages&&this.receivedMessages.shift(),this.receivedMessages.push(e),this.receivedMessageCount.next(this.receivedMessages.length)}consumeMessage(){const e=this.receivedMessages.shift()??null;return this.receivedMessageCount.next(this.receivedMessages.length),e}connectionForMessage(e){const s=this.server;if(s?.id===e.fromConnectionId)return s;const t=this.clients.find(s=>s.id===e.fromConnectionId);if(null!=t)return t;const n=this.currentMembers().find(s=>s.connectionId===e.fromConnectionId);return null!=n?a(n):null}enqueueReliableDelivery(e){const s=this.simulatedDelayMs(),t=this.reliableQueues.get(e.toConnectionId);if((null==t||0===t.messages.length)&&s<=0)return void this.deliverMessage(e);const n=Date.now(),i=t??{messages:[],timer:null},r=i.messages[i.messages.length-1]?.deliveryAt??n,o=Math.max(n+s,r);i.messages.push({message:e,deliveryAt:o}),this.reliableQueues.set(e.toConnectionId,i),this.scheduleReliableDelivery(e.toConnectionId,i)}scheduleReliableDelivery(e,s){if(null!=s.timer||0===s.messages.length)return;const t=Math.max(0,s.messages[0].deliveryAt-Date.now()),n=window.setTimeout(()=>{this.pendingDeliveryTimers.delete(n),s.timer=null,this.flushReliableDelivery(e)},t);s.timer=n,this.pendingDeliveryTimers.add(n)}flushReliableDelivery(e){const s=this.reliableQueues.get(e);if(null==s)return;const t=Date.now();for(;s.messages.length>0&&s.messages[0].deliveryAt<=t+1;)this.deliverMessage(s.messages.shift().message);s.messages.length>0?this.scheduleReliableDelivery(e,s):this.reliableQueues.delete(e)}shouldDropMessage(e){const s=e?this.simulation.reliablePacketLoss:this.simulation.packetLoss;return s>0&&Math.random()<s}simulatedDelayMs(){const e=this.simulation.jitterMs>0?(2*Math.random()-1)*this.simulation.jitterMs:0;return Math.max(0,this.simulation.latencyMs+e)}startHeartbeat(){this.heartbeatIntervalMs<=0||null!=this.heartbeatTimer||(this.heartbeatTimer=window.setInterval(()=>{const e=this.activeMembers([...this.currentMembers(),this.createLocalMember()]);this.setMembers(e,!0),this.writeLocalStorage({members:e}),this.broadcast({kind:"heartbeat",sessionId:this.sessionId,sourceConnectionId:this.localId,member:this.createLocalMember()})},this.heartbeatIntervalMs))}stopHeartbeat(){null!=this.heartbeatTimer&&(clearInterval(this.heartbeatTimer),this.heartbeatTimer=null)}cancelPendingDeliveries(){this.pendingDeliveryTimers.forEach(e=>clearTimeout(e)),this.pendingDeliveryTimers.clear(),this.reliableQueues.clear()}mergeMember(e,s){this.setMembers([...this.currentMembers(),e],s)}removeMember(e,s){this.setMembers(this.currentMembers().filter(s=>s.connectionId!==e),s)}setMembers(e,s){const t=this.storage?.members??[],n=this.activeMembers(this.connected?[...e,this.createLocalMember()]:e);if(s){const e=new Set(n.map(e=>e.connectionId));n.filter(e=>e.connectionId!==this.localId&&!this.knownMemberIds.has(e.connectionId)).forEach(e=>this.playerJoined.next(a(e))),this.knownMemberIds.forEach(s=>{if(s===this.localId||e.has(s))return;const n=t.find(e=>e.connectionId===s);null!=n&&this.playerLeft.next(a(n))})}this.storage={members:n},this.knownMemberIds.clear(),n.forEach(e=>this.knownMemberIds.add(e.connectionId))}currentMembers(){return this.activeMembers(this.storage?.members??this.getLocalStorage()?.members??[])}activeMembers(e){const s=Date.now();return function(e){const s=new Map;for(const t of e){if(!Number.isFinite(t.connectionId))continue;const e=s.get(t.connectionId);(null==e||(t.lastSeenAt??0)>=(e.lastSeenAt??0))&&s.set(t.connectionId,t)}return[...s.values()].sort((e,s)=>e.connectionId-s.connectionId)}(e).filter(e=>e.connectionId===this.localId||null!=e.lastSeenAt&&s-e.lastSeenAt<=this.memberTimeoutMs)}createLocalMember(){return{connectionId:this.localId,mode:this.mode,player:{id:this.localId.toString()},lastSeenAt:Date.now()}}createMessageId(){const e=window.crypto?.randomUUID;return"function"==typeof e?e.call(window.crypto):`${this.localId}-${Date.now()}-${this.messageSequence++}`}broadcast(e){this.channel?.postMessage(e)}getLocalStorage(){const e=localStorage.getItem(this.storageKey);if(null!=e)try{const s=JSON.parse(e);if(Array.isArray(s?.members))return{members:s.members}}catch(e){console.warn(`Failed to parse browser net session ${this.sessionId}`,e)}return null}writeLocalStorage(e){const s=this.activeMembers(e.members);0!==s.length?localStorage.setItem(this.storageKey,JSON.stringify({members:s})):localStorage.removeItem(this.storageKey)}}function a(e){return{id:e.connectionId,player:e.player}}function c(e){const s=new Uint8Array(e),t=new Uint8Array(s.byteLength);return t.set(s),t.buffer}function l(e){return{latencyMs:Math.max(0,e.latencyMs??n),jitterMs:Math.max(0,e.jitterMs??i),packetLoss:h(e.packetLoss??r),reliablePacketLoss:h(e.reliablePacketLoss??o)}}function h(e){return Math.min(1,Math.max(0,e))}/*
2
+ * Copyright (©) 2026 Hology Interactive AB. All rights reserved.
3
+ * See the LICENSE.md file for details.
4
+ */
@@ -0,0 +1,7 @@
1
+ export * from './service/rpc-decorator.js';
2
+ export * from './service/rpc.js';
3
+ export * from './service/net-service.js';
4
+ export * from './service/replication.js';
5
+ export * from './service/net-decorator.js';
6
+ export * from './service/net-actor-role.js';
7
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,4 @@
1
+ export*from"./service/rpc-decorator.js";export*from"./service/rpc.js";export*from"./service/net-service.js";export*from"./service/replication.js";export*from"./service/net-decorator.js";export*from"./service/net-actor-role.js";/*
2
+ * Copyright (©) 2026 Hology Interactive AB. All rights reserved.
3
+ * See the LICENSE.md file for details.
4
+ */
@@ -0,0 +1,25 @@
1
+ /**
2
+ * Each participant in a networked game including clients, dedicated servers and listen servers,
3
+ * each are represented by a single connection.
4
+ */
5
+ export interface NetConnection {
6
+ readonly id: string | bigint | number;
7
+ /**
8
+ * Player connected to this client.
9
+ * Not present for dedicated servers
10
+ */
11
+ readonly player?: NetPlayerInfo;
12
+ }
13
+ /**
14
+ * Information that represents the player.
15
+ */
16
+ export interface NetPlayerInfo {
17
+ /**
18
+ * An ID of a player. This may refer to an account id or some other persistent information.
19
+ * This can be used by the server to load data for this user.
20
+ * The NetSession implementation is responsible for authenticating users and providing
21
+ * the player ID.
22
+ */
23
+ readonly id: string;
24
+ }
25
+ //# sourceMappingURL=net-connection.d.ts.map
@@ -0,0 +1,4 @@
1
+ export{};/*
2
+ * Copyright (©) 2026 Hology Interactive AB. All rights reserved.
3
+ * See the LICENSE.md file for details.
4
+ */
@@ -0,0 +1,70 @@
1
+ import { Observable } from "rxjs";
2
+ import { NetConnection } from "./net-connection.js";
3
+ export declare enum NetMode {
4
+ /**
5
+ * Game is played locally so it has authority but no other clients are connected.
6
+ * This game be supported by NetSession implmentations that support later connecting
7
+ * to a game hosting a server.
8
+ */
9
+ none = 1,
10
+ /**
11
+ * The server runs the game but has no po player
12
+ */
13
+ dedicatedServer = 2,
14
+ /**
15
+ * One client's game acts as a server and other clients are connected
16
+ * via P2P.
17
+ */
18
+ listenServer = 3,
19
+ /**
20
+ * A client is connected to a server and doesn't have authority.
21
+ * Should be sending inputs to the server to affect important state.
22
+ */
23
+ client = 4
24
+ }
25
+ export interface NetSession {
26
+ /**
27
+ * A unique ID for this sessions
28
+ */
29
+ id: string;
30
+ /**
31
+ * The network mode from this player's point of view.
32
+ */
33
+ readonly mode: NetMode;
34
+ /**
35
+ * The server holds connections to all other clients.
36
+ */
37
+ readonly clients: NetConnection[];
38
+ /**
39
+ * Clients hold a connection to the server
40
+ */
41
+ readonly server: NetConnection;
42
+ /**
43
+ * Attempt to reconnect back to a session.
44
+ */
45
+ reconnect(): void;
46
+ /**
47
+ * Leave the session and disonnect from other clients/server
48
+ */
49
+ disconnect(): void;
50
+ sendMessage(receiver: NetConnection, reliable: boolean, buffer: ArrayBufferLike): void;
51
+ /**
52
+ * Use this method to check if there is any messages to read.
53
+ * Returns the number of messages available.
54
+ */
55
+ hasMessage(): number;
56
+ /**
57
+ * Consumes a received message and removes it.
58
+ * Messages should be consumed at an appropriate time rather than randomly whenever received.
59
+ * For example, avoid using the render loop to read messages as its order is not deterministic.
60
+ * You may want to process all messages at a single point in time before any other processing.
61
+ */
62
+ readMessage(): NetReceivedMessage | null;
63
+ readonly playerLeft: Observable<NetConnection>;
64
+ readonly playerJoined: Observable<NetConnection>;
65
+ }
66
+ export type NetReceivedMessage = {
67
+ from: NetConnection;
68
+ buffer: ArrayBufferLike;
69
+ };
70
+ //# sourceMappingURL=net-session.d.ts.map
@@ -0,0 +1,4 @@
1
+ export var NetMode;!function(e){e[e.none=1]="none",e[e.dedicatedServer=2]="dedicatedServer",e[e.listenServer=3]="listenServer",e[e.client=4]="client"}(NetMode||(NetMode={}));/*
2
+ * Copyright (©) 2026 Hology Interactive AB. All rights reserved.
3
+ * See the LICENSE.md file for details.
4
+ */
@@ -0,0 +1,12 @@
1
+ /**
2
+ * The NetRole is sent by the server and set on actors so that
3
+ * they can understan what control they have on the actor without
4
+ * knowing the connection ownership.
5
+ */
6
+ export declare enum NetRole {
7
+ authority = 0,// Server's authoritative instance
8
+ autonomousProxy = 1,// Client-owned instance (owner's client)
9
+ simulatedProxy = 2,// Non-owner client instance
10
+ none = 3
11
+ }
12
+ //# sourceMappingURL=net-actor-role.d.ts.map
@@ -0,0 +1,4 @@
1
+ export var NetRole;!function(o){o[o.authority=0]="authority",o[o.autonomousProxy=1]="autonomousProxy",o[o.simulatedProxy=2]="simulatedProxy",o[o.none=3]="none"}(NetRole||(NetRole={}));/*
2
+ * Copyright (©) 2026 Hology Interactive AB. All rights reserved.
3
+ * See the LICENSE.md file for details.
4
+ */
@@ -0,0 +1,29 @@
1
+ import { ReplOn } from "./replication";
2
+ /**
3
+ * Ensures that this function is only executed if on the server.
4
+ * This can be used to prevent executing something on the client
5
+ * in response to some other game play event that requires authority.
6
+ *
7
+ * Example:
8
+ * - An explosion does a random amount of damage to all actors nearby. A function is called
9
+ * on the actor to respond to the damage. The explosion also happens
10
+ * on clients but we don't know the exact amount of damage to apply because it is random.
11
+ * We instead want to let the server handle this and inform clients after.
12
+ */
13
+ export declare function RunIfServer(): (originalMethod: Function, context: ClassMethodDecoratorContext) => (this: any, ...args: any[]) => any;
14
+ /**
15
+ * Ensures that this function is only executed if on the client.
16
+ * Note that this only includes those that are not also servers like standalone and listen servers.
17
+ */
18
+ export declare function RunIfClient(): (originalMethod: Function, context: ClassMethodDecoratorContext) => (this: any, ...args: any[]) => any;
19
+ /**
20
+ * Ensures that this function is only executed if on an instance of the game with a player
21
+ * Useful for logic that should only run on the client, such as UI updates, visual effects, playing sound.
22
+ */
23
+ export declare function RunIfNotDedicatedServer(): (originalMethod: Function, context: ClassMethodDecoratorContext) => (this: any, ...args: any[]) => any;
24
+ /**
25
+ * Marks a property to be automatically replicated to clients.
26
+ * This is a placeholder; actual replication logic would be handled by the networking system.
27
+ */
28
+ export declare function Replicated(replicatedOn?: ReplOn, reliable?: boolean): (target: undefined, context: ClassMemberDecoratorContext) => void;
29
+ //# sourceMappingURL=net-decorator.d.ts.map
@@ -0,0 +1,4 @@
1
+ import{BaseActor as t}from"../../actors/actor";import{NetService as e}from"./net-service";import{inject as n}from"../../inject";import{ReplOn as r}from"./replication";import{isSignalLike as i}from"./net-utils";import{ActorComponent as o}from"../../actors/component";export function RunIfServer(){return function(r,i){let o;return i.addInitializer(function(){this instanceof t?o=n(e):console.warn("RunIfServer should not be defined on a non actor")}),function(...t){if(o.isServer)return r.apply(this,t)}}}export function RunIfClient(){return function(r,i){let o;return i.addInitializer(function(){this instanceof t?o=n(e):console.warn("RunIfClient should not be defined on a non actor")}),function(...t){if(!o.isServer)return r.apply(this,t)}}}export function RunIfNotDedicatedServer(){return function(r,i){let o;return i.addInitializer(function(){this instanceof t?o=n(e):console.warn("RunIfClient should not be defined on a non actor")}),function(...t){if(!o.isDedicatedServer)return r.apply(this,t)}}}export function Replicated(s=r.all,c=!0){return function(r,a){let f;a.addInitializer(function(){if(!(this instanceof t||this instanceof o))return void console.warn("RunIfClient should not only be used on actors and actor components");let r,u;if(this instanceof t)r=this;else if(this instanceof o&&(r=this.actor,u=this,null==r))return;f=n(e),f.registerReplicatedProperty(s,c,r,a.name.toString(),this,u);const l=this[a.name];if(i(l)){const t=l.subscribe(t=>{if(f.isServer){if(null==r.__netid)return;f.handlePropertySet(s,c,r,a.name.toString(),t,u)}});return void r.disposed.subscribe(()=>{t()})}let d=l;Object.defineProperty(this,a.name,{set:t=>{f.isServer&&f.handlePropertySet(s,c,r,a.name.toString(),t,u),d=t},get:()=>d})})}}export function makePropertyReplicated(t,e,n,r,i){n.registerReplicatedProperty(i,r,t,e,this,null);let o=t[e];Object.defineProperty(t,e,{set:s=>{n.isServer&&n.handlePropertySet(i,r,t,e,s,null),o=s},get:()=>o})}/*
2
+ * Copyright (©) 2026 Hology Interactive AB. All rights reserved.
3
+ * See the LICENSE.md file for details.
4
+ */
@@ -0,0 +1,15 @@
1
+ export declare class NetSerializer {
2
+ private world;
3
+ private assetLoader;
4
+ encode(data: unknown): string;
5
+ decode(data: string, result: DecodeResult): unknown;
6
+ private wrapObject;
7
+ private unwrapObject;
8
+ /**
9
+ * Mutates the result from decode to resolve all assets
10
+ * but leaving already decoded values as they are.
11
+ * @returns
12
+ */
13
+ decodeAssets(obj: unknown): Promise<unknown>;
14
+ }
15
+ //# sourceMappingURL=net-serializer.d.ts.map
@@ -0,0 +1,4 @@
1
+ import{__decorate as r}from"tslib";import{World as t}from"../../services/world";import{inject as e}from"../../inject";import{Service as s}from"typedi";import{BaseActor as n}from"../../actors/actor";import{Euler as o,Quaternion as i,Vector2 as a,Vector3 as c,Vector4 as f}from"three";import{DataAssetRef as u}from"../../../scene/objects/data-asset";import{AssetLoader as l}from"../../services/asset-loader";const p="-a",m="-v2",d="-v3",w="-v4",y="-e",A="-q",h="-s",b="-m",j="-dar";export class DecodeResult{constructor(){this.error=!1,this.requiresAssetLookups=!1}reset(){this.error=!1,this.missingActorId=void 0,this.requiresAssetLookups=!1}}let O=class{constructor(){this.world=e(t),this.assetLoader=e(l)}encode(r){return JSON.stringify(this.wrapObject(r))}decode(r,t){t.reset();const e=JSON.parse(r);return this.unwrapObject(e,t)}wrapObject(r){if(null!=r&&"object"==typeof r){if(Array.isArray(r))return r.map(r=>this.wrapObject(r));if(r instanceof n){if(null!=r.__netid)return{[p]:r.__netid};console.warn("Missing netid on actor",r)}else{if(r instanceof a)return{[m]:r.toArray([])};if(r instanceof c)return{[d]:r.toArray([])};if(r instanceof f)return{[w]:r.toArray([])};if(r instanceof o)return{[y]:r.toArray([])};if(r instanceof i)return{[A]:r.toArray([])};if(r instanceof Map)return{[b]:Array.from(r.entries()).map(([r,t])=>[r,this.wrapObject(t)])};if(r instanceof Set)return{[h]:Array.from(r.values()).map(r=>this.wrapObject(r))};if(r instanceof u)return{[j]:r.id}}const t={};for(const e of Object.keys(r))t[e]=this.wrapObject(r[e]);return t}return r}unwrapObject(r,t){if(null!=r&&"object"==typeof r){if(Array.isArray(r))return r.map(r=>this.unwrapObject(r,t));{if(null!=r[p]){const e=r[p],s=this.world.actors.find(r=>r.__netid===e);return null==s&&(t.error=!0,t.missingActorId=e,console.warn(`Failed to find replicated actor with netid "${e}"`)),s}if(null!=r[m]){const t=r[m];return(new a).fromArray(t)}if(null!=r[d]){const t=r[d];return(new c).fromArray(t)}if(null!=r[w]){const t=r[w];return(new f).fromArray(t)}if(null!=r[y]){const t=r[y];return(new o).fromArray(t)}if(null!=r[A]){const t=r[A];return(new i).fromArray(t)}if(null!=r[b]){const e=r[b];return new Map(e.map(([r,e])=>[r,this.unwrapObject(e,t)]))}if(null!=r[h]){const e=r[h];return new Set(e.map(r=>this.unwrapObject(r,t)))}if(null!=r[j])return t.requiresAssetLookups=!0,r;const e={};for(const s of Object.keys(r))e[s]=this.unwrapObject(r[s],t);return e}}return r}async decodeAssets(r){if(null!=r&&"object"==typeof r){if(Array.isArray(r))return await Promise.all(r.map(r=>this.decodeAssets(r)));if(r instanceof Map){const t=await Promise.all(Array.from(r.entries()).map(async([r,t])=>[r,await this.decodeAssets(t)]));r.clear();for(const[e,s]of t)r.set(e,s);return r}if(r instanceof Set){const t=await Promise.all(Array.from(r.values()).map(r=>this.decodeAssets(r)));r.clear();for(const e of t)r.add(e);return r}{const t=r;if(null!=t[j])return await this.assetLoader.getDataAssetById(t[j]);for(const r of Object.keys(t))t[r]=await this.decodeAssets(t[r]);return t}}return r}};O=r([s()],O);export{O as NetSerializer};new a,new c,new f,new o,new i;/*
2
+ * Copyright (©) 2026 Hology Interactive AB. All rights reserved.
3
+ * See the LICENSE.md file for details.
4
+ */