@moku-labs/game 0.0.2 → 0.0.3

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 (35) hide show
  1. package/README.md +89 -21
  2. package/dist/assets.d.mts +58 -6
  3. package/dist/assets.mjs +1630 -234
  4. package/dist/commands-BOxqlv7w.d.mts +99 -0
  5. package/dist/control.d.mts +3 -92
  6. package/dist/control.mjs +3 -757
  7. package/dist/define-BMo0pHe_.d.mts +51 -0
  8. package/dist/{registry-DlpRCibU.mjs → dev-CcwFrwok.mjs} +30 -1
  9. package/dist/index.d.mts +217 -29
  10. package/dist/index.mjs +6179 -727
  11. package/dist/inspect.d.mts +10 -8
  12. package/dist/inspect.mjs +2 -518
  13. package/dist/jsx-dev-runtime.d.mts +1 -1
  14. package/dist/jsx-runtime.d.mts +1 -1
  15. package/dist/{rolldown-runtime-D7D4PA-g.mjs → rolldown-runtime-8H4AJuhK.mjs} +1 -0
  16. package/dist/run-tlcn1w7y.mjs +944 -0
  17. package/dist/{runtime-DiOTkDZz.d.mts → runtime-BstIkrhH.d.mts} +1 -1
  18. package/dist/sources-BooL2MsX.mjs +545 -0
  19. package/dist/testing.d.mts +305 -3
  20. package/dist/testing.mjs +2056 -2
  21. package/dist/types-BTycq8_Z.d.mts +1196 -0
  22. package/dist/{types-yg_ywtT-.d.mts → types-C0SLQsx0.d.mts} +230 -31
  23. package/dist/types-Cjf3ywai.d.mts +5982 -0
  24. package/dist/{define-sFoO3y6X.d.mts → types-D0uYTTC3.d.mts} +180 -51
  25. package/dist/{types-DWILGrPn.d.mts → types-DgwbzDLP.d.mts} +87 -19
  26. package/dist/types-KlE_GL1z.d.mts +1444 -0
  27. package/dist/{visual-BDUHSRvf.mjs → visual-NPrDkvUk.mjs} +19 -13
  28. package/package.json +17 -2
  29. package/dist/headless-CvamCUcR.mjs +0 -186
  30. package/dist/headless-KaSWcd0s.d.mts +0 -181
  31. package/dist/types-BxkNNYul.d.mts +0 -2840
  32. package/dist/types-CTPS9GBu.d.mts +0 -742
  33. package/dist/types-DD-QrG_z.d.mts +0 -588
  34. package/dist/types-DYLnSgMI.d.mts +0 -570
  35. package/dist/types-JNc_UQBo.d.mts +0 -2896
@@ -0,0 +1,51 @@
1
+ import { c as Source, d as HeadlessApp, n as Command, o as InputSchema } from "./types-D0uYTTC3.mjs";
2
+
3
+ //#region src/plugins/flow/doors/define.d.ts
4
+ /**
5
+ * Declares a source: a read-only view the editor lists, reads and watches. The types flow from
6
+ * the object: the input from `input`, the app from the `read` parameter, the output from its
7
+ * result.
8
+ *
9
+ * @param source - The descriptor.
10
+ * @returns The same descriptor, frozen.
11
+ * @throws {Error} When the id is not a dotted name such as `"game.position"`.
12
+ * @example
13
+ * ```ts
14
+ * // A game's .dev module: the orders on the board, re-read after every edge.
15
+ * export const orders = defineSource({
16
+ * id: "timber.orders",
17
+ * title: "Orders",
18
+ * input: {},
19
+ * changes: "edge",
20
+ * read: app => app.flow.state().path
21
+ * });
22
+ * read(app, orders); // "board/awaitIntent"
23
+ * ```
24
+ */
25
+ declare function defineSource<S extends InputSchema, O, App = HeadlessApp>(source: Source<S, O, App>): Source<S, O, App>;
26
+ /**
27
+ * Declares a command: a dev-only action the editor lists and runs. Its body starts with the
28
+ * inline dev guard, so a production build drops it.
29
+ *
30
+ * @param command - The descriptor.
31
+ * @returns The same descriptor, frozen.
32
+ * @throws {Error} When the id is not a dotted name such as `"game.answer"`.
33
+ * @example
34
+ * ```ts
35
+ * // A game's .dev module: open the shop from anywhere, through the graph.
36
+ * export const openShop = defineCommand({
37
+ * id: "timber.openShop",
38
+ * title: "Open the shop",
39
+ * input: {},
40
+ * effect: "route",
41
+ * run: app => {
42
+ * if (typeof __MOKU_GAME_DEV__ === "undefined" || !__MOKU_GAME_DEV__) throw controlRefused();
43
+ * return app.flow.walk([{ at: "home", intent: "shop" }]);
44
+ * }
45
+ * });
46
+ * (await run(app, openShop)).state.path; // "shop"
47
+ * ```
48
+ */
49
+ declare function defineCommand<S extends InputSchema, O, App = HeadlessApp>(command: Command<S, O, App>): Command<S, O, App>;
50
+ //#endregion
51
+ export { defineSource as n, defineCommand as t };
@@ -381,4 +381,33 @@ function graphHash(graph) {
381
381
  return hashText(stableJson(graph));
382
382
  }
383
383
  //#endregion
