### Project Setup and Run Commands Source: https://github.com/marco-lepore/yage/blob/main/packages/create-yage/templates/recommended/AGENTS.md Standard npm commands for installing dependencies, starting the development server, building for production, and previewing the build. ```bash npm install npm run dev npm run build npm run preview ``` -------------------------------- ### Initialize and run the YAGE project Source: https://github.com/marco-lepore/yage/blob/main/packages/create-yage/templates/minimal/README.md Install dependencies and start the development server with hot reloading. ```bash npm install npm run dev ``` -------------------------------- ### Topological Sort Example Source: https://github.com/marco-lepore/yage/blob/main/docs/ARCHITECTURE.md Demonstrates the input list of plugins and their dependencies, followed by the resulting topologically sorted order for installation. ```plaintext Input: [renderer, input, physics, particles, ui, ui-react, debug] Dependencies: renderer: [] input: [] physics: [] particles: [renderer] ui: [renderer] ui-react: [renderer, ui] debug: [renderer] Sorted: [renderer, input, physics, particles, ui, ui-react, debug] (order among independent plugins is stable based on registration order) ``` -------------------------------- ### Start Development Server and Run E2E Tests Source: https://github.com/marco-lepore/yage/blob/main/docs/AGENT_GUIDE.md Launch the development server to serve examples or run end-to-end tests. E2E tests require a prior build. ```bash npm run dev npx playwright test npx playwright test e2e/specs/physics-bounce.spec.ts npx playwright test --headed ``` -------------------------------- ### Engine Setup with Plugins Source: https://github.com/marco-lepore/yage/blob/main/docs/AGENT_GUIDE.md Initializes the Yage engine, registers plugins, starts the engine, and pushes a scene. ```typescript import { Engine } from "@yagejs/core"; import { RendererPlugin } from "@yagejs/renderer"; import { PhysicsPlugin } from "@yagejs/physics"; import { InputPlugin } from "@yagejs/input"; import { DebugPlugin } from "@yagejs/debug"; const engine = new Engine({ debug: true }); engine.use(new RendererPlugin({ width: 800, height: 600 })); engine.use(new PhysicsPlugin({ gravity: { x: 0, y: 980 } })); engine.use(new InputPlugin({ actions: { jump: ["Space"] } })); engine.use(new DebugPlugin()); await engine.start(); engine.scenes.push(new GameScene()); ``` -------------------------------- ### Entity Setup with `setup()` Source: https://github.com/marco-lepore/yage/blob/main/docs/llms/core-concepts.md Use `setup()` for entity initialization after it's added to the scene. This ensures services and `onAdd` hooks are available. ```typescript class Player extends Entity { setup({ x, y }: { x: number; y: number }) { this.add(new Transform({ position: new Vec2(x, y) })); this.add(new SpriteComponent({ texture: "player.png" })); } } // scene.spawn(Player, { x: 100, y: 200 }); ``` -------------------------------- ### Initialize Yage Engine and Scene Source: https://github.com/marco-lepore/yage/blob/main/docs/AGENT_GUIDE.md Set up a new Yage example by initializing the engine, using plugins, defining a custom scene, and starting the engine. ```typescript import { Engine, Scene, Transform, Vec2 } from "@yagejs/core"; import { RendererPlugin } from "@yagejs/renderer"; // ... other imports const engine = new Engine({ debug: true }); engine.use(new RendererPlugin({ width: 800, height: 600 })); // ... other plugins class MyScene extends Scene { readonly name = "my-scene"; onEnter() { // Spawn entities } } await engine.start(); engine.scenes.push(new MyScene()); ``` -------------------------------- ### Minimal YAGE Engine Setup Source: https://github.com/marco-lepore/yage/blob/main/docs/llms/quick-start.md Initialize a YAGE engine with the RendererPlugin for basic rendering. This example sets up a simple canvas with a background color. ```typescript import { Engine } from "@yagejs/core"; import { RendererPlugin } from "@yagejs/renderer"; const engine = new Engine(); engine.use(new RendererPlugin({ width: 800, height: 600, backgroundColor: 0x1a1a2e })); await engine.start(); ``` -------------------------------- ### Install UI Packages Source: https://github.com/marco-lepore/yage/blob/main/docs/src/content/docs/guides/ui-react.mdx Install the necessary UI packages and React using npm. ```bash npm install @yagejs/ui @yagejs/ui-react react ``` -------------------------------- ### Build and Develop Yage Project Source: https://github.com/marco-lepore/yage/blob/main/README.md Commands to install dependencies, build the project, and run the development server for examples. ```bash npm install npx turbo run build npx turbo run dev --filter=examples ``` -------------------------------- ### Initialize and Start YAGE Engine Source: https://github.com/marco-lepore/yage/blob/main/docs/llms/core-concepts.md Demonstrates how to instantiate the YAGE engine, use plugins (like the renderer), start the engine, and push the initial scene. Ensure plugins are used before calling start(). ```typescript import { Engine } from "@yagejs/core"; import { RendererPlugin } from "@yagejs/renderer"; const engine = new Engine({ debug: true }); engine.use(new RendererPlugin({ width: 800, height: 600 })); await engine.start(); await engine.scenes.push(new MyScene()); // later: engine.destroy(); ``` -------------------------------- ### Tilemap Plugin Setup Source: https://github.com/marco-lepore/yage/blob/main/docs/src/content/docs/guides/tilemaps.mdx Installs the TilemapPlugin into the engine. This plugin requires @yagejs/renderer. ```typescript import { TilemapPlugin } from "@yagejs/tilemap"; engine.use(new TilemapPlugin()); ``` -------------------------------- ### Enemy Entity with Scene-Aware Setup Source: https://github.com/marco-lepore/yage/blob/main/docs/src/content/docs/patterns/entity-subclasses.mdx Demonstrates using the setup() method for initialization after the entity is registered with the scene. This allows safe access to engine services and querying of other scene entities. ```typescript class Enemy extends Entity { setup(params: EnemyParams) { // Safe — the entity is part of the scene here const physics = this.scene.engine.resolve(PhysicsWorldKey); this.add(new Transform(params.position)); this.add(new RigidBodyComponent({ type: "dynamic" })); this.add(new ColliderComponent({ shape: { type: "circle", radius: 16 } })); } } ``` -------------------------------- ### Setup Physics Plugin Source: https://github.com/marco-lepore/yage/blob/main/docs/llms/packages/physics.md Initialize the PhysicsPlugin with custom gravity and pixelsPerMeter settings. This should be done during engine setup. ```typescript import { PhysicsPlugin } from "@yagejs/physics"; engine.use(new PhysicsPlugin({ gravity: { x: 0, y: 980 }, // px/s², default (0, 980) pixelsPerMeter: 50, // default 50 })); ``` -------------------------------- ### Install Dialogue Addon and Engine Peers Source: https://github.com/marco-lepore/yage/blob/main/packages/addons/dialogue/docs/llms/dialogue.md Install the dialogue addon and its required engine peers. Ensure you have a single install of core engine packages. ```bash npm install @yagejs-addons/dialogue # engine peers (single install, reused — not bundled): npm install @yagejs/core @yagejs/input @yagejs/renderer ``` -------------------------------- ### Test Example Modifications Source: https://github.com/marco-lepore/yage/blob/main/docs/AGENT_GUIDE.md After modifying an example, build the project and run end-to-end tests for that specific example. ```bash npx turbo build && npx playwright test e2e/specs/.spec.ts ``` -------------------------------- ### Subclass Entity with setup() Source: https://github.com/marco-lepore/yage/blob/main/docs/llms/patterns.md Use `setup()` to add components and initialize entities after they are added to the scene. The constructor does not have scene access. ```typescript class Enemy extends Entity { setup({ type, pos }: { type: string; pos: Vec2 }) { this.add(new Transform({ position: pos })); this.add(new SpriteComponent({ texture: `${type}.png` })); this.add(new EnemyAI(type)); } } scene.spawn(Enemy, { type: "goblin", pos: new Vec2(100, 200) }); ``` -------------------------------- ### Run Dialogue Addon Example Source: https://github.com/marco-lepore/yage/blob/main/packages/addons/dialogue/examples/README.md Instructions to run the dialogue addon example using npm workspaces and a Vite dev server. Ensure you are in the repository root. ```bash # from the repo root npm run dev --workspace=@yagejs/examples # then open http://localhost:5199/dialogue-addon.html ``` -------------------------------- ### Install @yagejs/audio Source: https://github.com/marco-lepore/yage/blob/main/packages/audio/README.md Install the @yagejs/audio package using npm. This package bundles @pixi/sound, so no separate installation is required for it. ```bash npm install @yagejs/audio ``` -------------------------------- ### Initialize and Start Yage Engine Source: https://github.com/marco-lepore/yage/blob/main/docs/src/content/docs/index.mdx Sets up the engine with rendering, physics, and UI plugins, then starts the engine and adds a custom scene. ```typescript import { Engine, Scene, Transform, Vec2 } from "@yagejs/core"; import { RendererPlugin, CameraEntity } from "@yagejs/renderer"; import { PhysicsPlugin } from "@yagejs/physics"; import { UIPlugin } from "@yagejs/ui"; import { Ball } from "./Ball"; import { Paddle } from "./Paddle"; import { Wall, Goal, Scoreboard } from "./GameArea"; class PongScene extends Scene { readonly name = "pong"; onEnter() { this.spawn(CameraEntity, { position: new Vec2(300, 200) }); this.spawn(Scoreboard); const ball = this.spawn(Ball, { w: 600, h: 400 }); this.spawn(Paddle, { x: 30, y: 200, ball, side: "left" }); this.spawn(Paddle, { x: 570, y: 200, ball, side: "right" }); this.spawn(Wall, { x: 300, y: -10, w: 600, h: 20 }); // top this.spawn(Wall, { x: 300, y: 410, w: 600, h: 20 }); // bottom this.spawn(Goal, { x: -20, y: 200, w: 20, h: 400, side: "left" }); this.spawn(Goal, { x: 620, y: 200, w: 20, h: 400, side: "right" }); } } const engine = new Engine(); engine.use(new RendererPlugin({ width: 600, height: 400, backgroundColor: 0x0a0a0a })); engine.use(new PhysicsPlugin({ gravity: { x: 0, y: 0 } })); engine.use(new UIPlugin()); await engine.start(); engine.scenes.push(new PongScene()); ``` -------------------------------- ### Plugin Lifecycle Flow Source: https://github.com/marco-lepore/yage/blob/main/docs/ARCHITECTURE.md Illustrates the sequence of events during engine startup and destruction, including plugin installation, system registration, game loop start, and cleanup. ```plaintext engine.use(plugin) → stored (not installed) engine.start() → install() → registerSystems() → loop starts → onStart() engine.destroy() → loop stops → onDestroy() (reverse order) → context cleared ``` -------------------------------- ### Install Dialogue Addon Source: https://github.com/marco-lepore/yage/blob/main/packages/addons/dialogue/README.md Install the dialogue addon using npm. This command installs the core dialogue package. ```bash npm install @yagejs-addons/dialogue ``` -------------------------------- ### Install and Build YAGE Packages Source: https://github.com/marco-lepore/yage/blob/main/docs/AGENT_GUIDE.md Install project dependencies and build all packages. This is a prerequisite for running tests or the development server. ```bash npm install npx turbo build ``` -------------------------------- ### Setup Particles Plugin Source: https://github.com/marco-lepore/yage/blob/main/docs/llms/packages/particles.md Instructions on how to set up the ParticlesPlugin within the Yage engine. ```APIDOC ## Setup Particles Plugin ### Description Integrate the ParticlesPlugin into your Yage engine to enable particle effects. ### Method `engine.use()` ### Endpoint N/A (Plugin integration) ### Request Example ```ts import { ParticlesPlugin } from "@yagejs/particles"; engine.use(new ParticlesPlugin()); ``` ``` -------------------------------- ### Install Yage Core Packages Source: https://github.com/marco-lepore/yage/blob/main/README.md Manually install the core Yage packages if you prefer to set up your project from scratch. Additional packages can be installed as needed. ```bash npm install @yagejs/core @yagejs/renderer ``` ```bash npm install @yagejs/physics @yagejs/input @yagejs/audio @yagejs/debug ``` -------------------------------- ### Initialize Engine and Scene Source: https://github.com/marco-lepore/yage/blob/main/packages/core/README.md Basic setup for an engine instance and a custom scene with an entity. ```ts import { Engine, Scene, Entity, Component, Transform, Vec2 } from "@yagejs/core"; class Player extends Entity { setup() { this.add(new Transform({ position: new Vec2(100, 100) })); } } class GameScene extends Scene { readonly name = "game"; onEnter() { this.spawn(Player); } } const engine = new Engine(); await engine.start(); engine.scenes.push(new GameScene()); ``` -------------------------------- ### Physics Plugin Setup Source: https://github.com/marco-lepore/yage/blob/main/docs/llms/packages/physics.md Configure the physics engine with gravity and pixels per meter. ```APIDOC ## Setup ```ts import { PhysicsPlugin } from "@yagejs/physics"; engine.use(new PhysicsPlugin({ gravity: { x: 0, y: 980 }, // px/s², default (0, 980) pixelsPerMeter: 50, // default 50 })); ``` ``` -------------------------------- ### Install @yagejs/ui Source: https://github.com/marco-lepore/yage/blob/main/packages/ui/README.md Install the package via npm. ```bash npm install @yagejs/ui ``` -------------------------------- ### Install @yagejs/renderer Source: https://github.com/marco-lepore/yage/blob/main/packages/renderer/README.md Install the @yagejs/renderer package using npm. This package bundles PixiJS v8, so no separate installation is required. ```bash npm install @yagejs/renderer ``` -------------------------------- ### Setup Tilemap Plugin Source: https://github.com/marco-lepore/yage/blob/main/docs/llms/packages/tilemap.md Initialize the TilemapPlugin by using it with the engine. This is a required step before using tilemap functionalities. ```typescript import { TilemapPlugin } from "@yagejs/tilemap"; engine.use(new TilemapPlugin()); ``` -------------------------------- ### Install @yagejs/physics Source: https://github.com/marco-lepore/yage/blob/main/packages/physics/README.md Install the package via npm. Rapier 2D is bundled, but vite-plugin-wasm is recommended for Vite users. ```bash npm install @yagejs/physics ``` -------------------------------- ### Audio Plugin Setup Source: https://github.com/marco-lepore/yage/blob/main/docs/llms/packages/audio.md Configure the AudioPlugin with custom channel settings and auto-mute behavior on blur. ```APIDOC ## Setup ```ts import { AudioPlugin } from "@yagejs/audio"; engine.use(new AudioPlugin({ channels: { sfx: { volume: 1 }, music: { volume: 0.7 }, }, autoMuteOnBlur: true, // default: true — pause AudioContext on window blur })); ``` ``` -------------------------------- ### Setup InputPlugin with Action Maps Source: https://github.com/marco-lepore/yage/blob/main/docs/llms/packages/input.md Configure the InputPlugin by defining custom actions, grouping them into logical sets, and specifying keys that should have their default behavior prevented. This setup is crucial for initializing input handling in the Yage engine. ```typescript import { InputPlugin } from "@yagejs/input"; engine.use( new InputPlugin({ actions: { jump: ["Space", "KeyW"], left: ["ArrowLeft", "KeyA"], right: ["ArrowRight", "KeyD"], fire: ["MouseLeft"], }, groups: { gameplay: ["jump", "left", "right", "fire"], menu: ["confirm", "cancel"], }, preventDefaultKeys: ["Space", "ArrowUp", "ArrowDown"], }), ); ``` -------------------------------- ### Install @yagejs/core Source: https://github.com/marco-lepore/yage/blob/main/packages/core/README.md Install the core package via npm. ```bash npm install @yagejs/core ``` -------------------------------- ### Setup ParticlesPlugin Source: https://github.com/marco-lepore/yage/blob/main/docs/llms/packages/particles.md Register the ParticlesPlugin with the engine instance to enable particle functionality. ```ts import { ParticlesPlugin } from "@yagejs/particles"; engine.use(new ParticlesPlugin()); ``` -------------------------------- ### Install YAGE Core and Renderer Source: https://github.com/marco-lepore/yage/blob/main/docs/llms/quick-start.md Manually install the core YAGE engine and renderer packages using npm. Add other packages as needed for specific functionalities. ```bash npm install @yagejs/core @yagejs/renderer ``` ```bash npm install @yagejs/physics @yagejs/input @yagejs/audio @yagejs/debug ``` -------------------------------- ### Setup UIPlugin Source: https://github.com/marco-lepore/yage/blob/main/docs/src/content/docs/guides/ui.mdx Import and use the UIPlugin with the engine. This plugin requires the @yagejs/renderer package. ```typescript import { UIPlugin } from "@yagejs/ui"; engine.use(new UIPlugin()); ``` -------------------------------- ### Advanced YAGE Engine Setup Source: https://github.com/marco-lepore/yage/blob/main/docs/llms/quick-start.md Configure the YAGE engine with multiple plugins including Renderer, Input, and Physics. This setup enables debugging, defines input actions, and configures physics properties like gravity. ```typescript import { Engine } from "@yagejs/core"; import { RendererPlugin } from "@yagejs/renderer"; import { InputPlugin } from "@yagejs/input"; import { PhysicsPlugin } from "@yagejs/physics"; const engine = new Engine({ debug: true, fixedTimestep: 1000 / 60 }); engine.use(new RendererPlugin({ width: 800, height: 600, container: document.getElementById("game")! })); engine.use(new InputPlugin({ actions: { jump: ["Space", "KeyW"] } })); engine.use(new PhysicsPlugin({ gravity: { x: 0, y: 980 } })); await engine.start(); engine.scenes.push(new GameScene()); ``` -------------------------------- ### Snapshot Plugin Setup Source: https://github.com/marco-lepore/yage/blob/main/docs/llms/packages/save.md Configures and uses the SnapshotPlugin for full-scene serialization. Allows customization of the namespace and storage. ```typescript import { SnapshotPlugin } from "@yagejs/save"; engine.use(new SnapshotPlugin({ namespace: "my-game", // localStorage key prefix (default "yage") storage: myStorage, // custom SnapshotStorage (default localStorage) })); ``` -------------------------------- ### Initialize AudioPlugin Source: https://github.com/marco-lepore/yage/blob/main/docs/llms/packages/audio.md Configure audio channels and auto-mute behavior during engine setup. Ensure the AudioContext is ready before playing sounds. ```typescript import { AudioPlugin } from "@yagejs/audio"; engine.use(new AudioPlugin({ channels: { sfx: { volume: 1 }, music: { volume: 0.7 }, }, autoMuteOnBlur: true, // default: true — pause AudioContext on window blur })); ``` -------------------------------- ### Setup ParticlesPlugin Source: https://github.com/marco-lepore/yage/blob/main/docs/src/content/docs/guides/particles.mdx Initialize the particle system by adding the plugin to the engine. This plugin requires the @yagejs/renderer package. ```typescript import { ParticlesPlugin } from "@yagejs/particles"; engine.use(new ParticlesPlugin()); ``` -------------------------------- ### Initialize YAGE Engine with TilemapPlugin Source: https://github.com/marco-lepore/yage/blob/main/packages/tilemap/README.md Initialize the YAGE engine and register the TilemapPlugin. This setup is required before using any tilemap features. ```typescript import { Engine } from "@yagejs/core"; import { TilemapPlugin, TilemapComponent, tiledMap } from "@yagejs/tilemap"; const engine = new Engine(); engine.use(new TilemapPlugin()); ``` -------------------------------- ### Engine Lifecycle Management Source: https://github.com/marco-lepore/yage/blob/main/docs/src/content/docs/concepts/engine-and-plugins.mdx Register plugins using `engine.use()`, start the game loop with `engine.start()`, and clean up resources with `engine.destroy()`. ```typescript // 1. Register plugins engine.use(new RendererPlugin({ width: 800, height: 600, container: document.getElementById("game")! })); engine.use(new PhysicsPlugin()); engine.use(new InputPlugin()); // 2. Start the loop await engine.start(); // 3. Tear down when done engine.destroy(); ``` -------------------------------- ### Avatar Presenter Configuration Source: https://github.com/marco-lepore/yage/blob/main/packages/addons/dialogue/docs/llms/dialogue.md Example of configuring mixed dialogue with different avatar presenters. InBoxAvatarPresenter reserves space for a text column, while BubbleAvatarPresenter reserves space within a bubble. Use createMixedDialogue for composite setups. ```typescript createMixedDialogue(theme, { worldLayer: "world", avatar: { box: (layout) => new InBoxAvatarPresenter(layout, { layer, width: 84, background: { color } }), bubble: (layout) => new BubbleAvatarPresenter(layout, { layer: "world", size: 56 }), }, }); // box-only: createBoxDialogue(theme, { avatar: (layout) => new InBoxAvatarPresenter(...) }) ``` -------------------------------- ### Setup DebugPlugin Source: https://github.com/marco-lepore/yage/blob/main/docs/src/content/docs/guides/debug.mdx Import and use the `DebugPlugin` to enable the debug overlay. Configure `startEnabled` to show the overlay on launch and `toggleKey` to set the key for toggling. ```typescript import { DebugPlugin } from "@yagejs/debug"; engine.use(new DebugPlugin({ startEnabled: true, // show debug overlay on launch toggleKey: "Backquote", // key to toggle (default: backtick `) })); ``` -------------------------------- ### Install @yagejs/particles Source: https://github.com/marco-lepore/yage/blob/main/packages/particles/README.md Install the package via npm. ```bash npm install @yagejs/particles ``` -------------------------------- ### Install @yagejs/input Source: https://github.com/marco-lepore/yage/blob/main/packages/input/README.md Install the package via npm. ```bash npm install @yagejs/input ``` -------------------------------- ### Basic UI Component Setup with YAGE Source: https://github.com/marco-lepore/yage/blob/main/packages/ui-react/README.md Demonstrates setting up the YAGE engine, initializing the UI plugin, and creating a simple HUD component using React JSX. This includes importing necessary modules and defining a functional component with basic UI elements like Text and Button. ```tsx import { Engine } from "@yagejs/core"; import { UIPlugin } from "@yagejs/ui"; import { createUIRoot, Panel, Text, Button } from "@yagejs/ui-react"; const engine = new Engine(); engine.use(new UIPlugin()); await engine.start(); function HUD({ score }: { score: number }) { return ( Score: {score} ); } ``` -------------------------------- ### Install @yagejs/save Source: https://github.com/marco-lepore/yage/blob/main/packages/save/README.md Install the @yagejs/save package using npm. ```bash npm install @yagejs/save ``` -------------------------------- ### Setup Save Instance and Plugin Source: https://github.com/marco-lepore/yage/blob/main/docs/llms/packages/save.md Initializes the save instance with a local storage adapter and registers it with the YAGE engine using the SavePlugin. This allows components to access the save service. ```typescript import { Engine } from "@yagejs/core"; import { createSave, SavePlugin, localStorageAdapter } from "@yagejs/save"; const save = createSave({ adapter: localStorageAdapter({ namespace: "my-game" }), }); const engine = new Engine(); engine.use(new SavePlugin({ save })); ``` -------------------------------- ### Install @yagejs/debug Source: https://github.com/marco-lepore/yage/blob/main/packages/debug/README.md Install the @yagejs/debug package using npm. ```bash npm install @yagejs/debug ``` -------------------------------- ### InputPlugin Setup Source: https://github.com/marco-lepore/yage/blob/main/docs/src/content/docs/guides/input.mdx Configure input actions and groups for keyboard, mouse, and gamepad devices. Actions map to physical input codes, and groups organize related actions. ```typescript import { InputPlugin } from "@yagejs/input"; engine.use( new InputPlugin({ actions: { jump: ["Space", "GamepadA"], left: ["KeyA", "ArrowLeft", "GamepadDPadLeft"], right: ["KeyD", "ArrowRight", "GamepadDPadRight"], up: ["KeyW", "ArrowUp"], down: ["KeyS", "ArrowDown"], attack: ["KeyJ", "MouseLeft", "GamepadX"], interact: ["KeyE"], }, groups: { movement: ["jump", "left", "right", "up", "down"], combat: ["attack"], gameplay: ["interact"], }, }), ); ``` -------------------------------- ### Setting up DialogueController with Custom Storage and Commands Source: https://github.com/marco-lepore/yage/blob/main/packages/addons/dialogue/docs/llms/dialogue.md Demonstrates how to initialize a DialogueController with custom storage, functions, and commands. Use `cells` for two-way binding to game state and `MemoryVariableStorage` for local variables. Define functions for conditions and commands for game logic. ```typescript const dlg = host.add(new DialogueController({ ...createBoxDialogue(), storage: compose( cells({ gold: { get: () => player.gold, set: (v) => (player.gold = +v) } }), // two-way new MemoryVariableStorage(), // locals + seeds ), functions: { has_item: (id) => player.has(String(id)) }, // argument-read for conditions commands: { // game logic (rules in) "give-item": (cmd) => player.give(cmd.id), "skill-check": async (cmd, ctx) => ctx.setVar("passed", await roll(cmd.stat)), }, fallbackCommand: (cmd) => log(cmd), // optional catch-all })); const handle = dlg.play(script); // content-only handle.setVar("rude", true); // live poke (typed keyof declare); no-ops after stop/replay handle.getVars(); // snapshot of the storage's variables ``` -------------------------------- ### Install @yagejs/ui-react Source: https://github.com/marco-lepore/yage/blob/main/packages/ui-react/README.md Install the @yagejs/ui-react package along with React and ReactDOM. Note that React is a peer dependency. ```bash npm install @yagejs/ui-react react react-dom ``` -------------------------------- ### Initialize Engine in main.ts Source: https://github.com/marco-lepore/yage/blob/main/docs/src/content/docs/patterns/project-layout.mdx The main entry point should handle engine configuration and plugin registration without containing game logic. ```typescript // main.ts — entire file import { Engine } from "@yagejs/core"; import { RendererPlugin } from "@yagejs/renderer"; import { PhysicsPlugin } from "@yagejs/physics"; import { InputPlugin } from "@yagejs/input"; import { GameScene } from "./scenes/GameScene.js"; const engine = new Engine({ debug: true }); engine.use(new RendererPlugin({ width: 800, height: 600, container: document.getElementById("game")! })); engine.use(new PhysicsPlugin({ gravity: { x: 0, y: 980 } })); engine.use(new InputPlugin({ actions: { jump: ["Space"] } })); await engine.start(); engine.scenes.push(new GameScene()); ``` -------------------------------- ### Install Vite and WASM Plugin Source: https://github.com/marco-lepore/yage/blob/main/docs/src/content/docs/getting-started/installation.mdx Install Vite and the `vite-plugin-wasm` plugin, which is required if you are using `@yagejs/physics` to handle WebAssembly imports. ```bash npm install -D vite vite-plugin-wasm ``` -------------------------------- ### Basic Dialogue Scene Setup Source: https://github.com/marco-lepore/yage/blob/main/packages/addons/dialogue/docs/llms/dialogue.md Sets up a Yage scene to display dialogue. It initializes the DialogueController and plays a script, destroying the host entity when the dialogue ends. Ensure dialogue layers are declared in the scene. ```typescript import { Scene, Entity } from "@yagejs/core"; import { DialogueController, DialogueEndedEvent } from "@yagejs-addons/dialogue"; import { createBoxDialogue, DIALOGUE_LAYERS } from "@yagejs-addons/dialogue/presenters"; class TalkScene extends Scene { readonly layers = [...DIALOGUE_LAYERS]; // dialogue-frame / -avatar / -text (screen-space) onEnter() { const host = this.spawn("dialogue") as Entity; const dlg = host.add(new DialogueController({ ...createBoxDialogue() })); host.on(DialogueEndedEvent, () => host.destroy()); dlg.play(script); } } ``` -------------------------------- ### Create New Yage Project Source: https://github.com/marco-lepore/yage/blob/main/README.md Use this command to quickly scaffold a new Yage game project. Choose the 'minimal' template for an empty scene. ```bash npm create yage@latest my-game cd my-game npm run dev ``` -------------------------------- ### Camera Binding Recipes Source: https://github.com/marco-lepore/yage/blob/main/docs/llms/packages/renderer.md Provides examples of using CameraBinding for common effects like parallax and camera-agnostic minimaps. These demonstrate how to set translateRatio, rotateRatio, and scaleRatio to achieve desired visual behaviors. ```typescript // Parallax (translate-dampened) { layer: "background", translateRatio: 0.5 } ``` ```typescript // Camera-agnostic minimap (ignores every camera axis) { layer: "minimap", translateRatio: 0, rotateRatio: 0, scaleRatio: 0 } ``` -------------------------------- ### Install @yagejs/tilemap Source: https://github.com/marco-lepore/yage/blob/main/packages/tilemap/README.md Install the tilemap package using npm. This command adds the necessary library to your project for tile-based map functionalities. ```bash npm install @yagejs/tilemap ``` -------------------------------- ### Install Required Engine Packages Source: https://github.com/marco-lepore/yage/blob/main/packages/addons/dialogue/README.md Install the necessary YAGE engine packages as peer dependencies. These are required for the dialogue addon to function. ```bash npm install @yagejs/core @yagejs/input @yagejs/renderer ``` -------------------------------- ### Boot Pattern Initialization Source: https://github.com/marco-lepore/yage/blob/main/docs/llms/packages/save.md Initialize game state by restoring persistent stores and setting up auto-persistence. This pattern is typically used at the start of the application. ```typescript // game/main.ts import { settings, saves, opened, defeated } from "./persistence/stores.js"; import { save } from "./persistence/save.js"; await Promise.all([ save.restore("settings", settings), save.restore("saves", saves), save.restore("world.opened", opened), save.restore("world.defeated", defeated), ]); save.autoPersist("settings", settings); save.autoPersist("saves", saves); const engine = new Engine(); engine.use(new SavePlugin({ save })); await engine.start(); ``` -------------------------------- ### UIText with Installed Bitmap Font Source: https://github.com/marco-lepore/yage/blob/main/docs/llms/packages/ui.md Render text using an installed or loaded bitmap font by specifying its name in `style.fontFamily` and setting `bitmap: true`. ```typescript new UIText({ children: "READY", bitmap: true, style: { fontFamily: "PressStart", fontSize: 16 } }); ``` -------------------------------- ### Initialize Renderer Plugin Source: https://github.com/marco-lepore/yage/blob/main/docs/llms/packages/renderer.md Set up the RendererPlugin with essential configuration like canvas size, background color, and the HTML container. Optional parameters for virtual resolution, scaling, and pixel art are also shown. ```typescript import { RendererPlugin } from "@yagejs/renderer"; engine.use(new RendererPlugin({ width: 800, height: 600, backgroundColor: 0x1a1a2e, container: document.getElementById("game")!, // optional: virtualWidth: 320, // virtual resolution (auto-scaled) virtualHeight: 240, resolution: window.devicePixelRatio, fit: { mode: "cover" }, // override default letterbox (see below) pixelArtPreset: true, // crisp, non-blurred pixel art (see below) })); ``` -------------------------------- ### Implementing Quicksave and Quickload Source: https://github.com/marco-lepore/yage/blob/main/docs/src/content/docs/guides/snapshot-quicksave.mdx Integrate quicksave and quickload functionality into your game scene by listening for input events and using the `SnapshotService`. ```typescript import { Scene, InputManagerKey, SnapshotServiceKey } from "@yagejs/core"; class GameScene extends Scene { private readonly input = this.service(InputManagerKey); private readonly snapshot = this.service(SnapshotServiceKey); update(): void { if (this.input.isJustPressed("quicksave")) { this.snapshot.saveSnapshot("quicksave"); } if (this.input.isJustPressed("quickload")) { this.snapshot.loadSnapshot("quicksave"); } } } ``` -------------------------------- ### PhysicsPlugin Setup Source: https://github.com/marco-lepore/yage/blob/main/docs/src/content/docs/guides/physics.mdx Initialize the PhysicsPlugin with custom gravity and pixelsPerMeter settings. Gravity is in pixels/s², and pixelsPerMeter defines the conversion factor for physics calculations. ```typescript import { PhysicsPlugin } from "@yagejs/physics"; engine.use(new PhysicsPlugin({ gravity: { x: 0, y: 980 }, // pixels/s², default: (0, 980) pixelsPerMeter: 50, // conversion factor, default: 50 })); ``` -------------------------------- ### Setup UIReactPlugin Source: https://github.com/marco-lepore/yage/blob/main/docs/llms/packages/ui-react.md Import and use UIPlugin and UIReactPlugin to enable React reconciliation within the Yage engine. This setup is required for using React components with Yage's UI system. ```typescript import { UIPlugin } from "@yagejs/ui"; import { UIReactPlugin } from "@yagejs/ui-react"; engine.use(new UIPlugin()); engine.use(new UIReactPlugin()); ``` -------------------------------- ### Scene Transition Examples Source: https://github.com/marco-lepore/yage/blob/main/docs/llms/scene-transitions.md Demonstrates various scene transition types using the engine.scenes API. Imports include common transition functions from '@yagejs/renderer'. ```typescript import { chessboard, crossFade, fade, flash, iris, irisReveal, slidePush, } from "@yagejs/renderer"; // Push with a fade await engine.scenes.push(nextScene, { transition: fade({ duration: 400 }) }); // Pop with a flash await engine.scenes.pop({ transition: flash({ duration: 200, color: 0xff0000 }) }); // Replace with a cross-dissolve await engine.scenes.replace(newScene, { transition: crossFade({ duration: 500 }) }); // Iris-out → swap → iris-in (Zelda-style) await engine.scenes.replace(nextScene, { transition: iris({ duration: 700 }) }); // Checkerboard wipe with a custom grid await engine.scenes.push(nextScene, { transition: chessboard({ rows: 4, cols: 6 }) }); // Both scenes slide together (incoming pushes the previous one off) await engine.scenes.push(nextScene, { transition: slidePush({ direction: "left" }) }); // Per-scene default class MenuScene extends Scene { readonly name = "menu"; readonly defaultTransition = fade({ duration: 300 }); } ```