lecodes-sdk 2.4.9 → 2.5.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 (74) hide show
  1. package/dist/global.d.ts +35 -0
  2. package/dist/types/core/env.d.ts +25 -0
  3. package/dist/types/core/particlesConfig.d.ts +196 -0
  4. package/dist/types/g2/Font2D.d.ts +19 -0
  5. package/dist/types/g2/Material2D.d.ts +24 -0
  6. package/dist/types/g2/Node2D.d.ts +6 -5
  7. package/dist/types/g2/Particles2D.d.ts +169 -0
  8. package/dist/types/g2/Path2D.d.ts +95 -0
  9. package/dist/types/g2/Physics2D.d.ts +1 -1
  10. package/dist/types/g2/Scene2D.d.ts +15 -17
  11. package/dist/types/g2/Sprite.d.ts +12 -1
  12. package/dist/types/g2/SpriteSheet.d.ts +4 -1
  13. package/dist/types/g2/Text2D.d.ts +96 -0
  14. package/dist/types/g2/Tilemap.d.ts +8 -0
  15. package/dist/types/g2/defineScene2d.d.ts +69 -11
  16. package/dist/types/gl/Foliage.d.ts +0 -7
  17. package/dist/types/gl/Lightmap.d.ts +101 -2
  18. package/dist/types/gl/Material.d.ts +21 -15
  19. package/dist/types/gl/Model.d.ts +8 -3
  20. package/dist/types/gl/Particles.d.ts +3 -135
  21. package/dist/types/gl/Statics.d.ts +56 -0
  22. package/dist/types/gl/staticsFormat.d.ts +101 -0
  23. package/dist/types/inject.d.ts +11 -3
  24. package/dist/types/runtime/env.d.ts +10 -0
  25. package/dist/types/runtime/envValues.d.ts +8 -0
  26. package/dist/types/scene/defineScene.d.ts +17 -12
  27. package/dist/types/server/env.d.ts +14 -0
  28. package/dist/types/server/inject.d.ts +1 -0
  29. package/dist/types/ui/fonts.d.ts +4 -0
  30. package/dist/types/version.d.ts +1 -1
  31. package/dist/types.json +1 -1
  32. package/package.json +1 -1
  33. package/src/bridges/2d.d.ts +65 -5
  34. package/src/bridges/gl.d.ts +34 -15
  35. package/src/compile/bakeMacro.ts +3 -0
  36. package/src/compile/compileProject.ts +25 -4
  37. package/src/compile/envCompile.ts +74 -0
  38. package/src/compile/fontMacro.ts +11 -6
  39. package/src/compile/index.ts +6 -0
  40. package/src/compile/resourceSlots.ts +1 -0
  41. package/src/compile/serverSplit.ts +47 -4
  42. package/src/core/env.ts +47 -0
  43. package/src/core/particlesConfig.ts +422 -0
  44. package/src/g2/Font2D.ts +87 -0
  45. package/src/g2/Material2D.ts +64 -0
  46. package/src/g2/Node2D.ts +10 -6
  47. package/src/g2/Particles2D.ts +337 -0
  48. package/src/g2/Path2D.ts +215 -0
  49. package/src/g2/Physics2D.ts +1 -1
  50. package/src/g2/Scene2D.ts +16 -22
  51. package/src/g2/Sprite.ts +23 -4
  52. package/src/g2/SpriteSheet.ts +9 -5
  53. package/src/g2/Text2D.ts +178 -0
  54. package/src/g2/Tilemap.ts +10 -0
  55. package/src/g2/defineScene2d.ts +108 -21
  56. package/src/g2/groups2d.ts +2 -2
  57. package/src/gl/Foliage.ts +1 -16
  58. package/src/gl/Lightmap.ts +79 -26
  59. package/src/gl/Material.ts +51 -21
  60. package/src/gl/Model.ts +19 -5
  61. package/src/gl/Particles.ts +22 -361
  62. package/src/gl/Statics.ts +301 -0
  63. package/src/gl/nav/NavMesh.ts +4 -1
  64. package/src/gl/staticsFormat.ts +240 -0
  65. package/src/inject.ts +18 -3
  66. package/src/runtime/env.ts +13 -0
  67. package/src/runtime/envValues.ts +8 -0
  68. package/src/runtime/fetch.ts +18 -0
  69. package/src/scene/defineScene.ts +107 -27
  70. package/src/server/env.ts +25 -0
  71. package/src/server/host.ts +6 -0
  72. package/src/server/inject.ts +2 -1
  73. package/src/ui/fonts.ts +46 -0
  74. package/src/version.ts +1 -1