384
- export { graphHash as a, pushEntry as c, framePath as i, describeGraph as n, slotNames as o, findNode as r, compact as s, collectFlows as t };
384
+ //#region src/plugins/flow/doors/dev.ts
385
+ /**
386
+ * Reads the dev flag at call time. Undefined means off: production is the default.
387
+ *
388
+ * @returns True only when `__MOKU_GAME_DEV__` is exactly `true`.
389
+ * @example
390
+ * ```ts
391
+ * // The dev page set the flag in web/dev.ts before the engine started.
392
+ * globalThis.__MOKU_GAME_DEV__ = true;
393
+ * isDev(); // true
394
+ * ```
395
+ */
396
+ function isDev() {
397
+ return typeof __MOKU_GAME_DEV__ !== "undefined" && __MOKU_GAME_DEV__ === true;
398
+ }
399
+ /**
400
+ * Builds the error a control command throws outside a dev build.
401
+ *
402
+ * @returns The error, ready to throw.
403
+ * @example
404
+ * ```ts
405
+ * // A production build called a /control command.
406
+ * controlRefused().message; // "[game] Control commands run in dev builds only.\n Define __MOKU_GAME_DEV__ as true in the dev build."
407
+ * ```
408
+ */
409
+ function controlRefused() {
410
+ return /* @__PURE__ */ new Error("[game] Control commands run in dev builds only.\n Define __MOKU_GAME_DEV__ as true in the dev build.");
411
+ }
412
+ //#endregion
413
+ export { findNode as a, slotNames as c, describeGraph as i, compact as l, isDev as n, framePath as o, collectFlows as r, graphHash as s, controlRefused as t, pushEntry as u };
package/dist/index.d.mts CHANGED
@@ -1,16 +1,15 @@
1
- import { $ as PauseReason, A as Config$4, B as types_d_exports$8, C as SceneIdOf, D as Hint, E as GuideOptions, F as Config$3, G as SaveUnreadableError, J as RngApi, L as Json, N as types_d_exports$12, R as Root, T as Descriptor, V as Patch, X as Api$2, Z as Config$2, _ as DefineNode, a as GameTypes, at as State, c as TextStylesOf, ct as Events, d as exit, et as State$2, f as slot, h as FeatureDescription, i as FeaturePlugin, j as State$4, k as Api$3, l as types_d_exports$4, m as type, n as BundlesOf, nt as Api, ot as types_d_exports$3, p as to, q as StoreApi, r as Config$1, rt as Config, s as State$1, st as Config$5, t as Api$1, tt as types_d_exports$7, u as defineFlow, z as State$3 } from "./types-JNc_UQBo.mjs";
2
- import { A as ComponentHandle, B as SystemDefinition, C as ProjectionSpec, F as Mut, I as Narrowed, M as ComponentValue, R as QueryTerm, S as ProjectionMotion, V as TagType, a as types_d_exports$9, d as Config$7, f as State$6, g as Ease, h as DescriptionNode, i as State$5, j as ComponentType, k as AnyComponentValue, l as ViewportSize, n as Config$6, p as types_d_exports$14, t as Api$4, u as Api$5, x as NumericFields, z as ResourceType } from "./types-BxkNNYul.mjs";
3
- import { a as DefineBundles, c as LoadReason, d as Tier, i as Config$8, n as BundleMap, p as types_d_exports$1, r as BundleSpec, s as LoadBundles, t as Api$6, u as State$7 } from "./types-DWILGrPn.mjs";
4
- import { A as Transform, B as types_d_exports$5, C as NineSliceValue, D as Sprite, E as ShapeValue, H as InputApi, I as I18nApi, L as Message, M as sprite, N as Argument, O as SpriteOptions, P as Config$9, R as State$8, S as NineSlice, T as Shape, U as State$9, V as Config$10, W as types_d_exports$6, _ as Style, b as defineComponent, d as popup, f as defineTokens, g as ResolvedStyle, h as IsFlags, j as TransformValue, k as SpriteValue, l as Box, p as IntrinsicElementsFor, s as PopupComponent, u as LocalWrite, w as Parent, x as Display, y as WhenFlags, z as TypedTr } from "./types-yg_ywtT-.mjs";
5
- import { a as Config$11, c as TextApi, d as TextValue, f as types_d_exports$11, i as types_d_exports$13, l as TextStyleInput, n as State$11, o as Point, r as UiApi, s as State$10, t as Config$12, u as TextStyles } from "./types-DD-QrG_z.mjs";
6
- import { a as Config$13, c as SlotValues, d as types_d_exports, f as ExternalPlayer, g as Step, h as SfxDescriptor, i as BuildTools, l as State$12, m as PlayDescriptor, n as AnimationDefinition, o as MotionKeyframe, p as HapticDescriptor, r as AnimationSpec, s as SlotTags, t as AnimApi, u as Target } from "./types-CTPS9GBu.mjs";
7
- import { c as AnySceneProjection, d as SceneDefinition, f as SceneSpec, h as types_d_exports$10, i as MusicOptions, l as DefineScene, m as State$14, n as Config$14, o as State$13, p as ScenesApi, r as MusicDescriptor, s as types_d_exports$2, t as AudioApi, u as LayerMap } from "./types-DYLnSgMI.mjs";
1
+ import { $t as types_d_exports$3, At as Json, B as Mut, Bt as StoreApi, Ct as Config$5, D as ProjectionMotion, E as NumericFields, Et as types_d_exports$13, F as ComponentHandle, G as SystemDefinition, I as ComponentType, J as BundlesOf, Jt as types_d_exports$8, K as TagType, Kt as PauseReason, L as ComponentValue, Mt as State$3, Nt as types_d_exports$9, O as ProjectionSpec, Ot as Config$3, P as AnyComponentValue, Pt as Patch, Q as GameTypes, Qt as State, Rt as SaveUnreadableError, St as Api$4, U as QueryTerm, Ut as Api$2, V as Narrowed, Vt as RngApi, W as ResourceType, Wt as Config$2, X as EmitterIdOf, Xt as Config, Y as Config$1, Yt as Api, Z as FeaturePlugin, _ as State$6, at as slot, b as DescriptionNode, bt as Hint, c as types_d_exports$10, ct as FeatureDescription, en as Config$7, et as State$1, g as Config$6, gt as SceneIdOf, h as Api$5, it as exit, jt as Root, m as ViewportSize, n as Config$4, nt as types_d_exports$5, ot as to, q as Api$1, qt as State$2, rt as defineFlow, s as State$4, st as type, t as Api$3, tn as Events, tt as TextStylesOf, ut as DefineNode, v as types_d_exports$15, vt as Descriptor, wt as State$5, x as Ease, yt as GuideOptions } from "./types-Cjf3ywai.mjs";
2
+ import { a as DefineBundles, c as LoadReason, d as Tier, i as Config$8, n as BundleMap, p as types_d_exports$1, r as BundleSpec, s as LoadBundles, t as Api$6, u as State$7 } from "./types-DgwbzDLP.mjs";
3
+ import { A as Transform, B as types_d_exports$6, C as NineSliceValue, D as Sprite, E as ShapeValue, H as InputApi, I as I18nApi, L as Message, M as sprite, N as Argument, O as SpriteOptions, P as Config$9, R as State$8, S as NineSlice, T as Shape, U as State$9, V as Config$10, W as types_d_exports$7, _ as Style, b as defineComponent, d as popup, f as defineTokens, g as ResolvedStyle, h as IsFlags, j as TransformValue, k as SpriteValue, l as Box, p as IntrinsicElementsFor, s as PopupComponent, u as LocalWrite, w as Parent, x as Display, y as WhenFlags, z as TypedTr } from "./types-C0SLQsx0.mjs";
4
+ import { C as Point, D as TextStyles, E as TextStyleInput, O as TextValue, S as Config$12, T as TextApi, _ as Step, a as Config$11, b as UiApi, c as SlotTags, d as Target, f as types_d_exports, g as SfxDescriptor, h as PlayDescriptor, i as BuildTools, k as types_d_exports$12, l as SlotValues, m as HapticDescriptor, n as AnimationDefinition, o as FramesValue, p as ExternalPlayer, r as AnimationSpec, s as MotionKeyframe, t as AnimApi, u as State$10, v as Config$13, w as State$11, x as types_d_exports$14, y as State$12 } from "./types-KlE_GL1z.mjs";
5
+ import { A as FilterValueOf, C as EmitterValue, D as DisplacementValue, E as ColorMatrixValue, M as NoiseValue, N as OutlineValue, O as FilterComponent, P as UniformDeclaration, S as EmitterDefinition, T as BlurValue, _ as EffectsApi, b as types_d_exports$4, c as AnySceneProjection, d as SceneDefinition, f as SceneSpec, g as Config$15, h as types_d_exports$11, i as MusicOptions, j as GlowValue, k as FilterSpec, l as DefineScene, m as State$15, n as Config$14, o as State$13, p as ScenesApi, r as MusicDescriptor, s as types_d_exports$2, t as AudioApi, u as LayerMap, w as AlphaValue, x as EmitterConfig, y as State$14 } from "./types-BTycq8_Z.mjs";
8
6
 
