lecodes-sdk 2.8.1 → 2.8.2

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.
@@ -78,6 +78,13 @@ export declare abstract class Aspect<K extends string, P = Node, E extends Event
78
78
  static after?: Function[];
79
79
  /** Tick BEFORE these classes within the same phase (`static before = [Camera]`). */
80
80
  static before?: Function[];
81
+ /** DATA ONLY. A `use(...)` of this aspect in a scene file leaves its node STATIC for the level cache (gl/Statics.ts):
82
+ * the engine builds the node without a JS object, and the aspect is attached the first time a hit, a contact or
83
+ * a pick reaches the node — `hit.node.get(Surface)` answers then. So: fields and the methods the game calls on a
84
+ * hit (a tag like `Surface { kind }`, a breakable's hit points), no `update()` (`use()` refuses one) and nothing in
85
+ * `onAttach()` the level needs from its first frame. Without it a custom aspect keeps its node on the JS path,
86
+ * built at load like any mover. */
87
+ static passive?: boolean;
81
88
  /** Every live instance of an aspect/system class, in attach order — the registry a game used to
82
89
  * hand-roll as `static all[]`. Live, read-only: copy it (`[...Aspect.all(Barrel)]`) before a loop
83
90
  * that detaches. Empty in the scene editor (aspects are inert data there). */
@@ -3,6 +3,7 @@ import { Model, type FoliageKind } from "./Model";
3
3
  import { Node } from "./Node";
4
4
  import { Scene } from "./Scene";
5
5
  import type { SceneDef, SceneNodeDef } from "../scene/defineScene";
6
+ import type { AspectEntry } from "../scene/grammar";
6
7
  import type { BakeData } from "./Lightmap";
7
8
  import { type Digest } from "./staticsFormat";
8
9
  export { bakeDigest, type Digest } from "./staticsFormat";
@@ -17,6 +18,16 @@ export type CoveredRoot = {
17
18
  path: string;
18
19
  def: SceneNodeDef;
19
20
  };
21
+ /** A passive aspect (Aspect.passive): data the engine does not need — attached to the placement's wrapper on the
22
+ * first hit (`attachPassive`), never built at load. */
23
+ export declare const isPassive: (e: AspectEntry<any>) => boolean;
24
+ /** Attach the passive aspects of `def` to `node` (props as written: a passive aspect is data, `ref()`s are not
25
+ * resolved). Who gets them: the entity a hit comes back with. A placement's clone, on the first hit, through
26
+ * `lazyPlacements` — a covered root with a model included, since its clone is what the ray strikes, not the plain
27
+ * JS node the clone hangs under. A root WITHOUT a model (a group tagged `Surface` over its walls) has no clone:
28
+ * its JS node takes them at load, and a hit on a wall under it finds them one `parent` up (a game's surface lookup
29
+ * walks `hit.node.parent`). */
30
+ export declare const attachPassive: (node: Node, def: SceneNodeDef) => void;
20
31
  /** The maximal cacheable subtrees among `defs`, depth first: through `children`, and through a prefab's nodes
21
32
  * (paths run through the prefab's path, as the bake's keys do). */
22
33
  export declare const coveredRoots: (defs: Record<string, SceneNodeDef> | undefined, scene: SceneDef) => CoveredRoot[];
@@ -53,4 +64,4 @@ export declare const open: (url: string, defs: Digest, bake: Digest) => Promise<
53
64
  * templates load through `template` (one per kind, as the level's slow path would load them), the engine clones
54
65
  * each at its placements as it resolves. `pages` = the bake's light/aux texture ids interleaved (empty = no bake
55
66
  * bound). Resolves to the placements made. */
56
- export declare const build: (opened: OpenedCache, scene: Scene, roots: Node[], pages: Uint32Array, template: (url: string, lightmap: boolean, foliage: FoliageKind) => Promise<Model>) => Promise<number>;
67
+ export declare const build: (opened: OpenedCache, scene: Scene, roots: Node[], pages: Uint32Array, template: (url: string, lightmap: boolean, foliage: FoliageKind) => Promise<Model>, covered: CoveredRoot[], def: SceneDef) => Promise<number>;
@@ -47,13 +47,18 @@ export declare class CharacterController extends Aspect<"controller", Node> impl
47
47
  * True while a requested collider resize hasn't taken — you asked to stand up and there is something