@@ -201,26 +201,32 @@ export declare class Material {
201
201
  static terrainLightmap(): Material;
202
202
  private static _lmTemplate;
203
203
  private static _lmMaskedTemplate;
204
- /** The FOLIAGE tier (`Model.load(…, { foliage: true })`, see `Foliage`): an unlit shader with its own cheap
205
- * lighting plus a vertex shader that sways in the wind, bends away from benders and thins out with distance,
206
- * and a per-copy tint. glTF parameters like `Material.lightmap()` plus `wind` / `sway` / `fade` / `benders`,
207
- * which the engine writes itself. Not baked by the rewritten bake yet. */
204
+ /** The FOLIAGE tier's BARK (`Model.load(…, { foliage })`, see `Foliage`): the opaque material a vegetation model's
205
+ * trunks, limbs and stems take — lit by the sky and the real-time sun, swaying in the wind, bending away from
206
+ * benders, thinning out with distance, with a per-copy tint. glTF parameters like `Material.lightmap()` plus
207
+ * `wind` / `sway` / `fade` / `benders`, which the engine writes itself. */
208
208
  static foliage(): Material;
209
- /** `Material.foliage()`'s masked twin (`blending: masked`): what the engine gives a foliage model's alpha-MASK
210
- * materials — the cards. */
211
- static foliageMasked(): Material;
209
+ /** The CARDS of a crown (`Model.load(…, { foliage: 'tree' })`): what a vegetation model's alpha-MASK materials take
210
+ * — leaves and needles lit per vertex on the crown's hull normal by the sky and the real-time sun, with the
211
+ * sun's shadow per pixel. Ground cover takes `Material.grass()` instead. */
212
+ static foliageCards(): Material;
213
+ /** GROUND COVER (`Model.load(…, { foliage: 'grass' })`): the cards of grass, ferns, heath — the plant that IS the
214
+ * ground's surface. The same wind as `Material.foliage()`, lit by the terrain it stands on: the ground's baked
215
+ * ambient and sun share under it, the soil's colour at its base. A crown (`'tree'`) reads nothing from the ground. */
216
+ static grass(): Material;
217
+ /** A tree's far IMPOSTOR (`Model.load(…, { foliage: 'tree' })`): the material of the camera-facing quad
218
+ * lecodes-assets bakes into a tree's GLB as its last LOD level — an atlas of views of the tree (a grid of azimuths ×
219
+ * elevation rows, or a hemi-octahedron; albedo, normal, baked sky visibility) lit per pixel like the crown's cards.
220
+ * The engine picks it for the material whose extras carry `lecodes.impostor` and writes `impostorGrid` /
221
+ * `impostor` from them. */
222
+ static foliageImpostor(): Material;
212
223
  /** the glTF-side identity values every provider-handed material starts from */
213
224
  private static _glbDefaults;
214
225
  private static _lightmapDefaults;
215
226
  private static _folTemplate;
216
- /** Which material a foliage model's CARDS (its alpha-MASK materials) take: `"full"` = `foliage-masked`, the
217
- * shader with the card's own plane, normal map, edge fade and the ground's baked light; `"lean"` =
218
- * `foliage-cards`, the same wind with the lighting moved to the vertex (one texture read, the sun's shadow
219
- * kept) — a third of a forest frame less on a phone-class GPU (2026-10-18). Read when the first foliage
220
- * model loads; set it before. */
221
- static foliageCards: "full" | "lean";
222
- static _foliageMaskedTemplate(): Material | null;
223
- private static _folMaskedTemplate;
227
+ private static _folCardsTemplate;
228
+ private static _grassTpl;
229
+ private static _folImpostorTpl;
224
230
  private static _glbTemplate;
225
231
  /** Shadow-catcher material (transparent except where shadows fall). */
226
232
  static shadow(color?: ColorInput): Material;
@@ -12,7 +12,7 @@ export interface TrianglePick {
12
12
  mesh: string;
13
13
  primitive: number;
14
14
  material: string;
15
- /** the primitive's index over its file's meshes: the lightmap bake's record `<key>@<ordinal>` */
15
+ /** the primitive's index over its file's walked nodes' primitives: the lightmap bake's record `<key>@<ordinal>` */
16
16
  lightmapOrdinal: number;
17
17
  /** triangle index within the primitive (index-buffer order), and whether the ray came from behind */
18
18
  triangle: number;
@@ -33,6 +33,8 @@ export interface TrianglePick {
33
33
  }[];
34
34
  }[];
35
35
  }
36
+ /** What a vegetation model is lit as (`Model.load`'s `foliage`): a CROWN or GROUND COVER; false = not foliage. */
37
+ export type FoliageKind = false | "tree" | "grass";
36
38
  export declare class Model extends Node {
37
39
  /** The model's Animator — always present, its clip table = the GLB's embedded clips. Add to it
38
40
  * with `model.anim.addClip(name, clip)` (external clips), `model.anim.addLayer()`; set its fields
@@ -88,7 +90,10 @@ export declare class Model extends Node {
88
90
  * the standard shader, lit real-time (movers). Hosts without lightmap support ignore it. */
89
91
  lightmap?: boolean;
90
92
  /** Vegetation: load through the FOLIAGE tier (see `Foliage`) — wind, touch bending, distance fade,
91
- * per-copy tint. Hosts without the tier fall back to the standard shader. */
92
- foliage?: boolean;
93
+ * per-copy tint. `'tree'` (= `true`): a CROWN — a volume in the air, lit by the sky and the real-time sun
94
+ * through the shadow map. `'grass'`: GROUND COVER — grass, ferns, heath: the plant that is the ground's
95
+ * surface, lit by the terrain's baked light under it and tinted by its soil at the base. Hosts without the
96
+ * tier fall back to the standard shader. */
97
+ foliage?: boolean | "tree" | "grass";
93
98
  }): Promise<Model>;