9
7
  //#region src/plugins/text/components.d.ts
10
8
  /**
11
9
  * Words on the screen: a string or a message, the style it is drawn in, and the string `text`
12
- * resolved out of it. A game writes `content`, `style`, `bind` and `anchor`; `resolved` is
13
- * engine-owned and `ui` and the tests read it.
10
+ * resolved out of it. A game writes `content`, `style`, `bind`, `anchor` and `alpha`; `resolved`
11
+ * is engine-owned and `ui` and the tests read it. `alpha` (1 by default) fades the whole block and
12
+ * is patched in place, so a tween on it rebuilds nothing.
14
13
  */
15
14
  declare const Text: ComponentType<TextValue>;
16
15
  /**
@@ -37,7 +36,7 @@ type LabelOptions = {
37
36
  * ```ts
38
37
  * label({ text: "+5", style: "board.float", at: { x: 90, y: 180 } });
39
38
  * // [Text({ content: "+5", style: "board.float", bind: undefined,
40
- * // anchor: { x: 0.5, y: 0.5 }, resolved: "" }),
39
+ * // anchor: { x: 0.5, y: 0.5 }, alpha: 1, resolved: "" }),
41
40
  * // Transform({ x: 90, y: 180, rotation: 0, scale: 1 })]
42
41
  * ```
43
42
  */
@@ -112,7 +111,7 @@ type ProjectionFor<Player, Session> = <const LayerName extends string, const Lif
112
111
  * app.anim.play(coinsFly, { from: purse, to: counter }).marks(); // []: the first frame is next
113
112
  * ```
114
113
  */
115
- declare const animPlugin: import("@moku-labs/core").PluginInstance<"anim", Config$13, State$12, AnimApi, {
114
+ declare const animPlugin: import("@moku-labs/core").PluginInstance<"anim", Config$11, State$10, AnimApi, {
116
115
  "anim:mark": {
117
116
  animation: string;
118
117
  mark: string;
@@ -190,6 +189,23 @@ declare const audioPlugin: import("@moku-labs/core").PluginInstance<"audio", Con
190
189
  */
191
190
  declare const clockPlugin: import("@moku-labs/core").PluginInstance<"clock", Config, State, Api, {}> & Record<never, never>;
192
191
  //#endregion
192
+ //#region src/plugins/effects/index.d.ts
193
+ /**
194
+ * Effects plugin: `app.effects.stats()`; the `Emitter` component and every filter component do
195
+ * the rest as data on entities.
196
+ *
197
+ * @example
198
+ * ```ts
199
+ * // A game composes it next to the screen set; its features bring the emitters and filters.
200
+ * const app = createApp({
201
+ * plugins: [...screen, effectsPlugin, boardFeature],
202
+ * pluginConfigs: { renderer: { mount: "#game" }, effects: { maxPasses: 16 } }
203
+ * });
204
+ * app.effects.stats(); // { particles: 0, emitters: 0, filters: 0, renderPasses: 0 }: nothing runs before start
205
+ * ```
206
+ */
207
+ declare const effectsPlugin: import("@moku-labs/core").PluginInstance<"effects", Config$15, State$14, EffectsApi, {}> & Record<never, never>;
208
+ //#endregion
193
209
  //#region src/plugins/flow/index.d.ts
194
210
  /**
195
211
  * Flow plugin: `app.flow.run()`, `app.flow.gate.answer(...)`, `app.flow.fx.handle(...)`.
@@ -338,7 +354,7 @@ declare const modelPlugin: import("@moku-labs/core").PluginInstance<"model", Con
338
354
  * app.renderer.host.kind(); // "webgpu" in Chrome, "webgl" on an older device
339
355
  * ```