48
48
  * overhead. Resizing goes through the `Shape` aspect itself:
49
49
  *
50
- * hero.aspect(Shape, { capsule: CROUCHED }) // always fits — you are shrinking
51
- * hero.aspect(Shape, { capsule: STANDING }) // may be refused under a low ceiling
52
- * if (hero.controller.resizing) … // still crouched; call it again next frame
50
+ * hero.shape.capsule = CROUCHED // always fits — you are shrinking
51
+ * hero.shape.capsule = STANDING // may be refused under a low ceiling
52
+ * if (hero.controller.resizing) … // still crouched; write it again next frame
53
53
  *
54
54
  * A refusal changes nothing, so the retry is just the same call again — and it is an exact headroom
55
55
  * test against the real capsule, unlike a hand-rolled raycast (a ray is a line; a capsule has girth).
56
- * The FEET stay planted across a resize, so the character neither hovers nor sinks.
56
+ * The FEET stay planted across a resize, so the character neither hovers nor sinks — which means the
57
+ * node (the capsule's centre) has ALREADY moved by the feet difference when the write returns. Place
58
+ * a first-person camera from the feet (`node.y − (halfHeight + radius)` of the capsule worn) plus an
59
+ * eased eye height; placed from the node it pops by that difference. Write the property: a second
60
+ * `node.aspect(Shape, …)` builds a fresh Shape (it is handed to the character too, but it is a
61
+ * rebuild per stance, not a resize).
57
62
  */
58
63
  get resizing(): boolean;
59
64
  /** True while standing on walkable ground. */
@@ -87,6 +87,12 @@ export declare class Physics extends Aspect<"physics", Node> implements CompWrit
87
87
  /** Whether this host has 3D physics (an engine built with CREATOR_GL_PHYSICS). False, never a
88
88
  * throw, where there is no 3D engine at all. */
89
89
  static get supported(): boolean;
90
- /** Closest pickable body hit by the ray from `origin` along `dir` (up to `maxDist`), or null. */
90
+ /** The motion of the body on `node`, read off the engine: it answers for a body the SDK never made (a static the
91
+ * level cache built, which has no `Physics` aspect until a hit reaches it, and no body-making one ever). null = no
92
+ * body on this node. The way to tell a wall from a prop on a hit: `Physics.motionOf(hit.node) === "static"`. */
93
+ static motionOf(node: Node | null): MotionType | null;
94
+ /** Closest pickable body hit by the ray from `origin` along `dir` (up to `maxDist`), or null. `node` is the body's
95
+ * node — for a static the level cache built, a wrapper made on this hit (Node.ts nodeOf), carrying the placement's
96
+ * passive aspects; its `Physics` is read with `Physics.motionOf`. */
91
97
  static raycast(origin: Vec3Like, dir: Vec3Like, maxDist?: number): RayHit | null;
92
98
  }
@@ -138,6 +138,10 @@ export declare class Shape extends Aspect<"shape", Node> {
138
138
  static fitBounds(bounds: ShapeBounds, scale: Vec3Like, kind?: ShapeKind): ShapeFit;
139
139
  private _createPickBody;
140
140
  private _rebuild;
141
+ /** The character this node belongs to tries the geometry on. Jolt validates the fit (standing up
142
+ * under a pipe) and can refuse; a refusal changes nothing in the engine. The feet stay planted, so
143
+ * on success the node has already moved by the change in the shape's lower bound when this returns. */
144
+ private _offerToCharacter;
141
145
  private _build;
142
146
  private _applyOrigin;
143
147
  private _signature;
@@ -1,4 +1,4 @@
1
- export declare const SDK_VERSION = "2.8.1";
1
+ export declare const SDK_VERSION = "2.8.2";
2
2
  /** The major of a semver string, or null when it is not one. */
3
3
  export declare const sdkMajor: (version: string | null | undefined) => number | null;
4
4
  /** The `// sdk: <version>` line of a compiled bundle's header (sdk/src/compile/header.ts), read from