94
99
  }
@@ -1,140 +1,9 @@
1
- import { type ColorInput } from "../core/color";
2
- import { type Vec3Like } from "../math/vec";
1
+ import type { Vec3Like } from "../math/vec";
3
2
  import type { Geometry } from "./Geometry";
4
3
  import { Material, type ParticlesMaterialOptions } from "./Material";
5
4
  import { Node } from "./Node";
6
- type Range<T> = T | {
7
- min: T;
8
- max: T;
9
- };
10
- export declare class CurveBuilder {
11
- private _kind;
12
- private _lo;
13
- private _hi;
14
- private _stops;
15
- constructor(base: Range<number>, mode: "multiply" | "add");
16
- /** Curve value at birth (t = 0). Must come before any other stop. */
17
- from(v: Range<number>): this;
18
- /** Curve value at `t` (0..1 of the particle's life). Stops must be added in ascending t order. */
19
- via(t: number, v: Range<number>): this;
20
- /** Curve value at death (t = 1). */
21
- to(v: Range<number>): this;
22
- /** The classic opacity envelope: rise over the first `fadeIn`, fall over the last `fadeOut`. */
23
- fade(fadeIn?: number, fadeOut?: number): this;
24
- /** The PARAM_CURVE record payload (sans slot): [kind, baseLo, baseHi, n, (t, lo, hi)×n]. */
25
- get _data(): Float32Array;
26
- }
27
- export declare class ColorCurveBuilder {
28
- private _lo;
29
- private _hi;
30
- private _stops;
31
- constructor(base: Range<ColorInput>);
32
- /** Curve color at birth (t = 0). Must come first. The curve multiplies the base color. */
33
- from(c: Range<ColorInput>): this;
34
- /** Curve color at `t` (0..1 of the particle's life), in ascending t order. */
35
- via(t: number, c: Range<ColorInput>): this;
36
- /** Curve color at death (t = 1). */
37
- to(c: Range<ColorInput>): this;
38
- /** The COLOR_CURVE record payload: [baseLo rgba, baseHi rgba, n, (t, lo rgba, hi rgba)×n]. */
39
- get _data(): Float32Array;
40
- }
41
- /** A value curve over each particle's lifetime. Default mode `multiply` (the curve scales the
42
- * base); `add` offsets it instead. */
43
- export declare const curve: (base?: Range<number>, mode?: "multiply" | "add") => CurveBuilder;
44
- /** A color curve over each particle's lifetime — always multiplies the base color. */
45
- export declare const colorCurve: (base?: Range<ColorInput>) => ColorCurveBuilder;
46
- export type ParticleValue = Range<number> | CurveBuilder | {
47
- _data: Float32Array;
48
- };
49
- export type ParticleColor = ColorInput | {
50
- min: ColorInput;
51
- max: ColorInput;
52
- } | ColorCurveBuilder | {
53
- _data: Float32Array;
54
- };
55
- type VelocityValue = {
56
- speed?: Range<number>;
57
- /** Cone half-angle in radians — jitter the launch direction uniformly within it. */
58
- spread?: number;
59
- /** Asymmetric jitter: two angles (u, v — the x/y components) in radians. */
60
- randomizeAngle?: {
61
- min: Vec3Like;
62
- max: Vec3Like;
63
- };
64
- } & ({
65
- from: Vec3Like;
66
- } | {
67
- to: Vec3Like;
68
- } | {
69
- dir: Vec3Like;
70
- } | {});
71
- /** Where particles are born, in emitter space. Sphere / hemisphere / cone have an axis of +Y (the
72
- * hemisphere is the +Y half, the cone opens along +Y from its base disc at `center`) — aim the
73
- * node with `lookAt(target, 'y')`. `thickness` 0 emits from the surface only, 1 (default) from the
74
- * whole volume. A sphere or cone also sets the LAUNCH DIRECTION (outward / from the cone's apex)
75
- * when `startVelocity` gives a speed but no direction, like Unity's shapes. */
76
- type Shape = {
77
- type: "point";
78
- v: Vec3Like;
79
- } | {
80
- type: "box";
81
- min: Vec3Like;
82
- max: Vec3Like;
83
- } | {
84
- type: "circle";
85
- center: Vec3Like;
86
- radius: number;
87
- } | {
88
- type: "sphere";
89
- center?: Vec3Like;
90
- radius: number;
91
- thickness?: number;
92
- } | {
93
- type: "hemisphere";
94
- center?: Vec3Like;
95
- radius: number;
96
- thickness?: number;
97
- } | {
98
- type: "cone";
99
- center?: Vec3Like;
100
- radius: number; /** half-angle, radians */
101
- angle?: number; /** emit this far up the axis too */
102
- length?: number;
103
- thickness?: number;
104
- };
105
- /** Extra velocity over each particle's life — evaluated from the curves every frame and ADDED as a
106
- * displacement (not accumulated like `acceleration`): `radial` pushes outward along the particle's
107
- * birth direction (a burst that decays: `curve(4).to(0)`), `x`/`y`/`z` drift in the simulation
108
- * space (rising smoke: `y: curve(2).from(0).to(1)`). Unity's velocityOverLifetime. */
109
- export type VelocityOverLife = {
110
- radial?: ParticleValue;
111
- x?: ParticleValue;
112
- y?: ParticleValue;
113
- z?: ParticleValue;
114
- };
115
- type Noise = {
116
- strength?: number;
117
- frequency?: number;
118
- speed?: number;
119
- /** How much of the displacement a particle earns with AGE (default 0 = all of it from birth).
120
- * The field is sampled by position, so at 0 every particle born at the same spot is pushed the
121
- * same way and a plume's root wanders off its emitter by up to `strength` metres; at 1 a particle
122
- * is born exactly where the emitter put it and drifts into the field over its life — what you
123
- * want whenever the source is visible (an exhaust pipe, a contact patch, a muzzle). */
124
- ramp?: number;
125
- };
126
- /** Ground plane for bouncing particles (all render modes). `height` is in the simulation space:
127
- * world y with `space: 'world'`, emitter-local y otherwise. */
128
- export type ParticleGround = {
129
- /** Plane height (default 0). */
130
- height?: number;
131
- /** Contact radius — particles stop `radius` above the plane (a mesh's half-extent; default 0). */
132
- radius?: number;
133
- /** Fraction of the vertical speed kept on impact, 0..1 (default 0.3). */
134
- bounce?: number;
135
- /** Tangential damping while in contact, per second — like `drag` (default 8). */
136
- friction?: number;
137
- };
5
+ import { type ParticleColor, type ParticleGround, type ParticleNoise as Noise, type ParticleShape as Shape, type ParticleValue, type Range, type VelocityOverLife, type VelocityValue } from "../core/particlesConfig";
6
+ export { _particleTags, CurveBuilder, ColorCurveBuilder, curve, colorCurve, type ParticleValue, type ParticleColor, type VelocityOverLife, type ParticleGround, } from "../core/particlesConfig";
138
7
  export type ParticlesOptions = ParticlesMaterialOptions & {
139
8
  /** Draw every particle as this mesh — lit, tumbling 3D debris (shell casings, rubble, leaves,
140
9
  * shrapnel) in one draw call. The system switches to the mesh render mode; the default
@@ -341,4 +210,3 @@ export declare class Trail extends Node {
341
210
  set emitting(val: boolean);
342
211
  get material(): Material;
343
212
  }
344
- export {};
@@ -0,0 +1,56 @@
1
+ import { type FetchResponse } from "../runtime/fetch";
2
+ import { Model, type FoliageKind } from "./Model";
3
+ import { Node } from "./Node";
4
+ import { Scene } from "./Scene";
5
+ import type { SceneDef, SceneNodeDef } from "../scene/defineScene";
6
+ import type { BakeData } from "./Lightmap";
7
+ import { type Digest } from "./staticsFormat";
8
+ export { bakeDigest, type Digest } from "./staticsFormat";
9
+ /** `lecodes level build` runs the app with this on `globalThis.__lecodesStatic`: the project root the snapshot is written under. */
10
+ export type StaticsConfig = {
11
+ root: string;
12
+ };
13
+ export declare const staticsConfig: () => StaticsConfig | null;
14
+ /** True under any of the CLI's tool runs that must see the level the slow, complete way (the bakes, the snapshot). */
15
+ export declare const toolRun: () => boolean;
16
+ export type CoveredRoot = {
17
+ path: string;
18
+ def: SceneNodeDef;
19
+ };
20
+ /** The maximal cacheable subtrees among `defs`, depth first: through `children`, and through a prefab's nodes
21
+ * (paths run through the prefab's path, as the bake's keys do). */
22
+ export declare const coveredRoots: (defs: Record<string, SceneNodeDef> | undefined, scene: SceneDef) => CoveredRoot[];
23
+ /** The live node at a full path: a top-level entry of the record, or a prefab internal reached through its
24
+ * wrapper's part rows (the record only keys the top level; internals live in the wrapper's `_prefabParts`). */
25
+ export declare const findNode: (nodes: Record<string, Node>, path: string) => Node | null;
26
+ /** The digest of the covered defs — what a snapshot's placements were made from. */
27
+ export declare const defsDigest: (roots: CoveredRoot[], scene: SceneDef) => Digest;
28
+ /** The snapshot of the covered roots' subtrees as they stand: the bytes `lecodes level build` writes. `bake` = the
29
+ * data the level is bound to (its records go in, joined by path), null = an unbaked level (placements and bodies
30
+ * only; the CLI stitches the records in after the bake). */
31
+ export declare const snapshot: (roots: {
32
+ root: CoveredRoot;
33
+ node: Node;
34
+ }[], scene: SceneDef, bake: BakeData | null, defs: Digest) => {
35
+ bytes: Uint8Array;
36
+ kinds: number;
37
+ placements: number;
38
+ records: number;
39
+ };
40
+ export type OpenedCache = {
41
+ resp: FetchResponse;
42
+ kinds: {
43
+ url: string;
44
+ lightmap: boolean;
45
+ foliage: FoliageKind;
46
+ }[];
47
+ placements: number;
48
+ roots: number;
49
+ };
50
+ /** Fetch the level's cache and check it against the digests; null = absent, not a cache, or stale (the why logged). */
51
+ export declare const open: (url: string, defs: Digest, bake: Digest) => Promise<OpenedCache | null>;
52
+ /** Build the opened cache under `roots` (the covered roots' JS nodes, in the snapshot's order) in `scene`: the
53
+ * templates load through `template` (one per kind, as the level's slow path would load them), the engine clones
54
+ * each at its placements as it resolves. `pages` = the bake's light/aux texture ids interleaved (empty = no bake
55
+ * 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>;
@@ -0,0 +1,101 @@
1
+ import type { FoliageKind } from "./Model";
2
+ export declare const MAGIC = 1414742860, VERSION = 2, NONE = 4294967295;
3
+ export declare const HEADER = 11, KIND = 4, PLACEMENT = 20, RECORD = 6;
4
+ export declare const ShapeKind: {
5
+ readonly None: 0;
6
+ readonly Mesh: 1;
7
+ readonly Convex: 2;
8
+ readonly Box: 3;
9
+ readonly Sphere: 4;
10
+ readonly Cylinder: 5;
11
+ readonly Capsule: 6;
12
+ readonly AutoBox: 7;
13
+ };
14
+ export type ShapeKind = number;
15
+ export type Digest = [number, number];
16
+ export type StaticKind = {
17
+ name: string;
18
+ lightmap: boolean;
19
+ foliage: FoliageKind;
20
+ };
21
+ /** A record: a rect (`page` + `st`) or an object light (`page === NONE`, `slabs` = the floats lightmapObjectApply takes). */
22
+ export type StaticRecord = {
23
+ ordinal: number;
24
+ page: number;
25
+ st?: number[];
26
+ slabs?: number[];
27
+ };
28
+ export type StaticPlacement = {
29
+ kind: number;
30
+ path: string;
31
+ root: number;
32
+ pos: number[];
33
+ quat: number[];
34
+ scale: number[];
35
+ castShadows: boolean;
36
+ receiveShadows: boolean;
37
+ shape: ShapeKind;
38
+ params: number[];
39
+ records: StaticRecord[];
40
+ };
41
+ export type StaticsFile = {
42
+ defs: Digest;
43
+ bake: Digest;
44
+ kinds: StaticKind[];
45
+ placements: StaticPlacement[];
46
+ };
47
+ /** Two independent 32-bit hashes over `s` (FNV-1a and a multiplicative xor mix), chained from `seed`: 64 bits of
48
+ * "did this change", which is all a header needs. */
49
+ export declare const hash64: (s: string, seed?: Digest) => Digest;
50
+ export declare const NO_BAKE: Digest;
51
+ /** The bake's identity as the cache keys it: what a rebake changes. `bake` is the `.bake` JSON. */
52
+ export declare const bakeDigest: (bake: {
53
+ size: number;
54
+ pages: number;
55
+ texel: number;
56
+ texels?: number;
57
+ instances: unknown[];
58
+ uv1?: string | null;
59
+ } | null) => Digest;
60
+ /** What a `.bake` instance carries that the cache keeps (the SDK's BakeInstance, structurally). */
61
+ export type BakeRecordSource = {
62
+ key: string;
63
+ receiver: boolean;
64
+ small?: boolean;
65
+ page?: number;
66
+ st?: number[];
67
+ light?: {
68
+ axis: number;
69
+ from: number;
70
+ to: number;
71
+ cubes: number[][][];
72
+ probes: number[];
73
+ };
74
+ };
75
+ /** The records of every bake instance keyed by node PATH (`<path>@<ordinal>` and whole-node `<path>` alike), in the
76
+ * shape the cache stores — the same join the runtime makes when it binds a bake the slow way. */
77
+ export declare const recordsByPath: (instances: BakeRecordSource[]) => Map<string, StaticRecord[]>;
78
+ /** The file's bytes for `f`. */
79
+ export declare const encode: (f: StaticsFile) => Uint8Array;
80
+ /** The header alone: null when `bytes` is not a cache of this version. */
81
+ export declare const readHeader: (bytes: Uint8Array) => {
82
+ defs: Digest;
83
+ bake: Digest;
84
+ kinds: number;
85
+ placements: number;
86
+ records: number;
87
+ floats: number;
88
+ stringBytes: number;
89
+ } | null;
90
+ /** The whole file as data: null when it is not one. */
91
+ export declare const decode: (bytes: Uint8Array) => StaticsFile | null;
92
+ /** `f` with its records replaced by `bake`'s (joined by placement path) and its bake digest restamped — what
93
+ * `lecodes level build` does after a bake, with no host run. `null` bake = no records, NO_BAKE. */
94
+ export declare const stitch: (f: StaticsFile, bake: {
95
+ size: number;
96
+ pages: number;
97
+ texel: number;
98
+ texels?: number;
99
+ instances: BakeRecordSource[];
100
+ uv1?: string | null;
101
+ } | null) => StaticsFile;
@@ -13,16 +13,18 @@ export { __compWrite, __compOp, type CompAxis, type CompWriter } from "./core/co
13
13
  export { Canvas, Bitmap } from "./canvas/Canvas";
14
14
  export { toast, openURL, SvgSource } from "./runtime/misc";
15
15
  export { app, type AppState, type OrientationLock } from "./runtime/app";
16
+ export { env } from "./runtime/env";
16
17
  export { clipboard } from "./runtime/clipboard";
17
18
  export { permissions, type PermissionKind, type PermissionState } from "./runtime/permissions";
18
19
  export { date, type DateValue, type DateInput, type Unit, type Locale } from "./runtime/datetime";
19
- export { fetch, fetchLocal, FormData, File, type FetchResponse } from "./runtime/fetch";
20
+ export { fetch, fetchLocal, FormData, File, __localAsset, type FetchResponse } from "./runtime/fetch";
20
21
  export { localStorage } from "./runtime/storage";
21
22
  export { device, type HapticStyle, type MotionOptions } from "./runtime/device";
22
23
  export { Input, InputChannel, type InputKeyEvent, type InputGamepadEvent, type InputEventName, type GamepadState, type GamepadAxisName } from "./runtime/input";
23
24
  export { WebSocket } from "./runtime/net";
24
25
  export { Net, NetPlayer, Replicated, NetEntity, type NetMessage, type NetRole, type NetStatus, type NetEvents, type NetLaunch, type NetInput, type NetKind, type NetTransform, type NetCorrection } from "./net";
25
26
  export { __rpc, __channel, __pushChannel, __serverOnly, RpcError } from "./runtime/rpc";
27
+ export { __registerFont } from "./ui/fonts";
26
28
  export { resource, action, dataOf, failureOf, type Loaded, type Failure, type Resource, type Action } from "./runtime/resource";
27
29
  export type { ChannelSubscription } from "./server/channel";
28
30
  export type { PushChannel, PushMessage, PushNotification, PushTarget } from "./server/pushChannel";
@@ -47,7 +49,12 @@ export { CharacterController2D } from "./g2/CharacterController2D";
47
49
  export { OneWay2D } from "./g2/OneWay2D";
48
50
  export { PhysicsGroup2D } from "./g2/groups2d";
49
51
  export { Tilemap } from "./g2/Tilemap";
52
+ export { Path2D, type Path2DOptions, type Stroke2D, type StrokeJoin2D, type StrokeCap2D } from "./g2/Path2D";
53
+ export { Material2D, type Material2DOptions, type Blend2D, type Filter2D, type Wrap2D } from "./g2/Material2D";
50
54
  export { Texture2D } from "./g2/Texture2D";
55
+ export { Font2D, type Font2DOptions } from "./g2/Font2D";
56
+ export { Text2D, type Text2DOptions, type TextAlign2D, type TextOutline2D } from "./g2/Text2D";
57
+ export { Particles2D, type Particles2DOptions, type ParticleMode2D, type ParticleShape2D, type VelocityValue2D, type VelocityOverLife2D, } from "./g2/Particles2D";
51
58
  export { SpriteSheet, defineSpriteSheet } from "./g2/SpriteSheet";
52
59
  export type { SpriteSheetDef, SheetSprite, SpriteMakeOptions } from "./g2/SpriteSheet";
53
60
  export { Tileset, defineTileset, Autotile2D } from "./g2/Tileset";
@@ -55,7 +62,7 @@ export { rawCell, isRawCell, rawIndex } from "./g2/autotile";
55
62
  export { rot90, rot180, rot270, flipX, packTile, tileIndex, tileTurns, tileFlip, tileOriented } from "./g2/autotile";
56
63
  export type { TilesetDef, TileMaterial, PatchMaterial, PathMaterial, PatchSlots, EdgeSlot, FillBlock, BlockEntry, TileBlock, TilePart, } from "./g2/autotile";
57
64
  export { defineScene2d, Scene2dHandle } from "./g2/defineScene2d";
58
- export type { Scene2dDef, Scene2dNodeDef, Scene2dEnv, SpriteSourceDef, TilemapSourceDef, Camera2dNodeDef, LoadedScene2d } from "./g2/defineScene2d";
65
+ export type { Scene2dDef, Scene2dNodeDef, Scene2dEnv, SpriteSourceDef, TilemapSourceDef, PathSourceDef, TextSourceDef, Particles2DSourceDef, Camera2dNodeDef, LoadedScene2d } from "./g2/defineScene2d";
59
66
  export { cells, encodeCells, type CellsData } from "./g2/cells";
60
67
  export { CameraFollow } from "./g2/scenarios2d";
61
68
  export { UIScreen, type UIScreenStyle, UIRow, UIColumn, UIBox, type UIContainerStyle, UIText, type UITextStyle, UIButton, type UIButtonStyle, UIImage, type UIImageStyle, UIVideo, type UIVideoStyle, UIInput, UITextArea, type UIInputStyle, UIScrollable, type UIScrollableStyle, UIPager, type UIPagerStyle, UITabs, type UITabDef, defineTabs, type TabDef, type TabsHandle, UIWidget, type UIWidgetStyle, type WidgetSet, type UIWidgetContent, type UIWidgetChild, UIModal, type UIModalStyle, UIBottomSheet, type UIBottomSheetStyle, UIPopover, type UIPopoverStyle, UISpacer, type UISpacerStyle, UIVirtualizedList, Router, NativeView, type UINativeViewStyle, registerFont, __uiMap, __UIColumn, __UIRow, __UIBox, __UIButton, __UIScreen, __UIScrollable, __UIWidget, } from "./ui/UI";
@@ -157,6 +164,7 @@ export type { ReflectionProbeOptions } from "./gl/ReflectionProbe";
157
164
  export { Ray } from "./gl/Ray";
158
165
  export { Plane } from "./gl/Plane";
159
166
  export { Noise } from "./gl/Noise";
160
- export { Particles, Trail, curve, colorCurve } from "./gl/Particles";
167
+ export { Particles, Trail } from "./gl/Particles";
168
+ export { curve, colorCurve } from "./core/particlesConfig";
161
169
  export { DecalSet, DecalTrail } from "./gl/DecalSet";
162
170
  export type { DecalOptions, DecalSetOptions, DecalSpawnOptions, DecalPlacement, DecalTrailOptions } from "./gl/DecalSet";
@@ -0,0 +1,10 @@
1
+ /**
2
+ * `env` in the APP — the project's `PUBLIC_*` keys (src/core/env.ts says what `env` is): a maps key
3
+ * restricted to the app's id, an analytics id, a Sentry DSN. The values are baked into the bundle at
4
+ * compile time (./envValues.ts, replaced by the compile), so they are there offline and without a
5
+ * backend. Any other key is a secret: the compile refuses `env.STRIPE_KEY` in app code — read it in a
6
+ * `*.server.ts` file and call an endpoint.
7
+ */
8
+ import { type Env } from "../core/env";
9
+ /** The app's public keys. A `PUBLIC_*` key that is not set throws `EnvError` on read. */
10
+ export declare const env: Env;
@@ -0,0 +1,8 @@
1
+ /**
2
+ * The app's keys — the `PUBLIC_*` subset of the project's keys, baked into the bundle.
3
+ *
4
+ * This module is a placeholder the COMPILER REPLACES: `compileProjectWithMap({ env })` puts a module
5
+ * with the real values at this same path in chisel's file map (project files win over SDK files),
6
+ * the way `server/auth/appConfig.ts` carries app.json. Outside a compiled bundle it is empty.
7
+ */
8
+ export declare const values: Record<string, string>;
@@ -134,19 +134,24 @@ export type SceneNodeDef = {
134
134
  * the GLB instance, so `castShadows: false` on a first-person viewmodel covers the whole gun. */
135
135
  castShadows?: boolean;
136
136
  receiveShadows?: boolean;
137
- /** Baked lighting (a scene with `env.lightmap`): is this model/mesh node a lightmap STATIC — a
138
- * receiver and an occluder in the bake, real-time shadow casting off once the bake applies?
139
- * Default: static unless a `Physics` aspect moves the node (`dynamic` — Physics' default — or
140
- * `kinematic`). Set it only to override that rule; prefab subtrees inherit the verdict.
141
- * `'cube'` = a static whose every mesh bakes as AMBIENT CUBES instead of atlas texels — an occluder (its shadow and
137
+ /** Is this node STATIC — part of the level that never moves once loaded? A static is what the bake sees (a
138
+ * receiver and an occluder, real-time shadow casting off once the bake applies) and what the level cache
139
+ * snapshots after the first load. Default: static unless a `Physics` aspect moves the node (`dynamic` —
140
+ * Physics' default — or `kinematic`). `false` = built live, lit in real time, never cached. Set it only to
141
+ * override that rule; prefab subtrees inherit the verdict. */
142
+ static?: boolean;
143
+ /** `'cube'` = a static whose every mesh bakes as AMBIENT CUBES instead of atlas texels — an occluder (its shadow and
142
144
  * bounce stay in the bake) lit where it stands, the way the bake treats small and thin props on its own: a pipe run, a
143
145
  * fence, a prop whose lightmap seams show. A prefab marked `'cube'` bakes its statics that way too. By name for a whole
144
146
  * kit: the `cube` option of `env.lightmap`'s `bake()`. */
145
- lightmap?: boolean | "cube";
147
+ lightmap?: "cube";
146
148
  /** `model` nodes: vegetation — load through the FOLIAGE tier (wind, touch bending, per-copy tint; see
147
- * `Foliage`). `{ fade: [start, end] }` also thins the cards out over that distance range (m) and drops the
148
- * copy past `end` — for ground cover. The fade is per ASSET: every node of the same GLB shares it. */
149
- foliage?: boolean | {
149
+ * `Foliage`). `'tree'` (= `true`): a crown, lit by the sky and the real-time sun; `'grass'`: ground cover, lit by
150
+ * the terrain's baked light under it (`Model.load`'s `foliage`). The object form names the kind and may add
151
+ * `fade: [start, end]`: the cards thin out over that distance range (m) and the copy drops past `end` — for
152
+ * ground cover. The fade is per ASSET: every node of the same GLB shares it. */
153
+ foliage?: boolean | "tree" | "grass" | {
154
+ kind?: "tree" | "grass";
150
155
  fade?: [number, number];
151
156
  };
152
157
  /** Navigation (a scene with `env.navmesh`, see navmesh.md): every STATIC body is walkable by
@@ -250,9 +255,9 @@ export type ModelPartRow = {
250
255
  export declare const modelPartRows: (root: Node) => ModelPartRow[];
251
256
  /** Where a def node attaches: its `mount` part when it resolves, else the parent itself. */
252
257
  export declare const attachHost: (parent: Node, def: SceneNodeDef, path: string) => Node;
253
- /** The static verdict for one node def (the editor's "Baked lighting" switch shows the same rule).
254
- * Children of a mover are movers too — buildNodes carries that down, this is the node's own verdict. */
255
- export declare const isLightmapStatic: (def: SceneNodeDef) => boolean;
258
+ /** The static verdict for one node def (the editor's "Static" switch shows the same rule). Children of a
259
+ * mover are movers too — buildNodes carries that down, this is the node's own verdict. */
260
+ export declare const isStatic: (def: SceneNodeDef) => boolean;
256
261
  /** Edit mode: play the preview pose on a model node (`editor: { clip, time }`) — idempotent, the
257
262
  * harness re-applies it on inspector edits. No clip = back to the rest pose. */
258
263
  export declare const applyEditorPose: (node: Node, pose: {
@@ -0,0 +1,14 @@
1
+ /**
2
+ * `env` on the SERVER — every key of the project (src/core/env.ts says what `env` is). The values
3
+ * (Settings → Keys on le.codes, the project's `.env` on this machine) are handed to the bundle by the
4
+ * host that runs it (`setEnv`) through the `globalThis.__lecodesEnv` seam — a global on purpose,
5
+ * like `__lecodesRequest`: the bundle carries its own SDK copy, so the host can't pass a value by
6
+ * import. The compile lists the names the server code reads (serverSplit.ts `scanEnvReads`) so a
7
+ * deploy can warn before any call does.
8
+ */
9
+ import { type Env } from "../core/env";
10
+ export { ENV_NAME, PUBLIC_ENV_PREFIX, isPublicEnvName, EnvError, type Env } from "../core/env";
11
+ /** Host hook (runner / local backend / tests): the values the bundle reads. `null` = none set. */
12
+ export declare const setEnv: (values: Record<string, string> | null) => void;
13
+ /** The project's keys. A missing key throws `EnvError` on read. */
14
+ export declare const env: Env;
@@ -1,5 +1,6 @@
1
1
  export { t, model, defineDb, ref } from "./db";
2
2
  export { ApiError } from "./errors";
3
+ export { env, type Env } from "./env";
3
4
  export { channel } from "./channel";
4
5
  export { pushChannel, type PushChannel, type PushMessage, type PushNotification, type PushTarget } from "./pushChannel";
5
6
  export { request } from "./context";
@@ -6,4 +6,8 @@ type FontOptions = {
6
6
  * use in styles. For registry/project fonts prefer the compile-time `font()` macro — this is the
7
7
  * dynamic escape hatch. */
8
8
  export declare function registerFont(fontFamily: string, url: string, options?: FontOptions): Promise<void>;
9
+ /** The macro's registration call (a bundle global, like `__rpc`). `url` is either a full URL (a
10
+ * project / vendored entry) or a cdn base ending in "." — the format is appended here: the host's
11
+ * for the UI tree, always ttf for 2D text. */
12
+ export declare function __registerFont(family: string, url: string, weight: number, italic: boolean): void;
9
13
  export {};
@@ -1,4 +1,4 @@
1
- export declare const SDK_VERSION = "2.4.9";
1
+ export declare const SDK_VERSION = "2.5.0";
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