340
356
  */
341
- declare const rendererPlugin: import("@moku-labs/core").PluginInstance<"renderer", Config$6, State$5, Api$4, {
357
+ declare const rendererPlugin: import("@moku-labs/core").PluginInstance<"renderer", Config$4, State$4, Api$3, {
342
358
  "renderer:device-lost": {
343
359
  kind: "webgpu" | "webgl";
344
360
  reason: string;
@@ -361,7 +377,7 @@ declare const rendererPlugin: import("@moku-labs/core").PluginInstance<"renderer
361
377
  * export const awaitIntent = defineNode({ scene: "board", rest: true, outcomes: { merge: type() } });
362
378
  * ```
363
379
  */
364
- declare const scenesPlugin: import("@moku-labs/core").PluginInstance<"scenes", Record<string, never>, State$14, ScenesApi, {
380
+ declare const scenesPlugin: import("@moku-labs/core").PluginInstance<"scenes", Record<string, never>, State$15, ScenesApi, {
365
381
  "scenes:changed": {
366
382
  from: string | undefined;
367
383
  to: string;
@@ -386,7 +402,7 @@ declare const scenesPlugin: import("@moku-labs/core").PluginInstance<"scenes", R
386
402
  * app.text.styles(); // ["body", "digits", "hud.digits"]
387
403
  * ```
388
404
  */
389
- declare const textPlugin: import("@moku-labs/core").PluginInstance<"text", Config$11, State$10, TextApi, {}> & Record<never, never>;
405
+ declare const textPlugin: import("@moku-labs/core").PluginInstance<"text", Config$12, State$11, TextApi, {}> & Record<never, never>;
390
406
  //#endregion
391
407
  //#region src/plugins/time/index.d.ts
392
408
  /**
@@ -401,11 +417,12 @@ declare const textPlugin: import("@moku-labs/core").PluginInstance<"text", Confi
401
417
  * });
402
418
  * ```
403
419
  */
404
- declare const timePlugin: import("@moku-labs/core").PluginInstance<"time", Config$4, State$4, Api$3, {}> & Record<never, never>;
420
+ declare const timePlugin: import("@moku-labs/core").PluginInstance<"time", Config$5, State$5, Api$4, {}> & Record<never, never>;
405
421
  //#endregion
406
422
  //#region src/plugins/ui/index.d.ts
407
423
  /**
408
- * Ui plugin: `app.ui.tree()`, `app.ui.find(...)`, `app.ui.lint()`, the components `Box` and
424
+ * Ui plugin: `app.ui.tree()`, `app.ui.find(...)`, `app.ui.lint()`, `app.ui.fill(...)`, the
425
+ * text field `<input local>`, the components `Box` and
409
426
  * `LocalWrite`, and the helpers `defineComponent`, `defineStyle`, `defineTokens` and `popup`.
410
427
  *
411
428
  * @example
@@ -417,7 +434,7 @@ declare const timePlugin: import("@moku-labs/core").PluginInstance<"time", Confi
417
434
  * app.input.tap(app.ui.find("claim") ?? 0);
418
435
  * ```
419
436
  */
420
- declare const uiPlugin: import("@moku-labs/core").PluginInstance<"ui", Config$12, State$11, UiApi, {}> & Record<never, never>;
437
+ declare const uiPlugin: import("@moku-labs/core").PluginInstance<"ui", Config$13, State$12, UiApi, {}> & Record<never, never>;
421
438
  //#endregion
422
439
  //#region src/plugins/world/index.d.ts
423
440
  /**
@@ -433,7 +450,7 @@ declare const uiPlugin: import("@moku-labs/core").PluginInstance<"ui", Config$12
433
450
  * app.world.projection.entityOf("board.items", "i7"); // 1048576
434
451
  * ```
435
452
  */
436
- declare const worldPlugin: import("@moku-labs/core").PluginInstance<"world", Config$7, State$6, Api$5, {
453
+ declare const worldPlugin: import("@moku-labs/core").PluginInstance<"world", Config$6, State$6, Api$5, {
437
454
  "world:reconciled": {
438
455
  mode: "play" | "direct";
439
456
  projections: number;
@@ -789,6 +806,22 @@ declare function defineScene<Layers extends LayerMap, const Projections extends
789
806
  declare const Animation: ComponentType<{
790
807
  playing: number;
791
808
  }>;
809
+ /**
810
+ * A frame loop on an entity, for as long as the entity carries it: every `1000 / fps` ms
811
+ * `Sprite.texture` becomes the next key of `keys`, after the last key it wraps to the first. No
812
+ * timeline around it, not counted by `Animation` or `app.anim.active()`. A running `frames` step on
813
+ * the same entity owns the sprite until it ends; the loop goes on from where its clock stands.
814
+ * Paused and fast world modes and reduced motion stop the clock on the frame it shows.
815
+ *
816
+ * @example
817
+ * ```ts
818
+ * // A coin spins on the board for its whole life: a projection view returns both components.
819
+ * const coinSpin = ["items.coin-0", "items.coin-1", "items.coin-2", "items.coin-3"] as const;
820
+ * const coin = [Sprite({ texture: "items.coin-0" }), Frames({ keys: coinSpin, fps: 12 })];
821
+ * Frames({ keys: coinSpin, fps: 12 }).value.loop; // true: the default
822
+ * ```
823
+ */
824
+ declare const Frames: ComponentType<FramesValue>;
792
825
  //#endregion
793
826
  //#region src/plugins/anim/motion.d.ts
794
827
  /**
@@ -1242,6 +1275,147 @@ declare function resolve(style: Style | undefined, flags: StyleFlags, viewport:
1242
1275
  */
1243
1276
  declare function music(key: string | null, options?: MusicOptions): Descriptor;
1244
1277
  //#endregion
1278
+ //#region src/plugins/effects/filters/builtins.d.ts
1279
+ /**
1280
+ * A soft halo of `color` around the opaque pixels of a view and its subtree, `distance` pixels
1281
+ * wide, that follows the shape: rounded corners stay rounded. Its alpha is
1282
+ * `strength × alpha ×` the share of the disc of radius `distance` around the pixel the view
1283
+ * covers, so `strength: 2` is full next to a straight edge and fades to nothing at `distance`.
1284
+ * The view is padded by its live `distance`. One render pass per apply.
1285
+ *
1286
+ * @example
1287
+ * ```ts
1288
+ * // A merged item glows, and a motion hook tweens the glow away.
1289
+ * Glow({ strength: 4 }).value; // { strength: 4, distance: 10, color: 0xffffff, alpha: 1, enabled: true, order: 0 }
1290
+ * view.tween(Glow, { strength: 0 }, { ms: 200 });
1291
+ * ```
1292
+ */
1293
+ declare const Glow: FilterComponent<GlowValue>;
1294
+ /**
1295
+ * A ring of `thickness` pixels in `color` around the opaque pixels of a view and its subtree; the
1296
+ * view is padded by its live `thickness`. One render pass per apply.
1297
+ *
1298
+ * @example
1299
+ * ```ts
1300
+ * // The selected card is outlined in honey.
1301
+ * Outline({ thickness: 4, color: 0xffc233 }).value; // { thickness: 4, color: 0xffc233, alpha: 1, enabled: true, order: 0 }
1302
+ * ```
1303
+ */
1304
+ declare const Outline: FilterComponent<OutlineValue>;
1305
+ /**
1306
+ * Pixi's blur over a view and its subtree. `quality: 0` means `config.blur.quality`;
1307
+ * `resolution: 0` means `config.blur.phoneResolution` on a phone, otherwise 1. `repeatEdgePixels`
1308
+ * keeps the padding at 0. Costs `2 × quality` render passes per apply.
1309
+ *
1310
+ * @example
1311
+ * ```ts
1312
+ * // The board behind a popup: the filter sits on the ui slot that hosts the board.
1313
+ * Blur({ strength: 6 }).value; // { strength: 6, quality: 0, resolution: 0, repeatEdgePixels: true, enabled: true, order: 0 }
1314
+ * ```
1315
+ */
1316
+ declare const Blur: ComponentType<BlurValue>;
1317
+ /**
1318
+ * Pixi's colour matrix: brightness, saturation, contrast, hue in degrees and grayscale, composed
1319
+ * in that order from the identity on every change. Every default is the identity.
1320
+ *
1321
+ * @example
1322
+ * ```ts
1323
+ * // A locked card goes gray.
1324
+ * ColorMatrix({ grayscale: 1 }).value.grayscale; // 1
1325
+ * ```
1326
+ */
1327
+ declare const ColorMatrix: ComponentType<ColorMatrixValue>;
1328
+ /**
1329
+ * Pixi's noise. The seed is always given, never Pixi's random default, so two runs draw the same
1330
+ * grain.
1331
+ *
1332
+ * @example
1333
+ * ```ts
1334
+ * Noise({ amount: 0.2, seed: 7 }).value; // { amount: 0.2, seed: 7, enabled: true, order: 0 }
1335
+ * ```
1336
+ */
1337
+ declare const Noise: ComponentType<NoiseValue>;
1338
+ /**
1339
+ * Pixi's displacement over the texture of the asset key `map`. Nothing is drawn while the map is
1340
+ * not loaded; a missing key warns once.
1341
+ *
1342
+ * @example
1343
+ * ```ts
1344
+ * // Heat haze over the furnace.
1345
+ * Displacement({ map: "fx.ripple", scaleX: 8, scaleY: 8 }).value.map; // "fx.ripple"
1346
+ * ```
1347
+ */
1348
+ declare const Displacement: ComponentType<DisplacementValue>;
1349
+ /**
1350
+ * Pixi's alpha over a view and its subtree as one layer, so overlapping children do not show
1351
+ * through each other.
1352
+ *
1353
+ * @example
1354
+ * ```ts
1355
+ * Alpha({ alpha: 0.5 }).value; // { alpha: 0.5, enabled: true, order: 0 }
1356
+ * ```
1357
+ */
1358
+ declare const Alpha: ComponentType<AlphaValue>;
1359
+ //#endregion
1360
+ //#region src/plugins/effects/filters/define.d.ts
1361
+ /**
1362
+ * Turns a WGSL fragment body into a filter component type. The engine prepends the vertex stage,
1363
+ * the input bindings and a `FilterUniforms` struct in declaration order, bound as `fu`. Every
1364
+ * number uniform is a number field, so the existing `tween` drives it; a colour is one hex field
1365
+ * sent as a `vec3<f32>`; a tuple is an array field and not tweenable. Every filter component also
1366
+ * carries `enabled: true` and `order: 0`. Register it through the `filters` key of a feature.
1367
+ *
1368
+ * @param id - The filter id, also the component name; unique, and not one of the built-ins.
1369
+ * @param spec - The body, the uniforms, the passes one apply costs and the padding.
1370
+ * @returns The component type, with the frozen `filter` definition attached.
1371
+ * @throws {Error} When the id is empty, the body has no `mainFragment`, a uniform is reserved,
1372
+ * badly named or of no known form, or the passes or the padding break their rules.
1373
+ * @example
1374
+ * ```ts
1375
+ * // features/board/effects.ts: a gold tint a motion hook tweens on a merge.
1376
+ * const Tint = defineFilter("fx.tint", { wgsl: tintBody, uniforms: { amount: 0, color: { color: 0xffd700 } } });
1377
+ * Tint({ amount: 1 }).value; // { amount: 1, color: 0xffd700, enabled: true, order: 0 }
1378
+ * Tint.filter.passes; // 1
1379
+ * ```
1380
+ */
1381
+ declare function defineFilter<Uniforms extends Record<string, UniformDeclaration> = Record<never, never>>(id: string, spec: FilterSpec<Uniforms>): FilterComponent<FilterValueOf<Uniforms>>;
1382
+ //#endregion
1383
+ //#region src/plugins/effects/particles/component.d.ts
1384
+ /**
1385
+ * A particle effect on an entity. A `burst` effect emits when the component appears or its
1386
+ * `effect` changes; a `rate` effect emits while `active` is true and the entity lives. An effect in
1387
+ * `"world"` space outlives the entity, one in `"local"` space moves and dies with it. `""` draws
1388
+ * nothing. Plain JSON: it shows in `snapshot()`.
1389
+ *
1390
+ * @example
1391
+ * ```ts
1392
+ * // A merged item bursts stars from its enter hook; the generator steams for its whole life.
1393
+ * view.set(Emitter, { effect: "fx.starsBurst" });
1394
+ * Emitter({ effect: "fx.steam" }).value; // { effect: "fx.steam", active: true }
1395
+ * ```
1396
+ */
1397
+ declare const Emitter: ComponentType<EmitterValue>;
1398
+ //#endregion
1399
+ //#region src/plugins/effects/particles/define.d.ts
1400
+ /**
1401
+ * Describes a particle effect. Every field is optional except `textures` and exactly one of
1402
+ * `burst` and `rate`; the definition is frozen, registered through the `emitters` key of a feature
1403
+ * and started by an `Emitter` component naming its id.
1404
+ *
1405
+ * @param id - The effect id, unique across the features of the game.
1406
+ * @param config - The effect as data.
1407
+ * @returns The frozen definition `{ id, config }`, the config with every default filled in.
1408
+ * @throws {Error} When the id is empty or a field breaks its rule.
1409
+ * @example
1410
+ * ```ts
1411
+ * // features/board/effects.ts: the steam over the generator.
1412
+ * const steam = defineEmitter("fx.steam", { textures: ["fx.puff"], rate: 12, space: "local" });
1413
+ * steam.config.rate; // 12
1414
+ * steam.config.lifeMs; // [600, 1000], the default
1415
+ * ```
1416
+ */
1417
+ declare function defineEmitter(id: string, config: EmitterConfig): EmitterDefinition;
1418
+ //#endregion
1245
1419
  //#region src/index.d.ts
1246
1420
  /**
1247
1421
  * Creates a game application.
@@ -1255,7 +1429,7 @@ declare function music(key: string | null, options?: MusicOptions): Descriptor;
1255
1429
  * });
1256
1430
  * ```
1257
1431
  */
1258
- declare const createApp: <const ExtraPlugins extends readonly import("@moku-labs/core").AnyPluginInstance[] = readonly []>(options?: import("@moku-labs/core").CreateAppOptions<Config$5, Events, (import("@moku-labs/core").PluginInstance<"time", Config$4, State$4, Api$3, {}> & Record<never, never>) | (import("@moku-labs/core").PluginInstance<"lifecycle", Config$2, State$2, Api$2, {
1432
+ declare const createApp: <const ExtraPlugins extends readonly import("@moku-labs/core").AnyPluginInstance[] = readonly []>(options?: import("@moku-labs/core").CreateAppOptions<Config$7, Events, (import("@moku-labs/core").PluginInstance<"time", Config$5, State$5, Api$4, {}> & Record<never, never>) | (import("@moku-labs/core").PluginInstance<"lifecycle", Config$2, State$2, Api$2, {
1259
1433
  "lifecycle:changed": {
1260
1434
  reason: PauseReason;
1261
1435
  action: "push" | "pop";
@@ -1295,7 +1469,7 @@ declare const createApp: <const ExtraPlugins extends readonly import("@moku-labs
1295
1469
  rolledBackTo: string;
1296
1470
  retry: boolean;
1297
1471
  };
1298
- }> & Record<never, never>) | ExtraPlugins[number], [...ExtraPlugins], import("@moku-labs/core").CoreApisFromTuple<[import("@moku-labs/core").CorePluginInstance<"log", import("@moku-labs/common/browser").LogConfig, import("@moku-labs/common/browser").LogState, import("@moku-labs/common/browser").LogApi>, import("@moku-labs/core").CorePluginInstance<"env", import("@moku-labs/common/browser").EnvConfig, import("@moku-labs/common/browser").EnvState, import("@moku-labs/common/browser").EnvApi>]>> | undefined) => import("@moku-labs/core").App<Config$5, Events, (import("@moku-labs/core").PluginInstance<"time", Config$4, State$4, Api$3, {}> & Record<never, never>) | (import("@moku-labs/core").PluginInstance<"lifecycle", Config$2, State$2, Api$2, {
1472
+ }> & Record<never, never>) | ExtraPlugins[number], [...ExtraPlugins], import("@moku-labs/core").CoreApisFromTuple<[import("@moku-labs/core").CorePluginInstance<"log", import("@moku-labs/common/browser").LogConfig, import("@moku-labs/common/browser").LogState, import("@moku-labs/common/browser").LogApi>, import("@moku-labs/core").CorePluginInstance<"env", import("@moku-labs/common/browser").EnvConfig, import("@moku-labs/common/browser").EnvState, import("@moku-labs/common/browser").EnvApi>]>> | undefined) => import("@moku-labs/core").App<Config$7, Events, (import("@moku-labs/core").PluginInstance<"time", Config$5, State$5, Api$4, {}> & Record<never, never>) | (import("@moku-labs/core").PluginInstance<"lifecycle", Config$2, State$2, Api$2, {
1299
1473
  "lifecycle:changed": {
1300
1474
  reason: PauseReason;
1301
1475
  action: "push" | "pop";
@@ -1348,14 +1522,15 @@ declare const createApp: <const ExtraPlugins extends readonly import("@moku-labs
1348
1522
  * });
1349
1523
  * ```
1350
1524
  */
1351
- declare const createPlugin: import("@moku-labs/core").BoundCreatePluginFunction<Config$5, Events, import("@moku-labs/core").CoreApisFromTuple<[import("@moku-labs/core").CorePluginInstance<"log", import("@moku-labs/common/browser").LogConfig, import("@moku-labs/common/browser").LogState, import("@moku-labs/common/browser").LogApi>, import("@moku-labs/core").CorePluginInstance<"env", import("@moku-labs/common/browser").EnvConfig, import("@moku-labs/common/browser").EnvState, import("@moku-labs/common/browser").EnvApi>]>>;
1525
+ declare const createPlugin: import("@moku-labs/core").BoundCreatePluginFunction<Config$7, Events, import("@moku-labs/core").CoreApisFromTuple<[import("@moku-labs/core").CorePluginInstance<"log", import("@moku-labs/common/browser").LogConfig, import("@moku-labs/common/browser").LogState, import("@moku-labs/common/browser").LogApi>, import("@moku-labs/core").CorePluginInstance<"env", import("@moku-labs/common/browser").EnvConfig, import("@moku-labs/common/browser").EnvState, import("@moku-labs/common/browser").EnvApi>]>>;
1352
1526
  /**
1353
1527
  * Binds the authoring helpers to the types of one game: "createApp for a game". Each plugin binds
1354
1528
  * its own helpers (`flowFor`, `projectionFor`, `componentsFor`, `bundlesFor`, `scenesFor`); this
1355
1529
  * only spreads them, so the kit's type is inferred and never written by hand. At run time these
1356
1530
  * are the same functions and component objects the plugins export.
1357
1531
  *
1358
- * @returns The helpers typed with the game's `player`, `session`, `assets`, `bundles` and `strings`.
1532
+ * @returns The helpers typed with the game's `player`, `session`, `assets`, `bundles`, `strings`
1533
+ * and `emitters`.
1359
1534
  * @example
1360
1535
  * ```ts
1361
1536
  * // kit.ts of a game: bound once, imported by every node, flow and view file.
@@ -1364,6 +1539,16 @@ declare const createPlugin: import("@moku-labs/core").BoundCreatePluginFunction<
1364
1539
  * ```
1365
1540
  */
1366
1541
  declare function defineGame<Types extends GameTypes>(): {
1542
+ defineEmitter: (id: EmitterIdOf<Types>, config: Omit<EmitterConfig, "textures"> & {
1543
+ readonly textures: readonly Types["assets"][];
1544
+ }) => EmitterDefinition;
1545
+ Emitter: Narrowed<EmitterValue, {
1546
+ effect?: EmitterIdOf<Types>;
1547
+ active?: boolean;
1548
+ }>;
1549
+ Displacement: Narrowed<DisplacementValue, Partial<Omit<DisplacementValue, "map">> & {
1550
+ map?: Types["assets"];
1551
+ }>;
1367
1552
  music: MusicDescriptor<Types["assets"]>;
1368
1553
  defineComponent: typeof defineComponent;
1369
1554
  defineStyle: <const Given extends Style<Types["assets"]>>(style: Given) => Readonly<Given>;
@@ -1392,6 +1577,9 @@ declare function defineGame<Types extends GameTypes>(): {
1392
1577
  bus?: string;
1393
1578
  }) => SfxDescriptor;
1394
1579
  play: typeof play;
1580
+ Frames: Narrowed<FramesValue, Partial<Omit<FramesValue, "keys">> & {
1581
+ keys?: readonly Types["assets"][];
1582
+ }>;
1395
1583
  defineScene: DefineScene<Types["assets"], BundlesOf<Types>>;
1396
1584
  defineBundles: DefineBundles<BundlesOf<Types>>;
1397
1585
  load: LoadBundles<BundlesOf<Types>>;
@@ -1415,14 +1603,14 @@ declare function defineGame<Types extends GameTypes>(): {
1415
1603
  };
1416
1604
  /**
1417
1605
  * The screen plugins, in dependency order. A game with a screen spreads them into `plugins`;
1418
- * a headless test leaves them out. V2: `world`, `renderer`, `input`, `assets`, `scenes`. V3 appends `anim`, `i18n`, `text`, `ui`; `audio` stays opt-in: `[...screen, audioPlugin]`.
1606
+ * a headless test leaves them out. V2: `world`, `renderer`, `input`, `assets`, `scenes`. V3 appends `anim`, `i18n`, `text`, `ui`; `audio` and `effects` stay opt-in: `[...screen, audioPlugin, effectsPlugin]`.
1419
1607
  *
1420
1608
  * @example
1421
1609
  * ```ts
1422
1610
  * createApp({ plugins: [...screen, boardFeature], pluginConfigs: { renderer: { mount: "#game" } } });
1423
1611
  * ```
1424
1612
  */
1425
- declare const screen: readonly [import("@moku-labs/core").PluginInstance<"world", Config$7, State$6, Api$5, {
1613
+ declare const screen: readonly [import("@moku-labs/core").PluginInstance<"world", Config$6, State$6, Api$5, {
1426
1614
  "world:reconciled": {
1427
1615
  mode: "play" | "direct";
1428
1616
  projections: number;
@@ -1434,7 +1622,7 @@ declare const screen: readonly [import("@moku-labs/core").PluginInstance<"world"
1434
1622
  hintsRouted: number;
1435
1623
  hintsDropped: number;
1436
1624
  };
1437
- }> & Record<never, never>, import("@moku-labs/core").PluginInstance<"renderer", Config$6, State$5, Api$4, {
1625
+ }> & Record<never, never>, import("@moku-labs/core").PluginInstance<"renderer", Config$4, State$4, Api$3, {
1438
1626
  "renderer:device-lost": {
1439
1627
  kind: "webgpu" | "webgl";
1440
1628
  reason: string;
@@ -1458,13 +1646,13 @@ declare const screen: readonly [import("@moku-labs/core").PluginInstance<"world"
1458
1646
  reason: "budget" | "request";
1459
1647
  keys: readonly string[];
1460
1648
  };
1461
- }> & Record<never, never>, import("@moku-labs/core").PluginInstance<"scenes", Record<string, never>, State$14, ScenesApi, {
1649
+ }> & Record<never, never>, import("@moku-labs/core").PluginInstance<"scenes", Record<string, never>, State$15, ScenesApi, {
1462
1650
  "scenes:changed": {
1463
1651
  from: string | undefined;
1464
1652
  to: string;
1465
1653
  music: string | undefined;
1466
1654
  };
1467
- }> & Record<never, never>, import("@moku-labs/core").PluginInstance<"anim", Config$13, State$12, AnimApi, {
1655
+ }> & Record<never, never>, import("@moku-labs/core").PluginInstance<"anim", Config$11, State$10, AnimApi, {
1468
1656
  "anim:mark": {
1469
1657
  animation: string;
1470
1658
  mark: string;
@@ -1476,6 +1664,6 @@ declare const screen: readonly [import("@moku-labs/core").PluginInstance<"world"
1476
1664
  "i18n:locale-changed": {
1477
1665
  locale: string;
1478
1666
  };
1479
- }> & Record<never, never>, import("@moku-labs/core").PluginInstance<"text", Config$11, State$10, TextApi, {}> & Record<never, never>, import("@moku-labs/core").PluginInstance<"ui", Config$12, State$11, UiApi, {}> & Record<never, never>];
1667
+ }> & Record<never, never>, import("@moku-labs/core").PluginInstance<"text", Config$12, State$11, TextApi, {}> & Record<never, never>, import("@moku-labs/core").PluginInstance<"ui", Config$13, State$12, UiApi, {}> & Record<never, never>];
1480
1668
  //#endregion
1481
- export { types_d_exports as Anim, Animation, types_d_exports$1 as Assets, types_d_exports$2 as Audio, Box, types_d_exports$3 as Clock, type DescriptionNode, Display, Draggable, DropTarget, Exiting, types_d_exports$4 as Flow, Held, Hovered, types_d_exports$5 as I18n, types_d_exports$6 as Input, Layer, types_d_exports$7 as Lifecycle, LocalWrite, types_d_exports$8 as Model, NineSlice, Order, Parent, Pointer, PointerOver, Pressable, Pressed, types_d_exports$9 as Renderer, SaveUnreadableError, types_d_exports$10 as Scenes, Shape, Sprite, Swipeable, Tappable, Text, types_d_exports$11 as TextTypes, types_d_exports$12 as Time, Touchable, Transform, Tree, types_d_exports$13 as Ui, types_d_exports$14 as World, animPlugin, assetsPlugin, audioPlugin, clockPlugin, component, createApp, createPlugin, defineAnimation, defineBundles, defineComponent, defineFeature, defineGame, defineMotion, defineScene, defineStyle, defineTextStyles, defineTokens, exit, external, flowPlugin, frames, guide, haptic, hint, i18nPlugin, inputPlugin, label, lifecyclePlugin, load, mark, modelPlugin, music, mut, parallel, play, popup, projection, rendererPlugin, resolve, resource, scenesPlugin, schedule, screen, sequence, set, sfx, slot, spawn, spawned, sprite, stagger, system, tag, textPlugin, timePlugin, to, tr, tween, type, uiPlugin, use, wait, worldPlugin };
1669
+ export { Alpha, types_d_exports as Anim, Animation, types_d_exports$1 as Assets, types_d_exports$2 as Audio, Blur, Box, types_d_exports$3 as Clock, ColorMatrix, type DescriptionNode, Displacement, Display, Draggable, DropTarget, types_d_exports$4 as Effects, Emitter, Exiting, types_d_exports$5 as Flow, Frames, Glow, Held, Hovered, types_d_exports$6 as I18n, types_d_exports$7 as Input, Layer, types_d_exports$8 as Lifecycle, LocalWrite, types_d_exports$9 as Model, NineSlice, Noise, Order, Outline, Parent, Pointer, PointerOver, Pressable, Pressed, types_d_exports$10 as Renderer, SaveUnreadableError, types_d_exports$11 as Scenes, Shape, Sprite, Swipeable, Tappable, Text, types_d_exports$12 as TextTypes, types_d_exports$13 as Time, Touchable, Transform, Tree, types_d_exports$14 as Ui, types_d_exports$15 as World, animPlugin, assetsPlugin, audioPlugin, clockPlugin, component, createApp, createPlugin, defineAnimation, defineBundles, defineComponent, defineEmitter, defineFeature, defineFilter, defineGame, defineMotion, defineScene, defineStyle, defineTextStyles, defineTokens, effectsPlugin, exit, external, flowPlugin, frames, guide, haptic, hint, i18nPlugin, inputPlugin, label, lifecyclePlugin, load, mark, modelPlugin, music, mut, parallel, play, popup, projection, rendererPlugin, resolve, resource, scenesPlugin, schedule, screen, sequence, set, sfx, slot, spawn, spawned, sprite, stagger, system, tag, textPlugin, timePlugin, to, tr, tween, type, uiPlugin, use, wait, worldPlugin };