narraleaf-react 0.0.1-beta.1 → 0.0.1-beta.10

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 (44) hide show
  1. package/README.md +123 -0
  2. package/dist/game/nlcore/action/action.d.ts +1 -1
  3. package/dist/game/nlcore/action/actionTypes.d.ts +4 -2
  4. package/dist/game/nlcore/action/actions.d.ts +3 -1
  5. package/dist/game/nlcore/common/player.d.ts +4 -1
  6. package/dist/game/nlcore/common/transition.d.ts +2 -1
  7. package/dist/game/nlcore/elements/image.d.ts +8 -9
  8. package/dist/game/nlcore/elements/scene.d.ts +1 -1
  9. package/dist/game/nlcore/elements/sound.d.ts +3 -1
  10. package/dist/game/nlcore/elements/text.d.ts +17 -5
  11. package/dist/game/nlcore/elements/transform/position.d.ts +22 -8
  12. package/dist/game/nlcore/elements/transform/transform.d.ts +11 -6
  13. package/dist/game/nlcore/elements/transition/base.d.ts +2 -1
  14. package/dist/game/nlcore/elements/transition/type.d.ts +2 -1
  15. package/dist/game/nlcore/game.d.ts +18 -0
  16. package/dist/game/nlcore/gameTypes.d.ts +124 -0
  17. package/dist/game/nlcore/store/storable.d.ts +3 -3
  18. package/dist/game/nlcore/types.d.ts +4 -5
  19. package/dist/game/player/elements/Player.d.ts +2 -10
  20. package/dist/game/player/elements/elements.d.ts +6 -0
  21. package/dist/game/player/elements/menu/Menu.d.ts +2 -7
  22. package/dist/game/player/elements/menu/Sentence.d.ts +2 -1
  23. package/dist/game/player/elements/menu/type.d.ts +9 -0
  24. package/dist/game/player/elements/player/KeyEventAnnouncer.d.ts +5 -0
  25. package/dist/game/player/elements/say/Say.d.ts +2 -9
  26. package/dist/game/player/elements/say/TypingEffect.d.ts +1 -0
  27. package/dist/game/player/elements/say/type.d.ts +15 -0
  28. package/dist/game/player/elements/scene/Background.d.ts +1 -1
  29. package/dist/game/player/elements/type.d.ts +37 -0
  30. package/dist/game/player/gameState.d.ts +7 -16
  31. package/dist/game/player/gameState.type.d.ts +15 -0
  32. package/dist/game/player/lib/{main.d.ts → AspectRatio.d.ts} +1 -1
  33. package/dist/game/player/lib/Motion.d.ts +4 -0
  34. package/dist/game/player/lib/isolated.d.ts +1 -2
  35. package/dist/game/player/libElements.d.ts +4 -0
  36. package/dist/game/player/provider/game-state.d.ts +4 -0
  37. package/dist/game/player/provider/providers.d.ts +3 -1
  38. package/dist/game/player/provider/ratio.d.ts +41 -17
  39. package/dist/game/player/type.d.ts +1 -0
  40. package/dist/{index.js → main.js} +8540 -3494
  41. package/dist/main.js.map +1 -0
  42. package/dist/util/data.d.ts +36 -2
  43. package/package.json +8 -6
  44. package/dist/index.js.map +0 -1
