yuuna-engine 0.2.0 → 0.2.1

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 CHANGED
@@ -70,8 +70,9 @@ runEngine<GameState>({
70
70
  ## Concepts
71
71
 
72
72
  - **Renderables** — declarative shapes drawn each frame: `RECTANGLE`,
73
- `CIRCLE`, `TEXT`, and `SPRITE`. Give one an `id` plus `isClickable` /
74
- `isHoverable` / `trackMouseMovement` to make it interactive.
73
+ `CIRCLE`, `TEXT`, `SPRITE`, and `LINE`. Give one an `id` plus
74
+ `isClickable` / `isHoverable` / `trackMouseMovement` to make it
75
+ interactive.
75
76
  - **Events** — your `nextState` function receives one `GameEvent` per call:
76
77
  `TIME` (frame tick with `delta`), `CLICK`, `HOVER_IN`, `HOVER_OUT`, or
77
78
  `MOUSE_MOVE`.
@@ -80,11 +81,42 @@ runEngine<GameState>({
80
81
  `isPressed` / `isJustPressed` / `isJustReleased`.
81
82
  - **Sprites** — pass a `resources` map of `{ src, size, slices }` to
82
83
  `runEngine` to load spritesheets, then reference them by id with a
83
- `SPRITE` renderable's `resourceId` and `frame`.
84
+ `SPRITE` renderable's `resourceId` and `frame`. Set `flipX: true` to
85
+ mirror a sprite horizontally — useful when the art is drawn facing one
86
+ direction but needs to move the other way.
84
87
  - **Canvas** — pass `canvas: { width, height, backgroundColor }` to
85
88
  `runEngine` to size and color the canvas from code. All three are
86
89
  optional; anything you don't set falls back to the canvas element's
87
90
  existing HTML/CSS.
91
+ - **Mechanics** — `nextState` can also be an array of small
92
+ `NextStateFunction`s instead of one big function. Each one is run in
93
+ order for every event, and can return:
94
+ - a new state, to update to
95
+ - `undefined` (or no `return` at all) — no change, but the rest of the
96
+ list still runs, so a guard can just be `if (...) return;`
97
+ - `STOP` (imported from `yuuna-engine`) — no change, and the rest of
98
+ the list is skipped for this event, so a shared rule (like "nothing
99
+ happens once the game is over") only needs to be written once
100
+
101
+ ```ts
102
+ import { runEngine, STOP, type NextStateFunction } from "yuuna-engine";
103
+
104
+ const freezeOnGameOver: NextStateFunction<GameState> = ({ state }) => {
105
+ if (state.lives <= 0) return STOP;
106
+ };
107
+
108
+ const moveEnemies: NextStateFunction<GameState> = ({ state, event }) => {
109
+ if (event.tag === "TIME") {
110
+ return { ...state, enemies: move(state.enemies, event.delta) };
111
+ }
112
+ };
113
+
114
+ runEngine<GameState>({
115
+ initialState,
116
+ render,
117
+ nextState: [freezeOnGameOver, moveEnemies /* ... */],
118
+ });
119
+ ```
88
120
 
89
121
  ## Development
90
122
 
package/lib/index.d.ts CHANGED
@@ -1,3 +1,4 @@
1
1
  import { runEngine } from "./engine/runEngine";
2
2
  import { STOP } from "./engine/types";
3
3
  export { runEngine, STOP };
4
+ export type { NextStateFunction, NextStateProps, Renderable, GameEvent } from "./engine/types";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "yuuna-engine",
3
- "version": "0.2.0",
3
+ "version": "0.2.1",
4
4
  "description": "A lightweight, state-machine-based TypeScript game engine for quick prototypes. Runs directly in the browser.",
5
5
  "type": "module",
6
6
  "main": "./lib/index.cjs",