@lute-lang/player-web 0.0.0-stage → 0.40.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.
- package/README.md +44 -2
- package/dist/assets/pixiAssets.d.ts +47 -0
- package/dist/assets/pixiAssetsBackend.d.ts +3 -0
- package/dist/audio/pixiAudio.d.ts +61 -0
- package/dist/audio/pixiSoundBackend.d.ts +3 -0
- package/dist/choice/choiceMenu.d.ts +56 -0
- package/dist/effects/catalogue.d.ts +52 -0
- package/dist/engine/app.d.ts +14 -0
- package/dist/engine/behaviours.d.ts +35 -0
- package/dist/engine/easing.d.ts +24 -0
- package/dist/engine/types.d.ts +70 -0
- package/dist/engine/world.d.ts +10 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +3361 -0
- package/dist/input/gamepad.d.ts +22 -0
- package/dist/input/index.d.ts +7 -0
- package/dist/input/map.d.ts +42 -0
- package/dist/mount.d.ts +31 -0
- package/dist/presenter/index.d.ts +1 -0
- package/dist/presenter/pixiPresenter.d.ts +66 -0
- package/dist/scene/actor.d.ts +26 -0
- package/dist/scene/background.d.ts +24 -0
- package/dist/scene/camera.d.ts +37 -0
- package/dist/scene/cgLayer.d.ts +21 -0
- package/dist/scene/index.d.ts +7 -0
- package/dist/scene/shared.d.ts +36 -0
- package/dist/scene/vfx.d.ts +14 -0
- package/dist/scene/videoLayer.d.ts +21 -0
- package/dist/text/dialogueWindow.d.ts +52 -0
- package/dist/text/richText.d.ts +37 -0
- package/dist/text/segments.d.ts +31 -0
- package/dist/theme.d.ts +7 -0
- package/dist/ui/index.d.ts +3 -0
- package/dist/ui/screens/backlog-screen.d.ts +1 -0
- package/dist/ui/screens/backlog.d.ts +25 -0
- package/dist/ui/screens/common.d.ts +68 -0
- package/dist/ui/screens/confirm.d.ts +1 -0
- package/dist/ui/screens/ended.d.ts +1 -0
- package/dist/ui/screens/halted.d.ts +1 -0
- package/dist/ui/screens/hud.d.ts +1 -0
- package/dist/ui/screens/idle.d.ts +1 -0
- package/dist/ui/screens/index.d.ts +4 -0
- package/dist/ui/screens/loading.d.ts +1 -0
- package/dist/ui/screens/menu.d.ts +1 -0
- package/dist/ui/screens/save-load-screen.d.ts +1 -0
- package/dist/ui/screens/save-load.d.ts +14 -0
- package/dist/ui/screens/settings-screen.d.ts +1 -0
- package/dist/ui/screens/settings.d.ts +13 -0
- package/dist/ui/screens/title.d.ts +1 -0
- package/dist/ui/ui.d.ts +65 -0
- package/dist/ui/widgets/base.d.ts +54 -0
- package/dist/ui/widgets/button.d.ts +15 -0
- package/dist/ui/widgets/controls.d.ts +47 -0
- package/dist/ui/widgets/focus-manager.d.ts +1 -0
- package/dist/ui/widgets/index.d.ts +4 -0
- package/dist/ui/widgets/label.d.ts +1 -0
- package/dist/ui/widgets/list.d.ts +50 -0
- package/dist/ui/widgets/panel.d.ts +1 -0
- package/dist/ui/widgets/scroll-list.d.ts +1 -0
- package/dist/ui/widgets/segmented.d.ts +1 -0
- package/dist/ui/widgets/slider.d.ts +1 -0
- package/dist/ui/widgets/toggle.d.ts +1 -0
- package/package.json +48 -4
package/README.md
CHANGED
|
@@ -1,3 +1,45 @@
|
|
|
1
|
-
#
|
|
1
|
+
# @lute-lang/player-web
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
The Lute 0.40 browser visual-novel player. It supplies PixiJS 8 rendering, Web Audio, screens, and keyboard/mouse/touch/gamepad input for the renderer-free `@lute-lang/player` core.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```sh
|
|
8
|
+
bun add @lute-lang/player-web@0.40.0 @lute-lang/player@0.40.0 @lute-lang/runtime@0.40.0 effect@4.0.2 @effect/platform-browser@4.0.2 pixi.js@8.22.0 @pixi/sound@6.0.1
|
|
9
|
+
# npm install @lute-lang/player-web@0.40.0 @lute-lang/player@0.40.0 @lute-lang/runtime@0.40.0 effect@4.0.2 @effect/platform-browser@4.0.2 pixi.js@8.22.0 @pixi/sound@6.0.1
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
The package requires exact `effect@4.0.2` and `@effect/platform-browser@4.0.2` peers. Runtime and player packages are released in lockstep.
|
|
13
|
+
|
|
14
|
+
## Minimal usage
|
|
15
|
+
|
|
16
|
+
Serve a `lute compile --all` bundle, the runtime wasm file, the bindings file, and its assets. Then mount into an element:
|
|
17
|
+
|
|
18
|
+
```ts
|
|
19
|
+
import { mountPlayer } from "@lute-lang/player-web"
|
|
20
|
+
|
|
21
|
+
const player = await mountPlayer(document.querySelector("#player")!, {
|
|
22
|
+
bindings: { url: "/player.bindings.yaml" },
|
|
23
|
+
bundleUrl: "/bundle/",
|
|
24
|
+
wasmUrl: "/wasm/lute_runtime_wasm_bg.wasm",
|
|
25
|
+
assetsUrl: "/assets/",
|
|
26
|
+
storageKey: "my-game"
|
|
27
|
+
})
|
|
28
|
+
|
|
29
|
+
await player.act({ type: "newGame" })
|
|
30
|
+
const view = await player.view()
|
|
31
|
+
// Later:
|
|
32
|
+
await player.unmount()
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
`bindings` accepts a decoded `Bindings` object, YAML text, or `{ url }`. `assetsUrl` overrides the file's `assetsBase`; `host` supplies custom bridge/idle behavior. `mountPlayer` returns Promise methods `act`, `view`, and `unmount`. The Effect-native `LuteWeb.mount` is available when the application already manages an Effect scope.
|
|
36
|
+
|
|
37
|
+
## API and guides
|
|
38
|
+
|
|
39
|
+
- [Web architecture](../../docs/player/web-architecture.md)
|
|
40
|
+
- [Getting started](/player/getting-started/)
|
|
41
|
+
- [Controls](/player/controls/)
|
|
42
|
+
- [Bindings reference](/player/bindings/)
|
|
43
|
+
- [Demo game](../../examples/player-demo/)
|
|
44
|
+
|
|
45
|
+
Source and releases: [github.com/journeyWorker/lute](https://github.com/journeyWorker/lute).
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { Texture } from "pixi.js";
|
|
2
|
+
import { Effect, Scope, Stream } from "effect";
|
|
3
|
+
import { AssetMissing, type AssetLoader } from "@lute-lang/player";
|
|
4
|
+
/** Backend seam for PixiAssets; tests can use an in-memory loader. */
|
|
5
|
+
export interface AssetBackend {
|
|
6
|
+
readonly loadTexture: (url: string) => Effect.Effect<Texture, unknown>;
|
|
7
|
+
readonly unloadTexture: (url: string, texture: Texture) => Effect.Effect<void, never>;
|
|
8
|
+
readonly loadAudio: (url: string) => Effect.Effect<void, unknown>;
|
|
9
|
+
readonly unloadAudio: (url: string) => Effect.Effect<void, never>;
|
|
10
|
+
}
|
|
11
|
+
/** Constructor options for {@link PixiAssets}. */
|
|
12
|
+
export interface PixiAssetsOptions {
|
|
13
|
+
readonly assetsBase?: string;
|
|
14
|
+
readonly backend: AssetBackend;
|
|
15
|
+
readonly concurrency?: number;
|
|
16
|
+
readonly graceSeconds?: number;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Pixi-backed, scoped and ref-counted AssetLoader. A scope that calls ensure owns
|
|
20
|
+
* one reference to every requested file; the references are released by its finalizer.
|
|
21
|
+
*/
|
|
22
|
+
export declare class PixiAssets implements AssetLoader {
|
|
23
|
+
readonly progress: Stream.Stream<number>;
|
|
24
|
+
private readonly backend;
|
|
25
|
+
private readonly base;
|
|
26
|
+
private readonly maxConcurrency;
|
|
27
|
+
private readonly graceSeconds;
|
|
28
|
+
private readonly progressRef;
|
|
29
|
+
private readonly records;
|
|
30
|
+
private readonly unloadFibers;
|
|
31
|
+
constructor(options: PixiAssetsOptions);
|
|
32
|
+
/** Ensure all files are loaded and retain them until the caller's scope closes. */
|
|
33
|
+
readonly ensure: (files: ReadonlyArray<string>) => Effect.Effect<void, AssetMissing, Scope.Scope>;
|
|
34
|
+
/** Return a loaded image/video texture, or undefined before ensure. */
|
|
35
|
+
readonly texture: (file: string) => Texture | undefined;
|
|
36
|
+
/** Return a loaded video texture, or undefined before ensure. */
|
|
37
|
+
readonly video: (file: string) => Texture | undefined;
|
|
38
|
+
private readonly acquire;
|
|
39
|
+
private readonly release;
|
|
40
|
+
private readonly unload;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Collect binding-referenced files in stable insertion order. Dynamic keys such
|
|
44
|
+
* as effect names, colours, labels and flow occasions are intentionally ignored.
|
|
45
|
+
* Voice patterns are deliberately excluded because they are generated per line.
|
|
46
|
+
*/
|
|
47
|
+
export declare const assetsFromBindings: (bindings: unknown) => ReadonlyArray<string>;
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { Effect, SubscriptionRef } from "effect";
|
|
2
|
+
import type { AudioChannel, AudioPlay, AudioPort, Volumes } from "@lute-lang/player";
|
|
3
|
+
/** A typed failure raised by the sound backend while decoding or starting media. */
|
|
4
|
+
export declare class AudioDecodeError extends Error {
|
|
5
|
+
readonly file: string;
|
|
6
|
+
readonly _tag = "AudioDecodeError";
|
|
7
|
+
constructor(file: string, cause: unknown);
|
|
8
|
+
}
|
|
9
|
+
/** The playback object required by {@link PixiAudio}; useful for deterministic unit tests. */
|
|
10
|
+
export interface AudioPlayback {
|
|
11
|
+
readonly setVolume: (volume: number) => void;
|
|
12
|
+
readonly stop: () => void;
|
|
13
|
+
readonly ended: Effect.Effect<void>;
|
|
14
|
+
}
|
|
15
|
+
/** Backend seam for PixiAudio. The default implementation delegates to @pixi/sound. */
|
|
16
|
+
export interface AudioBackend {
|
|
17
|
+
readonly load: (file: string) => Effect.Effect<void, AudioDecodeError>;
|
|
18
|
+
readonly play: (file: string, options: {
|
|
19
|
+
readonly loop: boolean;
|
|
20
|
+
readonly volume: number;
|
|
21
|
+
}) => Effect.Effect<AudioPlayback, AudioDecodeError>;
|
|
22
|
+
readonly unlock: Effect.Effect<void, AudioDecodeError>;
|
|
23
|
+
}
|
|
24
|
+
/** Constructor options for {@link PixiAudio}. */
|
|
25
|
+
export interface PixiAudioOptions {
|
|
26
|
+
readonly backend: AudioBackend;
|
|
27
|
+
readonly logger?: (message: string, error?: unknown) => void;
|
|
28
|
+
readonly initialVolumes?: Volumes;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* PixiJS/@pixi-sound implementation of the player AudioPort.
|
|
32
|
+
*
|
|
33
|
+
* Playback is deliberately best-effort: an absent optional file is logged and does
|
|
34
|
+
* not stop the story. Fade jobs run in detached Effect fibers so superseding a
|
|
35
|
+
* channel interrupts the old Clock-driven fade without interrupting the caller.
|
|
36
|
+
*/
|
|
37
|
+
export declare class PixiAudio implements AudioPort {
|
|
38
|
+
readonly unlocked: SubscriptionRef.SubscriptionRef<boolean>;
|
|
39
|
+
readonly unlock: Effect.Effect<void, AudioDecodeError>;
|
|
40
|
+
private readonly backend;
|
|
41
|
+
private readonly logger;
|
|
42
|
+
private readonly active;
|
|
43
|
+
private currentVolumes;
|
|
44
|
+
private readonly gate;
|
|
45
|
+
constructor(options: PixiAudioOptions);
|
|
46
|
+
/** Play a channel sound, waiting for finite sounds to end. */
|
|
47
|
+
readonly play: (channel: AudioChannel, soundToPlay: AudioPlay) => Effect.Effect<void>;
|
|
48
|
+
/** Fade and stop every playback currently in a channel. */
|
|
49
|
+
readonly stop: (channel: AudioChannel, fade: number) => Effect.Effect<void>;
|
|
50
|
+
/** Set master/channel gains and apply them immediately to every active instance. */
|
|
51
|
+
readonly setVolumes: (volumes: Volumes) => Effect.Effect<void>;
|
|
52
|
+
private effectiveVolume;
|
|
53
|
+
private removeRecord;
|
|
54
|
+
private readonly interruptFade;
|
|
55
|
+
private readonly startFade;
|
|
56
|
+
private readonly fadeOutAndStop;
|
|
57
|
+
private readonly stopVoiceImmediately;
|
|
58
|
+
private readonly replaceMusic;
|
|
59
|
+
}
|
|
60
|
+
/** Construct a PixiAudio from an injected backend. */
|
|
61
|
+
export declare const makePixiAudio: (options: PixiAudioOptions) => PixiAudio;
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { Effect, Stream } from "effect";
|
|
2
|
+
import { Container } from "pixi.js";
|
|
3
|
+
import type { ChoiceView } from "@lute-lang/player";
|
|
4
|
+
import type { Theme } from "../engine/types.js";
|
|
5
|
+
/** A menu option with the runtime's visibility verdict and authored display text. */
|
|
6
|
+
export interface ChoiceOption {
|
|
7
|
+
readonly id: string;
|
|
8
|
+
readonly verdict: string;
|
|
9
|
+
readonly text?: string;
|
|
10
|
+
readonly once?: boolean;
|
|
11
|
+
readonly exit?: boolean;
|
|
12
|
+
}
|
|
13
|
+
type ChoiceInput = ChoiceView;
|
|
14
|
+
/** Whether a runtime verdict leaves an option selectable. */
|
|
15
|
+
export declare const isChoiceEnabled: (verdict: string) => boolean;
|
|
16
|
+
/** Immutable keyboard/pointer navigation state. */
|
|
17
|
+
export interface ChoiceNavigationState {
|
|
18
|
+
readonly ids: ReadonlyArray<string>;
|
|
19
|
+
readonly enabled: ReadonlyArray<boolean>;
|
|
20
|
+
readonly focused: number;
|
|
21
|
+
}
|
|
22
|
+
/** Creates navigation state, selecting the first enabled option. */
|
|
23
|
+
export declare const choiceNavigation: (options: ReadonlyArray<ChoiceOption>) => ChoiceNavigationState;
|
|
24
|
+
/** Applies a navigation key or a one-based digit to a menu state. */
|
|
25
|
+
export declare const navigateChoice: (state: ChoiceNavigationState, key: "up" | "down" | "enter" | string) => ChoiceNavigationState | string | undefined;
|
|
26
|
+
/** A vertical, keyboard and pointer accessible choice menu. */
|
|
27
|
+
export declare class ChoiceMenu {
|
|
28
|
+
readonly target: Container;
|
|
29
|
+
private readonly theme;
|
|
30
|
+
private readonly panel;
|
|
31
|
+
private readonly prompt;
|
|
32
|
+
private readonly optionsLayer;
|
|
33
|
+
private readonly countdown;
|
|
34
|
+
private readonly rendered;
|
|
35
|
+
private navigation;
|
|
36
|
+
private deferred;
|
|
37
|
+
private resolveChoice;
|
|
38
|
+
private maxRemaining;
|
|
39
|
+
private remainingValue;
|
|
40
|
+
private pulsePhase;
|
|
41
|
+
constructor(parent: Container, theme: Theme);
|
|
42
|
+
/** Shows a menu and resolves with the selected option id. */
|
|
43
|
+
show: (choice: ChoiceInput, remaining: Stream.Stream<number>) => Effect.Effect<string>;
|
|
44
|
+
/** Hides the menu and removes all option children. */
|
|
45
|
+
readonly hide: Effect.Effect<void>;
|
|
46
|
+
/** Updates the countdown from a test or host without consuming a stream. */
|
|
47
|
+
readonly setRemaining: (seconds: number) => void;
|
|
48
|
+
/** Advances the countdown pulse by seconds; called by a ticker if desired. */
|
|
49
|
+
readonly tick: (dt: number) => void;
|
|
50
|
+
private readonly keydown;
|
|
51
|
+
private pointerAt;
|
|
52
|
+
private renderOptions;
|
|
53
|
+
private updateFocus;
|
|
54
|
+
private drawCountdown;
|
|
55
|
+
}
|
|
56
|
+
export {};
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { Effect, Schema } from "effect";
|
|
2
|
+
import { Container } from "pixi.js";
|
|
3
|
+
import type { Behaviour } from "../engine/types.js";
|
|
4
|
+
/** Names accepted by the 0.40 player effect catalogue. */
|
|
5
|
+
export type EffectName = "fade" | "dissolve" | "wipeLeft" | "wipeRight" | "wipeUp" | "wipeDown" | "slideLeft" | "slideRight" | "cut" | "fadeIn" | "fadeOut" | "slideIn" | "slideOut" | "hop" | "shake" | "none" | "zoom" | "pan" | "flash" | "blur" | "tint";
|
|
6
|
+
/** Values accepted in a binding effect parameter object. */
|
|
7
|
+
export type EffectParams = Readonly<Record<string, number | string | boolean>>;
|
|
8
|
+
/** Optional scene context needed by camera and full-screen effects. */
|
|
9
|
+
export interface EffectContext {
|
|
10
|
+
readonly design?: {
|
|
11
|
+
readonly width: number;
|
|
12
|
+
readonly height: number;
|
|
13
|
+
};
|
|
14
|
+
readonly overlay?: Container;
|
|
15
|
+
readonly camera?: Container;
|
|
16
|
+
}
|
|
17
|
+
declare const EffectDecodeError_base: Schema.Class<EffectDecodeError, Schema.TaggedStruct<"EffectDecodeError", {
|
|
18
|
+
readonly effect: Schema.String;
|
|
19
|
+
readonly parameter: Schema.String;
|
|
20
|
+
readonly message: Schema.String;
|
|
21
|
+
}>, import("effect/Cause").YieldableError>;
|
|
22
|
+
/** Typed decoding failure for an effect name, parameter name, or parameter value. */
|
|
23
|
+
export declare class EffectDecodeError extends EffectDecodeError_base {
|
|
24
|
+
}
|
|
25
|
+
declare const UnknownEffect_base: Schema.Class<UnknownEffect, Schema.TaggedStruct<"UnknownEffect", {
|
|
26
|
+
readonly name: Schema.String;
|
|
27
|
+
}>, import("effect/Cause").YieldableError>;
|
|
28
|
+
/** Compatibility error for callers that distinguish unknown names. */
|
|
29
|
+
export declare class UnknownEffect extends UnknownEffect_base {
|
|
30
|
+
}
|
|
31
|
+
declare const UnknownEffectParameter_base: Schema.Class<UnknownEffectParameter, Schema.TaggedStruct<"UnknownEffectParameter", {
|
|
32
|
+
readonly effect: Schema.String;
|
|
33
|
+
readonly parameter: Schema.String;
|
|
34
|
+
}>, import("effect/Cause").YieldableError>;
|
|
35
|
+
/** Compatibility error for callers that distinguish unknown parameters. */
|
|
36
|
+
export declare class UnknownEffectParameter extends UnknownEffectParameter_base {
|
|
37
|
+
}
|
|
38
|
+
declare const InvalidEffectParameter_base: Schema.Class<InvalidEffectParameter, Schema.TaggedStruct<"InvalidEffectParameter", {
|
|
39
|
+
readonly effect: Schema.String;
|
|
40
|
+
readonly parameter: Schema.String;
|
|
41
|
+
readonly message: Schema.String;
|
|
42
|
+
}>, import("effect/Cause").YieldableError>;
|
|
43
|
+
/** Compatibility error for callers that distinguish malformed parameter values. */
|
|
44
|
+
export declare class InvalidEffectParameter extends InvalidEffectParameter_base {
|
|
45
|
+
}
|
|
46
|
+
/** Build behaviours for one catalogue effect, returning typed decoding failures. */
|
|
47
|
+
export declare const build: (name: string, target: Container, params?: EffectParams, duration?: number, ctx?: EffectContext) => Effect.Effect<ReadonlyArray<Behaviour>, EffectDecodeError>;
|
|
48
|
+
/** Catalogue facade for callers that prefer an object. */
|
|
49
|
+
export declare const EffectCatalogue: {
|
|
50
|
+
build: typeof build;
|
|
51
|
+
};
|
|
52
|
+
export {};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { Context, Layer } from "effect";
|
|
2
|
+
import type { PixiAppShape } from "./types.js";
|
|
3
|
+
/** Design resolution used to lay out the stage. */
|
|
4
|
+
export interface DesignSize {
|
|
5
|
+
readonly width: number;
|
|
6
|
+
readonly height: number;
|
|
7
|
+
}
|
|
8
|
+
declare const PixiApp_base: Context.ServiceClass<PixiApp, "Lute.Web.PixiApp", PixiAppShape>;
|
|
9
|
+
/** Scoped PixiJS application and stage graph. */
|
|
10
|
+
export declare class PixiApp extends PixiApp_base {
|
|
11
|
+
/** Initialize an application and attach its canvas to `element`. */
|
|
12
|
+
static layer: (element: HTMLElement, design: DesignSize, background?: number) => Layer.Layer<PixiApp, unknown>;
|
|
13
|
+
}
|
|
14
|
+
export {};
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { Container } from "pixi.js";
|
|
2
|
+
import type { Behaviour } from "./types.js";
|
|
3
|
+
import type { Easing } from "./easing.js";
|
|
4
|
+
/** Properties supported by a tween. */
|
|
5
|
+
export interface TweenProps {
|
|
6
|
+
readonly x?: number;
|
|
7
|
+
readonly y?: number;
|
|
8
|
+
readonly alpha?: number;
|
|
9
|
+
readonly scaleX?: number;
|
|
10
|
+
readonly scaleY?: number;
|
|
11
|
+
readonly rotation?: number;
|
|
12
|
+
readonly tint?: number;
|
|
13
|
+
}
|
|
14
|
+
/** Wipe direction. */
|
|
15
|
+
export type WipeDirection = "left" | "right" | "up" | "down";
|
|
16
|
+
/** Create a pooled property tween. */
|
|
17
|
+
export declare const tween: (target: Container, props: TweenProps, to: TweenProps, duration: number, easing?: Easing) => Behaviour;
|
|
18
|
+
/** Create a pooled alpha tween. */
|
|
19
|
+
export declare const fade: (target: Container, to: number, duration: number) => Behaviour;
|
|
20
|
+
/** Crossfade two containers over a duration. */
|
|
21
|
+
export declare const crossfade: (from: Container, to: Container, duration: number) => Behaviour;
|
|
22
|
+
/** Shake a container around its original position. */
|
|
23
|
+
export declare const shake: (target: Container, strength: number, duration: number, frequency?: number) => Behaviour;
|
|
24
|
+
/** Lift a container in a single hop and return it to its baseline. */
|
|
25
|
+
export declare const hop: (target: Container, height: number, duration: number) => Behaviour;
|
|
26
|
+
/** Slide a container from one x coordinate to another. */
|
|
27
|
+
export declare const slide: (target: Container, fromX: number, toX: number, duration: number) => Behaviour;
|
|
28
|
+
/** Reveal or conceal a target with a reusable Graphics mask. */
|
|
29
|
+
export declare const wipe: (target: Container, direction: WipeDirection, duration: number, reveal?: boolean) => Behaviour;
|
|
30
|
+
/** Flash an overlay container and then hide it. */
|
|
31
|
+
export declare const flash: (overlay: Container, colour: number, duration: number) => Behaviour;
|
|
32
|
+
/** Pulse a target forever until cancelled. */
|
|
33
|
+
export declare const pulse: (target: Container, scale: number, period: number) => Behaviour;
|
|
34
|
+
/** Create a pooled timer behaviour. */
|
|
35
|
+
export declare const delay: (seconds: number) => Behaviour;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/** Easing functions used by the pooled scene behaviours. */
|
|
2
|
+
export type Easing = (progress: number) => number;
|
|
3
|
+
/** Linear interpolation progress. */
|
|
4
|
+
export declare const linear: Easing;
|
|
5
|
+
/** Quadratic ease in. */
|
|
6
|
+
export declare const quadIn: Easing;
|
|
7
|
+
/** Quadratic ease out. */
|
|
8
|
+
export declare const quadOut: Easing;
|
|
9
|
+
/** Quadratic ease in and out. */
|
|
10
|
+
export declare const quadInOut: Easing;
|
|
11
|
+
/** Cubic ease in. */
|
|
12
|
+
export declare const cubicIn: Easing;
|
|
13
|
+
/** Cubic ease out. */
|
|
14
|
+
export declare const cubicOut: Easing;
|
|
15
|
+
/** Cubic ease in and out. */
|
|
16
|
+
export declare const cubicInOut: Easing;
|
|
17
|
+
/** Sine ease in and out. */
|
|
18
|
+
export declare const sineInOut: Easing;
|
|
19
|
+
/** Back ease out. */
|
|
20
|
+
export declare const backOut: Easing;
|
|
21
|
+
/** Elastic ease out. */
|
|
22
|
+
export declare const elasticOut: Easing;
|
|
23
|
+
/** Named easing lookup used by bindings and tests. */
|
|
24
|
+
export declare const easings: Readonly<Record<string, Easing>>;
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared engine contracts of the web player (docs/player/web-architecture.md):
|
|
3
|
+
* the Pixi application service, the scene layers, and the entity–behaviour
|
|
4
|
+
* model every module builds on.
|
|
5
|
+
*/
|
|
6
|
+
import type { Context, Deferred, Effect, Stream } from "effect";
|
|
7
|
+
import type { Application, Container } from "pixi.js";
|
|
8
|
+
/** Fixed scene layers, back to front. `camera` holds the actors and is what framing/moves transform. */
|
|
9
|
+
export interface Layers {
|
|
10
|
+
readonly background: Container;
|
|
11
|
+
readonly cg: Container;
|
|
12
|
+
readonly camera: Container;
|
|
13
|
+
readonly actors: Container;
|
|
14
|
+
readonly video: Container;
|
|
15
|
+
readonly dialogue: Container;
|
|
16
|
+
readonly choice: Container;
|
|
17
|
+
readonly overlay: Container;
|
|
18
|
+
readonly transition: Container;
|
|
19
|
+
}
|
|
20
|
+
/** The Pixi application as a scoped service (initialized with WebGL, destroyed on scope close). */
|
|
21
|
+
export interface PixiAppShape {
|
|
22
|
+
readonly app: Application;
|
|
23
|
+
readonly layers: Layers;
|
|
24
|
+
/** Design resolution from `bindings.canvas`; the stage is letterboxed into the element. */
|
|
25
|
+
readonly design: {
|
|
26
|
+
readonly width: number;
|
|
27
|
+
readonly height: number;
|
|
28
|
+
};
|
|
29
|
+
/** Seconds elapsed per tick. */
|
|
30
|
+
readonly frames: Stream.Stream<number>;
|
|
31
|
+
}
|
|
32
|
+
export type PixiAppTag = Context.Service<PixiAppShape, PixiAppShape>;
|
|
33
|
+
/**
|
|
34
|
+
* A unit of per-frame behaviour attached to an entity (tween, fade, shake,
|
|
35
|
+
* typewriter, …). `update` advances by `dt` seconds and reports whether it
|
|
36
|
+
* is finished; `finish` jumps to the end state. `done` is completed by the
|
|
37
|
+
* world when the behaviour ends either way.
|
|
38
|
+
*/
|
|
39
|
+
export interface Behaviour {
|
|
40
|
+
readonly update: (dt: number) => "running" | "done";
|
|
41
|
+
readonly finish: () => void;
|
|
42
|
+
/** Release resources (masks, filters) after the behaviour ended. */
|
|
43
|
+
readonly dispose: () => void;
|
|
44
|
+
}
|
|
45
|
+
/** Owns every running behaviour; stepped once per frame by the ticker. */
|
|
46
|
+
export interface WorldShape {
|
|
47
|
+
/** Run `behaviour` on `target`; completes when it finished (or was finished by `finishAll`). */
|
|
48
|
+
readonly run: (target: Container, behaviour: Behaviour) => Effect.Effect<void>;
|
|
49
|
+
/** Finish every behaviour on `target` (or all) at once. */
|
|
50
|
+
readonly finishAll: (target?: Container) => Effect.Effect<void>;
|
|
51
|
+
/** Cancel behaviours on `target` without finishing them (e.g. superseded tweens). */
|
|
52
|
+
readonly cancel: (target: Container) => Effect.Effect<void>;
|
|
53
|
+
/** Number of running behaviours (tests, debug overlay). */
|
|
54
|
+
readonly size: Effect.Effect<number>;
|
|
55
|
+
}
|
|
56
|
+
/** A running behaviour's completion signal, as stored by the world. */
|
|
57
|
+
export interface Running {
|
|
58
|
+
readonly target: Container;
|
|
59
|
+
readonly behaviour: Behaviour;
|
|
60
|
+
readonly done: Deferred.Deferred<void>;
|
|
61
|
+
}
|
|
62
|
+
/** UI theme derived from `bindings.ui` (colours as 0xRRGGBB numbers). */
|
|
63
|
+
export interface Theme {
|
|
64
|
+
readonly font: string;
|
|
65
|
+
readonly text: number;
|
|
66
|
+
readonly accent: number;
|
|
67
|
+
readonly panel: number;
|
|
68
|
+
readonly panelAlpha: number;
|
|
69
|
+
readonly readText: number;
|
|
70
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { Context, Layer } from "effect";
|
|
2
|
+
import type { WorldShape } from "./types.js";
|
|
3
|
+
import { PixiApp } from "./app.js";
|
|
4
|
+
declare const World_base: Context.ServiceClass<World, "Lute.Web.World", WorldShape>;
|
|
5
|
+
/** The scene behaviour scheduler. */
|
|
6
|
+
export declare class World extends World_base {
|
|
7
|
+
/** Build a world and run it from the Pixi application ticker. */
|
|
8
|
+
static readonly layer: Layer.Layer<World, never, PixiApp>;
|
|
9
|
+
}
|
|
10
|
+
export {};
|
package/dist/index.d.ts
ADDED