package/README.md ADDED
@@ -0,0 +1,123 @@
1
+ ![](./docs/nlr-logo-banner.png)
2
+
3
+ # NarraLeaf-React
4
+
5
+ A React visual novel player framework
6
+
7
+ ## What is NarraLeaf-React?
8
+
9
+ NarraLeaf-React is a lightweight front-end visual novel player.
10
+ NL focuses on visual novel playing, so the user interface can be customized very easily.
11
+
12
+ It doesn't use any rendering libraries and can be used on any web platform (e.g. Electron)
13
+
14
+ ## Why NarraLeaf-React?
15
+
16
+ - **Lightweight**: NarraLeaf-React is a front-end framework, and it doesn't use any rendering libraries.
17
+ - **Customizable**: You can customize the UI as you like, even replace the whole components.
18
+ - **Easy to use**: It is easy to use and has a simple API that is built for developers. Based on OOP principles.
19
+ - **Built for React**: It is built for React!
20
+ - **Cross-platform**: It can be used on any web platform (e.g. Electron)
21
+
22
+ ## Get Started
23
+
24
+ ### Install
25
+
26
+ ```bash
27
+ npm install narraleaf-react
28
+ ```
29
+
30
+ ### Documentation
31
+
32
+ - [Quick Start](./docs/quick-start.md)
33
+ - [Customization](./docs/customization.md)
34
+
35
+ Read more in [🛠React.NarraLeaf.com](https://react.narraleaf.com)
36
+
37
+ ### Example
38
+
39
+ ```tsx
40
+ "use client";
41
+
42
+ import {Character, Scene, Story, Image, Player, GameProviders} from "narraleaf-react";
43
+
44
+ export default function App() {
45
+
46
+ const character1 = new Character("character1");
47
+ const image1 = new Image({
48
+ src: "https://placehold.it/200x200",
49
+ })
50
+
51
+ const story = new Story("My First NarraLeaf Story").entry(
52
+ new Scene("scene1").action([
53
+ // Show image1 for 1 second
54
+ image1.show({
55
+ duration: 1000,
56
+ }).toActions(),
57
+
58
+ // Say something
59
+ character1
60
+ .say("Hello, world!")
61
+ .say("This is my first NarraLeaf story.")
62
+ .say("Start editing this file and enjoy the journey!")
63
+ .toActions(),
64
+ ])
65
+ );
66
+
67
+ function handleOnReady({game}) {
68
+ game.getLiveGame().newGame();
69
+ }
70
+
71
+ return (
72
+ <GameProviders>
73
+ <Player
74
+ story={story}
75
+ onReady={handleOnReady}
76
+ width="100vw"
77
+ height="100vh"
78
+ />
79
+ </GameProviders>
80
+ );
81
+ }
82
+ ```
83
+
84
+ Read more in [Quick Start](./docs/quick-start.md)
85
+
86
+ ### Performance
87
+
88
+ Please enable image cache for a better performance.
89
+ Narraleaf-React tries to cache the images before showing them, but it is recommended to enable cache on your server.
90
+
91
+ for NextJS, add this to your `next.config.js`:
92
+
93
+ ```js
94
+ /** @type {import('next').NextConfig} */
95
+ const nextConfig = {
96
+ async headers() {
97
+ return [
98
+ {
99
+ source: '/YOUR_IMAGE_ENDPOINT/(.*)', // ex: /static/images/(.*)
100
+ headers: [
101
+ {
102
+ key: 'Cache-Control',
103
+ value: 'public, max-age=31536000, immutable',
104
+ },
105
+ ],
106
+ }
107
+ ]
108
+ }
109
+ };
110
+
111
+ export default nextConfig;
112
+ ```
113
+
114
+ ## License
115
+
116
+ > NarraLeaf-React is licensed under the MIT License.
117
+
118
+ ## Contributing
119
+
120
+ We welcome all contributions.
121
+ If you have any ideas, just open an issue or a pull request.
122
+
123
+
@@ -1,6 +1,6 @@
1
1
  import { LogicAction } from "./logicAction";
2
2
  import { ContentNode } from "../action/tree/actionTree";
3
- import type { CalledActionResult } from "@core/gameTypes";
3
+ import type { CalledActionResult } from "../gameTypes";
4
4
  import { Awaitable } from "../../../util/data";
5
5
  import { GameState } from "../../player/gameState";
6
6
  export declare class Action<ContentNodeType = any, Callee = LogicAction.GameElement> {
@@ -79,15 +79,17 @@ export declare const SoundActionTypes: {
79
79
  readonly fade: "sound:fade";
80
80
  readonly setVolume: "sound:setVolume";
81
81
  readonly setRate: "sound:setRate";
82
+ readonly pause: "sound:pause";
83
+ readonly resume: "sound:resume";
82
84
  };
83
85
  export type SoundActionContentType = {
84
86
  [K in typeof SoundActionTypes[keyof typeof SoundActionTypes]]: K extends "sound:play" ? [void] : K extends "sound:stop" ? [void] : K extends "sound:fade" ? [
85
87
  {
86
- start: number;
88
+ start?: number;
87
89
  end: number;
88
90
  duration: number;
89
91
  }
90
- ] : K extends "sound:setVolume" ? [number] : K extends "sound:setRate" ? [number] : any;
92
+ ] : K extends "sound:setVolume" ? [number] : K extends "sound:setRate" ? [number] : K extends "sound:pause" ? [void] : K extends "sound:resume" ? [void] : any;
91
93
  };
92
94
  export declare const ControlActionTypes: {
93
95
  readonly action: "control:action";
@@ -9,7 +9,7 @@ import type { Story } from "../elements/story";
9
9
  import type { Script } from "../elements/script";
10
10
  import type { Menu } from "../elements/menu";
11
11
  import type { Condition } from "../elements/condition";
12
- import type { CalledActionResult } from "@core/gameTypes";
12
+ import type { CalledActionResult } from "../gameTypes";
13
13
  import { GameState } from "../../player/gameState";
14
14
  import type { Sound } from "../elements/sound";
15
15
  import { Control } from "../elements/control";
@@ -97,6 +97,8 @@ export declare class SoundAction<T extends typeof SoundActionTypes[keyof typeof
97
97
  readonly fade: "sound:fade";
98
98
  readonly setVolume: "sound:setVolume";
99
99
  readonly setRate: "sound:setRate";
100
+ readonly pause: "sound:pause";
101
+ readonly resume: "sound:resume";
100
102
  };
101
103
  static initSound(state: GameState, sound: Sound): void;
102
104
  executeAction(state: GameState): CalledActionResult | Awaitable<CalledActionResult, any>;
@@ -1,4 +1,7 @@
1
1
  import Player from "../../player/elements/Player";
2
2
  import GameProviders from "../../player/provider/providers";
3
3
  import { GameState } from "../../player/gameState";
4
- export { GameProviders, Player, GameState, };
4
+ import { useGame } from "../../../game/player/provider/game-state";
5
+ export * from "../../player/type";
6
+ export * from "../../player/libElements";
7
+ export { GameProviders, Player, useGame, GameState, };
@@ -2,5 +2,6 @@ import { ITransition } from "../elements/transition/type";
2
2
  import { Fade } from "../elements/transition/fade";
3
3
  import { FadeIn } from "../elements/transition/fadeIn";
4
4
  import { Dissolve } from "../elements/transition/dissolve";
5
- export { Fade, FadeIn, Dissolve };
5
+ import { Base } from "../elements/transition/base";
6
+ export { Fade, FadeIn, Dissolve, Base };
6
7
  export type { ITransition };
@@ -1,14 +1,13 @@
1
- import { CommonImage, NextJSStaticImageData, StaticImageData } from "../types";
2
- import { DeepPartial, EventDispatcher } from "../../../util/data";
3
- import { Transform } from "./transform/transform";
1
+ import React from "react";
2
+ import type { TransformDefinitions } from "../elements/transform/type";
4
3
  import { ImageAction } from "../action/actions";
5
4
  import { Actionable } from "../action/actionable";
6
- import type { TransformDefinitions } from "../elements/transform/type";
7
- import React from "react";
8
- import { AnimationScope } from "framer-motion";
5
+ import { Transform } from "./transform/transform";
6
+ import { CommonImage, StaticImageData } from "../types";
9
7
  import { ITransition } from "../elements/transition/type";
8
+ import { DeepPartial, EventDispatcher } from "../../../util/data";
10
9
  export type ImageConfig = {
11
- src: string | NextJSStaticImageData;
10
+ src: string | StaticImageData;
12
11
  display: boolean;
13
12
  disposed?: boolean;
14
13
  } & CommonImage;
@@ -22,7 +21,7 @@ export type ImageEventTypes = {
22
21
  "event:image.applyTransform": [Transform];
23
22
  "event:image.mount": [];
24
23
  "event:image.unmount": [];
25
- "event:image.ready": [AnimationScope];
24
+ "event:image.ready": [React.MutableRefObject<HTMLImageElement | null>];
26
25
  "event:image.elementLoaded": [];
27
26
  "event:image.setTransition": [ITransition | null];
28
27
  };
@@ -69,6 +68,7 @@ export declare class Image extends Actionable<ImageDataRaw> {
69
68
  * @example
70
69
  * ```ts
71
70
  * // shake the image
71
+ *
72
72
  * image.applyTransform(
73
73
  * new Transform([
74
74
  * {
@@ -117,7 +117,6 @@ export declare class Image extends Actionable<ImageDataRaw> {
117
117
  hide(transform: Transform): this;
118
118
  hide(transform: Partial<TransformDefinitions.CommonTransformProps>): this;
119
119
  toTransform(): Transform;
120
- toHTMLElementProps(): React.DetailedHTMLProps<React.ImgHTMLAttributes<HTMLImageElement>, HTMLImageElement>;
121
120
  setScope(scope: React.RefObject<HTMLImageElement>): this;
122
121
  getScope(): React.RefObject<HTMLImageElement> | undefined;
123
122
  copy(): Image;
@@ -81,7 +81,7 @@ export declare class Scene extends Constructable<any, Actions, SceneAction<"scen
81
81
  *
82
82
  * Any operations after the jump operation will not be executed
83
83
  */
84
- jumpTo(arg0: Scene, config?: JumpConfig): this;
84
+ jumpTo(arg0: Scene, config?: Partial<JumpConfig>): this;
85
85
  transitionSceneBackground(scene?: Scene, transition?: ITransition): this;
86
86
  /**
87
87
  * Wait for a period of time, the parameter can be the number of milliseconds, a Promise, or an unresolved {@link Awaitable}
@@ -42,9 +42,11 @@ export declare class Sound extends Actionable<SoundDataRaw> {
42
42
  constructor(config?: DeepPartial<SoundConfig>);
43
43
  play(): this;
44
44
  stop(): this;
45
- fade(start: number, end: number, duration: number): this;
45
+ fade(start: number | undefined, end: number, duration: number): this;
46
46
  setVolume(volume: number): this;
47
47
  setRate(rate: number): this;
48
+ pause(fade?: number): this;
49
+ resume(fade?: number): this;
48
50
  getHowlOptions(): HowlOptions;
49
51
  getSrc(): string;
50
52
  $setToken(token: any): void;
@@ -1,7 +1,10 @@
1
- import { Color } from "../types";
1
+ import { color, Color } from "../types";
2
+ import { DeepPartial } from "../../../util/data";
2
3
  import { Actionable } from "../action/actionable";
4
+ import type { Sound } from "../elements/sound";
3
5
  export type SentenceConfig = {
4
6
  pause?: boolean | number;
7
+ voice: Sound | string | null | undefined;
5
8
  } & Color;
6
9
  export type WordConfig = {} & Color;
7
10
  export type SentenceDataRaw = {
@@ -28,18 +31,27 @@ export declare class Sentence {
28
31
  toString(): string;
29
32
  }
30
33
  export declare class Word {
31
- static defaultConfig: WordConfig;
34
+ static defaultConfig: Partial<WordConfig>;
35
+ static defaultColor: color;
32
36
  text: string;
33
- config: WordConfig;
37
+ config: Partial<WordConfig>;
34
38
  constructor(text: string, config?: Partial<WordConfig>);
35
39
  static isWord(obj: any): obj is Word;
36
40
  }
37
- export type CharacterConfig = {};
41
+ export declare enum CharacterMode {
42
+ "adv" = "adv",
43
+ "nvl" = "nvl"
44
+ }
45
+ export type CharacterConfig = {
46
+ mode: CharacterMode;
47
+ };
38
48
  export type CharacterStateData = {};
39
49
  export declare class Character extends Actionable<CharacterStateData> {
50
+ static Modes: typeof CharacterMode;
51
+ static defaultConfig: CharacterConfig;
40
52
  name: string | null;
41
53
  config: CharacterConfig;
42
- constructor(name: string | null, config?: CharacterConfig);
54
+ constructor(name: string | null, config?: DeepPartial<CharacterConfig>);
43
55
  /**
44
56
  * Say something
45
57
  * @example
@@ -1,13 +1,13 @@
1
1
  import { CSSProps } from "../../elements/transition/type";
2
2
  export declare enum CommonPositionType {
3
- Left = 0,
4
- Center = 1,
5
- Right = 2
3
+ Left = "left",
4
+ Center = "center",
5
+ Right = "right"
6
6
  }
7
7
  export declare const CommonPositions: {
8
- 0: `${number}%`;
9
- 1: `${number}%`;
10
- 2: `${number}%`;
8
+ left: `${number}%`;
9
+ center: `${number}%`;
10
+ right: `${number}%`;
11
11
  };
12
12
  export interface IPosition {
13
13
  toCSS(): D2Position;
@@ -30,6 +30,13 @@ export type D2Position<X = any, Y = any> = {
30
30
  xoffset: UnknownAble<number>;
31
31
  yoffset: UnknownAble<number>;
32
32
  };
33
+ export type RawPosition = CommonPositionType | (Coord2DPosition & {
34
+ xalign?: never;
35
+ yalign?: never;
36
+ }) | (AlignPosition & {
37
+ x: never;
38
+ y: never;
39
+ });
33
40
  export type Unknown = typeof PositionUtils.Unknown;
34
41
  export type UnknownAble<T> = T | Unknown;
35
42
  export declare class PositionUtils {
@@ -41,6 +48,13 @@ export declare class PositionUtils {
41
48
  static toCoord2D(pos: IPosition | D2Position): Coord2D;
42
49
  static mergePosition(a: IPosition, b: IPosition): Coord2D;
43
50
  static serializePosition(pos: IPosition): D2Position;
51
+ static isRawCommonPositionType(arg: any): arg is CommonPositionType;
52
+ static isRawCoord2DPosition(arg: any): arg is Coord2DPosition;
53
+ static isRawAlignPosition(arg: any): arg is AlignPosition;
54
+ static isRawPosition(arg: any): arg is IPosition;
55
+ static isPosition(arg: any): arg is IPosition;
56
+ static rawPositionToCoord2D(arg: any): Coord2D;
57
+ static tryParsePosition(arg: any): IPosition;
44
58
  }
45
59
  export declare class CommonPosition implements IPosition {
46
60
  static Positions: typeof CommonPositionType;
@@ -50,10 +64,10 @@ export declare class CommonPosition implements IPosition {
50
64
  * @example
51
65
  * ```ts
52
66
  * new CommonPosition(CommonPosition.Positions.Center);
53
- * new CommonPosition("Center");
67
+ * new CommonPosition("center");
54
68
  * ```
55
69
  */
56
- constructor(position: CommonPositionType | keyof typeof CommonPositionType);
70
+ constructor(position: CommonPositionType);
57
71
  static isCommonPositionType(arg: any): arg is CommonPosition;
58
72
  toCSS(): D2Position;
59
73
  }
@@ -3,10 +3,11 @@ import type { AnimationPlaybackControls, DOMKeyframesDefinition, DynamicAnimatio
3
3
  import { DeepPartial } from "../../../../util/data";
4
4
  import { GameState } from "../../../player/gameState";
5
5
  import { TransformDefinitions } from "./type";
6
- import { Align, Coord2D, IPosition } from "./position";
6
+ import { Align, Coord2D, IPosition, RawPosition } from "./position";
7
7
  import { CSSProps } from "../../elements/transition/type";
8
8
  import Sequence = TransformDefinitions.Sequence;
9
9
  import SequenceProps = TransformDefinitions.SequenceProps;
10
+ import React from "react";
10
11
  export type Transformers = "position" | "opacity" | "scale" | "rotation" | "display" | "src" | "backgroundColor" | "backgroundOpacity" | "transform";
11
12
  export type TransformHandler<T> = (value: T) => DOMKeyframesDefinition;
12
13
  export type TransformersMap = {
@@ -52,7 +53,7 @@ export declare class Transform<T extends TransformDefinitions.Types = TransformD
52
53
  backgroundImage?: string;
53
54
  backgroundColor?: string;
54
55
  };
55
- static mergePosition(a: IPosition | undefined, b: IPosition | undefined): Coord2D;
56
+ static mergePosition(a: RawPosition | undefined, b: RawPosition | undefined): Coord2D;
56
57
  static mergeState<T>(state: any, props: any): DeepPartial<T>;
57
58
  /**
58
59
  * @example
@@ -62,9 +63,11 @@ export declare class Transform<T extends TransformDefinitions.Types = TransformD
62
63
  * return <div ref={scope} />
63
64
  * ```
64
65
  */
65
- animate<U extends Element = any>({ scope, animate }: {
66
- scope: TransformDefinitions.FramerAnimationScope<U>;
67
- animate: TransformDefinitions.FramerAnimate;
66
+ animate({ scope, overwrites }: {
67
+ scope: React.MutableRefObject<HTMLImageElement | null>;
68
+ overwrites?: Partial<{
69
+ [K in Transformers]?: TransformHandler<any>;
70
+ }>;
68
71
  }, gameState: GameState, state: SequenceProps<T>, after?: (state: DeepPartial<T>) => void): Promise<void>;
69
72
  /**
70
73
  * @example
@@ -88,7 +91,9 @@ export declare class Transform<T extends TransformDefinitions.Types = TransformD
88
91
  * ```
89
92
  */
90
93
  overwrite<T extends keyof TransformersMap = any>(key: T, transformer: TransformHandler<TransformersMap[T]>): this;
91
- propToCSS(state: GameState, prop: DeepPartial<T>): DOMKeyframesDefinition;
94
+ propToCSS(state: GameState, prop: DeepPartial<T>, overwrites?: Partial<{
95
+ [K in Transformers]?: TransformHandler<any>;
96
+ }>): DOMKeyframesDefinition;
92
97
  optionsToFramerMotionOptions(options?: Partial<TransformDefinitions.CommonTransformProps>): DynamicAnimationOptions | void;
93
98
  propToCSSTransform(state: GameState, prop: Record<string, any>): string;
94
99
  setControl(control: AnimationPlaybackControls | null): this;
@@ -1,7 +1,8 @@
1
1
  import { EventDispatcher } from "../../../../util/data";
2
2
  import { ElementProp, EventTypes, ITransition } from "./type";
3
- import { AnimationPlaybackControls, ValueAnimationTransition } from "framer-motion";
3
+ import type { AnimationPlaybackControls, ValueAnimationTransition } from "framer-motion";
4
4
  export declare class Base<T extends ElementProp> implements ITransition<T> {
5
+ controller: AnimationPlaybackControls | null | undefined;
5
6
  events: EventDispatcher<EventTypes<[T[]]>>;
6
7
  start(_onComplete?: () => void): void;
7
8
  toElementProps(): T[];
@@ -1,6 +1,6 @@
1
1
  import type { EventDispatcher } from "../../../../util/data";
2
2
  import React from "react";
3
- import { DOMKeyframesDefinition } from "framer-motion";
3
+ import type { DOMKeyframesDefinition, AnimationPlaybackControls } from "framer-motion";
4
4
  export type ElementProp<T extends Element = Element, U extends React.HTMLAttributes<T> = React.HTMLAttributes<T>> = React.JSX.IntrinsicAttributes & React.ClassAttributes<T> & React.HTMLAttributes<T> & U;
5
5
  export type ImgElementProp = ElementProp<HTMLImageElement, React.ImgHTMLAttributes<HTMLImageElement>>;
6
6
  export type CSSElementProp<T extends React.CSSProperties | DOMKeyframesDefinition> = ElementProp & {
@@ -9,6 +9,7 @@ export type CSSElementProp<T extends React.CSSProperties | DOMKeyframesDefinitio
9
9
  export type CSSProps = React.CSSProperties;
10
10
  export interface ITransition<T extends ElementProp = {}> {
11
11
  events: EventDispatcher<EventTypes<[T[]]>>;
12
+ controller: AnimationPlaybackControls | null | undefined;
12
13
  start(onComplete?: () => void): void;
13
14
  toElementProps(): T[];
14
15
  setSrc(src: string): void;
@@ -4,6 +4,7 @@ import { Storable } from "./store/storable";
4
4
  import { Story } from "./elements/story";
5
5
  import { LogicAction } from "./action/logicAction";
6
6
  import { GameState } from "../player/gameState";
7
+ import { ComponentsTypes } from "../player/elements/type";
7
8
  declare const IdManager_base: {
8
9
  new (): {};
9
10
  _instance: {} | null;
@@ -26,6 +27,9 @@ declare enum GameSettingsNamespace {
26
27
  }
27
28
  export declare class Game {
28
29
  static defaultSettings: GameSettings;
30
+ static ComponentTypes: {
31
+ [K in keyof ComponentsTypes]: K;
32
+ };
29
33
  static DefaultConfig: GameConfig;
30
34
  static GameSettingsNamespace: typeof GameSettingsNamespace;
31
35
  readonly config: Readonly<GameConfig>;
@@ -36,6 +40,7 @@ export declare class Game {
36
40
  */
37
41
  constructor(config: DeepPartial<GameConfig>);
38
42
  static getIdManager(): IdManager;
43
+ useComponent<T extends keyof ComponentsTypes>(key: T, components: ComponentsTypes[T]): this;
39
44
  getLiveGame(): LiveGame;
40
45
  private createLiveGame;
41
46
  }
@@ -64,15 +69,28 @@ export declare class LiveGame {
64
69
  * Start a new game
65
70
  */
66
71
  newGame(): this;
72
+ /**
73
+ * Load a saved game
74
+ *
75
+ * Note: Different versions of the game won't be able to load each other's saved games
76
+ */
67
77
  deserialize(savedGame: SavedGame, { gameState }: {
68
78
  gameState: GameState;
69
79
  }): void;
80
+ /**
81
+ * Serialize the current game state
82
+ *
83
+ * You can use this to save the game state to a file or a database
84
+ *
85
+ * Note: Different versions of the game won't be able to load each other's saved games
86
+ */
70
87
  serialize({ gameState }: {
71
88
  gameState: GameState;
72
89
  }): SavedGame;
73
90
  getCurrentAction(): LogicAction.Actions | null;
74
91
  setCurrentAction(action: LogicAction.Actions | null): this;
75
92
  next(state: GameState): CalledActionResult | Awaitable<CalledActionResult, CalledActionResult> | null;
93
+ abortAwaiting(): void;
76
94
  executeAction(state: GameState, action: LogicAction.Actions): LogicAction.Actions | Awaitable<CalledActionResult, CalledActionResult> | null;
77
95
  }
78
96
  declare const _default: {
@@ -0,0 +1,124 @@
1
+ import { ContentNode, RawData } from "./action/tree/actionTree";
2
+ import { LogicAction } from "./action/logicAction";
3
+ import { ElementStateRaw } from "./elements/story";
4
+ import { PlayerStateData } from "../player/gameState";
5
+ import { StorableData } from "./store/type";
6
+ import { MenuComponent, SayComponent } from "../player/elements/type";
7
+ export interface SavedGame {
8
+ name: string;
9
+ version: string;
10
+ meta: {
11
+ created: number;
12
+ updated: number;
13
+ };
14
+ game: {
15
+ store: {
16
+ [key: string]: StorableData;
17
+ };
18
+ elementState: RawData<ElementStateRaw>[];
19
+ nodeChildIdMap: Record<string, string>;
20
+ stage: PlayerStateData;
21
+ currentScene: number;
22
+ currentAction: string | null;
23
+ };
24
+ }
25
+ export type GameConfig = {
26
+ version: string;
27
+ player: {
28
+ contentContainerId: string;
29
+ /**
30
+ * The aspect ratio of the game
31
+ * Ex: 16/9, 4/3, 1/1
32
+ */
33
+ aspectRatio: number;
34
+ /**
35
+ * The minimum width and height of the player in pixels
36
+ */
37
+ minWidth: number;
38
+ /**
39
+ * The minimum width and height of the player in pixels
40
+ */
41
+ minHeight: number;
42
+ width: number | string;
43
+ height: number | string;
44
+ /**
45
+ * When player presses one of these keys, the game will skip the current action
46
+ *
47
+ * See [Key_Values](https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/key/Key_Values)
48
+ */
49
+ skipKey: string[];
50
+ /**
51
+ * The interval in milliseconds between each skip action.
52
+ * ex: 100ms means the player can skip 10 actions per second.
53
+ * higher value means faster skipping.
54
+ */
55
+ skipInterval: number;
56
+ };
57
+ elements: {
58
+ say: {
59
+ /**
60
+ * When the player presses one of these keys, the game will show the next sentence
61
+ *
62
+ * See [Key_Values](https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/key/Key_Values)
63
+ */
64
+ nextKey: string[];
65
+ /**
66
+ * The speed of the text effect in milliseconds.
67
+ * higher value means slower text effect.
68
+ * default: 50
69
+ */
70
+ textInterval: number;
71
+ use: SayComponent;
72
+ };
73
+ img: {
74
+ /**
75
+ * If true, the game will show a warning when loading takes longer than `elements.img.slowLoadThreshold`
76
+ */
77
+ slowLoadWarning: boolean;
78
+ slowLoadThreshold: number;
79
+ };
80
+ menu: {
81
+ use: MenuComponent;
82
+ };
83
+ };
84
+ elementStyles: {
85
+ say: {
86
+ /**
87
+ * Custom class for the say container
88
+ * Ex: "rounded-md shadow-md" for rounded and shadowed container
89
+ */
90
+ container: string;
91
+ nameText: string;
92
+ textContainer: string;
93
+ textSpan: string;
94
+ };
95
+ menu: {
96
+ container: string;
97
+ choiceButton: string;
98
+ choiceButtonText: string;
99
+ };
100
+ };
101
+ app: {
102
+ debug: boolean;
103
+ /**
104
+ * Log level for the logger
105
+ */
106
+ logger: {
107
+ log: boolean;
108
+ info: boolean;
109
+ warn: boolean;
110
+ error: boolean;
111
+ debug: boolean;
112
+ trace: boolean;
113
+ };
114
+ };
115
+ };
116
+ export type GameSettings = {
117
+ volume: number;
118
+ };
119
+ export type CalledActionResult<T extends keyof LogicAction.ActionContents = any> = {
120
+ [K in keyof LogicAction.ActionContents]: {
121
+ type: T extends undefined ? K : T;
122
+ node: ContentNode<LogicAction.ActionContents[T extends undefined ? K : T]> | null;
123
+ };
124
+ }[keyof LogicAction.ActionContents];
@@ -6,7 +6,7 @@ export declare class Namespace<T extends NameSpaceContent<keyof T>> {
6
6
  constructor(name: string, initContent: T, key?: string);
7
7
  static isSerializable(value: any): boolean;
8
8
  set<Key extends keyof T>(key: Key, value: T[Key]): this;
9
- get<Key extends keyof T>(key: Key): T[Key];
9
+ get<Key extends keyof T = any>(key: Key): T[Key];
10
10
  toData(): {
11
11
  [key: string]: WrappedStorableData;
12
12
  };
@@ -27,8 +27,8 @@ export declare class Storable {
27
27
  };
28
28
  constructor();
29
29
  addNamespace<T extends NameSpaceContent<keyof T>>(namespace: Namespace<T>): this;
30
- getNamespace<T extends NameSpaceContent<keyof T>>(key: string): Namespace<T>;
31
- setNamespace<T extends NameSpaceContent<keyof T>>(key: string, namespace: Namespace<T>): this;
30
+ getNamespace<T extends NameSpaceContent<keyof T> = any>(key: string): Namespace<T>;
31
+ setNamespace<T extends NameSpaceContent<keyof T> = any>(key: string, namespace: Namespace<T>): this;
32
32
  getNamespaces(): {
33
33
  [key: string]: Namespace<any>;
34
34
  };
@@ -1,4 +1,4 @@
1
- import { IPosition } from "./elements/transform/position";
1
+ import { IPosition, RawPosition } from "./elements/transform/position";
2
2
  export type color = string | {
3
3
  r: number;
4
4
  g: number;
@@ -35,12 +35,11 @@ export type Background = {
35
35
  };
36
36
  export type CommonImagePosition = "left" | "center" | "right";
37
37
  export type CommonImage = {
38
- height?: number;
39
- width?: number;
40
38
  scale?: number;
41
39
  rotation?: number;
42
- position?: IPosition;
43
- opacity: number;
40
+ position?: RawPosition | IPosition;
41
+ opacity?: number;
42
+ alt?: string;
44
43
  };
45
44
  export declare const ImagePosition: {
46
45
  [K in CommonImagePosition]: K;