From 5ebe6ee7868c3ee6021c1b9c425b5819f7c60e1c Mon Sep 17 00:00:00 2001 From: gem Date: Sun, 7 Jun 2026 23:08:21 +0800 Subject: [PATCH] Add package documentation for AI agents --- AGENTS.md | 150 +++++++++++++++++++++++++++++++++++++ README.md | 11 +++ docs/architecture.md | 103 +++++++++++++++++++++++++ docs/lua-package-format.md | 110 +++++++++++++++++++++++++++ docs/protocol.md | 93 +++++++++++++++++++++++ docs/quick-start.md | 100 +++++++++++++++++++++++++ docs/validation.md | 82 ++++++++++++++++++++ 7 files changed, 649 insertions(+) create mode 100644 AGENTS.md create mode 100644 docs/architecture.md create mode 100644 docs/lua-package-format.md create mode 100644 docs/protocol.md create mode 100644 docs/quick-start.md create mode 100644 docs/validation.md diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..5c21579 --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,150 @@ +# flame_lua_runtime Agent Guide + +This file is the first-stop guide for AI agents and maintainers working in this package. + +## What this package is + +`flame_lua_runtime` is a reusable Flutter + Flame + Lua 2D game runtime. + +The stable runtime boundary is: + +```text +RuntimeEvent -> Lua -> GameDiff / RuntimeCommand -> Flame +``` + +Flutter/Flame owns runtime infrastructure, rendering, resources, events, commands, diagnostics, and package lifecycle. Lua owns game logic, UI layout, event handling, and construction of diff/command tables. + +## Hard boundaries + +Do not add game-specific logic to Dart runtime code. + +Do not let Lua directly hold or mutate Flutter, Flame, Spine, Particle, or native objects. + +Do not expose unrestricted Lua APIs: + +- `require` +- `package` +- `dofile` +- `loadfile` +- `os` + +Lua modularization must go through: + +```lua +runtime.import(moduleName) +``` + +Modules must be declared in the game manifest. + +## Runtime Lua assets + +Shared Lua helper modules live here: + +```text +assets/runtime/lua/ +``` + +Supported shared modules currently include: + +```text +runtime_ui.lua +runtime_widgets.lua +runtime_commands.lua +layout.lua +``` + +Game manifests may reference them with restricted `runtime:` paths: + +```json +{ + "modules": { + "runtime_ui": "runtime:runtime_ui.lua" + } +} +``` + +`runtime:` paths must remain narrow: only `runtime:*.lua`, no `/`, no `..`, and no empty path. + +Package-local Lua modules remain under: + +```text +scripts/*.lua +``` + +## Public API surface + +The public barrel is: + +```text +lib/flame_lua_runtime.dart +``` + +Keep this API intentionally small. Add exports only when host apps need them. + +Current primary API: + +- `LuaGameWidget` +- `FlameLuaGame` +- `RuntimeOptions` +- `RuntimeLocaleResolver` +- `GamePackageRepository` +- `AssetGamePackageRepository` +- `RemoteGamePackageRepository` +- `ScriptEngine` +- `LuaDardoScriptEngine` + +## Repository layout + +```text +assets/runtime/lua/ Shared Lua framework modules +lib/runtime/ Dart runtime implementation +lib/flame_lua_runtime.dart Public API barrel +test/ Runtime and public API tests +tool/ Runtime helper/check scripts +example/ Runnable Flutter showcase app +``` + +## Validation commands + +Run these before committing package changes: + +```bash +flutter analyze +flutter test test +dart run tool/generate_lua_runtime_defs.dart --check +``` + +For the example app: + +```bash +cd example +flutter analyze +flutter test +``` + +For publish readiness: + +```bash +flutter pub publish --dry-run +``` + +A warning about missing `homepage` / `repository` is acceptable until real public metadata is configured. + +## Development rules + +- Keep protocol fields white-listed and explicit. +- Prefer simple data models over implicit behavior. +- Runtime commands must be generic, not game-specific. +- Lua helper aliases are allowed only if normalized before protocol validation. +- Tests should cover protocol parsing, package validation, script loading, command execution, and public API exports. +- If adding Lua helper APIs, update generated defs through `tool/generate_lua_runtime_defs.dart`. + +## More docs + +Read these docs before larger changes: + +- `docs/quick-start.md` +- `docs/architecture.md` +- `docs/lua-package-format.md` +- `docs/protocol.md` +- `docs/validation.md` diff --git a/README.md b/README.md index 1eee729..e96b592 100644 --- a/README.md +++ b/README.md @@ -98,6 +98,17 @@ For source-tree development, the default remains: RuntimeOptions.defaultRuntimeLuaRoot // assets/runtime/lua ``` +## Documentation + +For AI agents and maintainers, start with: + +- [`AGENTS.md`](AGENTS.md) — package boundaries, rules, public API, and validation commands. +- [`docs/quick-start.md`](docs/quick-start.md) — host app integration. +- [`docs/architecture.md`](docs/architecture.md) — Dart/Lua/Flame responsibilities. +- [`docs/lua-package-format.md`](docs/lua-package-format.md) — manifest and Lua package rules. +- [`docs/protocol.md`](docs/protocol.md) — RuntimeEvent, GameDiff, RuntimeNode, RuntimeCommand boundary. +- [`docs/validation.md`](docs/validation.md) — checks, smoke tests, and release flow. + ## Status This package is in early extraction stage. Public API is intentionally small and centered on `LuaGameWidget`, `FlameLuaGame`, `RuntimeOptions`, package repositories, and script engine interfaces. diff --git a/docs/architecture.md b/docs/architecture.md new file mode 100644 index 0000000..45200e8 --- /dev/null +++ b/docs/architecture.md @@ -0,0 +1,103 @@ +# Architecture + +`flame_lua_runtime` separates generic runtime infrastructure from game-specific Lua packages. + +## Boundary + +```text +RuntimeEvent -> Lua -> GameDiff / RuntimeCommand -> Flame +``` + +- Dart receives input, lifecycle, resource, and host events. +- Dart forwards white-listed runtime events to Lua. +- Lua returns a `GameDiff` and/or `RuntimeCommand` list. +- Dart validates and applies diffs/commands to Flame-owned components. + +## Responsibilities + +### Dart / Flutter / Flame owns + +- Rendering tree and `Component` lifecycle. +- Resource loading and cache ownership. +- Audio playback. +- Spine and particle object creation. +- Input/event dispatch. +- Package validation and activation. +- Runtime command execution. +- Diagnostics and error reporting. + +### Lua owns + +- Game state transitions. +- UI tree description. +- Layout calculation. +- Event handling decisions. +- Command/node table construction. + +Lua should only describe desired runtime state. It must not receive or retain Dart/Flame object references. + +## Key Dart areas + +```text +lib/runtime/models/ Protocol data models +lib/runtime/protocol/ Protocol validation/parsing +lib/runtime/scripting/ Lua engine boundary +lib/runtime/packages/ Manifest/package loading and activation +lib/runtime/rendering/ Flame render tree adapter +lib/runtime/commands/ Runtime command execution +lib/runtime/resources/ Resource loading and cache management +lib/runtime/events/ Event dispatch and gates +lib/runtime/lifecycle/ Async/session/task safety +``` + +## Package loading + +Game packages are manifest-driven. Bundled assets and remote/downloaded packages should flow through the same package abstraction where possible. + +Shared Runtime Lua modules are loaded from `RuntimeOptions.runtimeLuaRoot`. + +Default source-tree root: + +```text +assets/runtime/lua +``` + +Package dependency root: + +```text +packages/flame_lua_runtime/assets/runtime/lua +``` + +## Safety model + +- Lua module loading is manifest-declared. +- `runtime.import(moduleName)` is the only intended module import API. +- `runtime:` module paths are restricted to `runtime:*.lua`. +- Package-local scripts are restricted to `scripts/*.lua`. +- Runtime protocol fields are white-listed. +- Invalid diffs/commands should fail clearly instead of being silently ignored. + +## Extension guidance + +When adding features, prefer this order: + +1. Lua helper composition if it can be represented by existing nodes/commands. +2. Generic protocol field if multiple games need the capability. +3. Generic Runtime node/command if it requires Dart/Flame ownership. +4. Avoid game-specific Dart code. + +Examples of valid generic runtime features: + +- `listView` node. +- `particle` node. +- `toast` command. +- `copy_text` command. +- `play_spine_animation` command. +- Button image states. + +Examples that should stay Lua-side: + +- Game board rules. +- Game-specific dialog composition. +- Showcase category/menu behavior. +- Ludo/flight-specific animation choices. diff --git a/docs/lua-package-format.md b/docs/lua-package-format.md new file mode 100644 index 0000000..03eed38 --- /dev/null +++ b/docs/lua-package-format.md @@ -0,0 +1,110 @@ +# Lua game package format + +A game package is a manifest plus Lua scripts and optional assets. + +Typical structure: + +```text +assets/games// + manifest.json + scripts/ + main.lua + state.lua + ui.lua + runtime_defs.lua + assets/ + image.png + audio/ + click.wav +``` + +## Manifest modules + +Lua modules must be declared in `manifest.json`. + +```json +{ + "id": "template", + "version": "0.1.0", + "entry": "main", + "modules": { + "main": "scripts/main.lua", + "state": "scripts/state.lua", + "ui": "scripts/ui.lua", + "runtime_ui": "runtime:runtime_ui.lua", + "runtime_widgets": "runtime:runtime_widgets.lua", + "runtime_commands": "runtime:runtime_commands.lua", + "layout": "runtime:layout.lua" + } +} +``` + +Lua imports by module name: + +```lua +local ui = runtime.import("ui") +local widgets = runtime.import("runtime_widgets") +``` + +Do not use `require`, `package`, `dofile`, `loadfile`, or `os`. + +## Path rules + +Package-local module paths: + +```text +scripts/*.lua +``` + +Runtime shared module paths: + +```text +runtime:*.lua +``` + +`runtime:` paths must not contain `/`, `..`, or an empty filename. + +## Entry module + +The manifest `entry` module should expose lifecycle/event functions expected by the script engine. Keep game-specific state in Lua modules and return runtime diffs/commands through the approved protocol. + +## Runtime helper modules + +Shared helpers are provided by the runtime package: + +```text +assets/runtime/lua/runtime_ui.lua +assets/runtime/lua/runtime_widgets.lua +assets/runtime/lua/runtime_commands.lua +assets/runtime/lua/layout.lua +``` + +Use helpers for authoring convenience, but remember helpers must normalize into supported Runtime protocol nodes/commands before Dart validation. + +## Generated Lua definitions + +`runtime_defs.lua` files are generated from common definitions. After changing helper APIs, run: + +```bash +dart run tool/generate_lua_runtime_defs.dart +``` + +Check without rewriting: + +```bash +dart run tool/generate_lua_runtime_defs.dart --check +``` + +## Package validation + +A host repository can validate a game package with: + +```bash +dart run tool/check_runtime_package.dart assets/games/template packages/flame_lua_runtime/assets/runtime/lua +``` + +Within this package repo, example game packages live under: + +```text +example/assets/games/ +``` diff --git a/docs/protocol.md b/docs/protocol.md new file mode 100644 index 0000000..5fd501e --- /dev/null +++ b/docs/protocol.md @@ -0,0 +1,93 @@ +# Runtime protocol + +The runtime protocol is the stable boundary between Lua and Dart. + +```text +RuntimeEvent -> Lua -> GameDiff / RuntimeCommand -> Flame +``` + +## RuntimeEvent + +Dart sends white-listed events to Lua. Events represent input, lifecycle, command/resource outcomes, and host/runtime notifications. + +Lua should treat events as data and return explicit state changes. + +## GameDiff + +A `GameDiff` describes desired changes to the runtime render tree. + +Typical operations include creating, updating, and removing runtime nodes. Dart validates node fields before applying them to Flame components. + +## RuntimeNode + +Runtime nodes are generic render descriptions. They are not Flame objects. + +Supported node concepts include: + +- Containers/panels. +- Text. +- Sprites/images. +- Buttons. +- List views. +- Particles. +- Spine nodes. + +Lua may compose higher-level widgets, but those widgets must normalize into supported runtime nodes. + +## RuntimeCommand + +Runtime commands request generic side effects owned by Dart/Flame. + +Examples: + +- `move_path` +- `move_to` +- `fade_to` +- `scale_to` +- `rotate_to` +- `remove_node` +- `sequence` +- `parallel` +- `delay` +- `toast` +- `play_sound` +- `play_bgm` +- `pause_bgm` +- `resume_bgm` +- `stop_bgm` +- `preload_resources` +- `evict_resources` +- `cancel_commands` +- `play_spine_animation` +- `copy_text` + +Commands must remain generic. Do not add commands like `roll_ludo_dice` or `move_airplane_piece`; those belong in Lua game logic. + +## Validation expectations + +- Unknown protocol fields should not become implicit behavior. +- Required fields should fail clearly when absent. +- Helper-only aliases must be normalized before Dart protocol validation. +- Runtime code should not silently convert invalid game state into fake success. + +## Where to change protocol code + +```text +lib/runtime/models/ Data models +lib/runtime/protocol/ Protocol validation +lib/runtime/commands/ Command validation/execution +lib/runtime/rendering/ Runtime node to Flame component mapping +assets/runtime/lua/ Lua helper constructors/aliases +``` + +When protocol changes affect Lua authoring, update: + +```text +tool/lua_runtime_defs_common.lua +``` + +Then run: + +```bash +dart run tool/generate_lua_runtime_defs.dart +``` diff --git a/docs/quick-start.md b/docs/quick-start.md new file mode 100644 index 0000000..ed12c1e --- /dev/null +++ b/docs/quick-start.md @@ -0,0 +1,100 @@ +# Quick start + +This package embeds manifest-driven Lua game packages in Flutter apps. + +## Add dependency + +For private Git usage, prefer a pinned tag: + +```yaml +dependencies: + flame_lua_runtime: + git: + url: https://gitea.sdws.shop/xim/flutter_lua_runtime.git + ref: v0.1.0 +``` + +For local development: + +```yaml +dependencies: + flame_lua_runtime: + path: ../flame_lua_runtime +``` + +## Add game assets to the host app + +A minimal host app should provide one game package: + +```text +assets/games/template/manifest.json +assets/games/template/scripts/main.lua +assets/games/template/scripts/state.lua +assets/games/template/scripts/ui.lua +``` + +Declare assets in the host app `pubspec.yaml`: + +```yaml +flutter: + assets: + - assets/games/template/manifest.json + - assets/games/template/scripts/ + - assets/games/template/assets/ +``` + +The runtime package itself provides shared Runtime Lua helpers from: + +```text +packages/flame_lua_runtime/assets/runtime/lua/ +``` + +## Embed in Flutter + +```dart +import 'package:flutter/material.dart'; +import 'package:flame_lua_runtime/flame_lua_runtime.dart'; + +class GameScreen extends StatelessWidget { + const GameScreen({super.key}); + + @override + Widget build(BuildContext context) { + return const LuaGameWidget( + gameId: 'template', + runtimeOptions: RuntimeOptions( + runtimeLuaRoot: 'packages/flame_lua_runtime/assets/runtime/lua', + ), + ); + } +} +``` + +## Run the package example + +```bash +cd example +flutter run --dart-define=LUA_GAME_ID=showcase +flutter run --dart-define=LUA_GAME_ID=template +flutter run --dart-define=LUA_GAME_ID=ludo +flutter run --dart-define=LUA_GAME_ID=flight +``` + +## Minimal manifest + +```json +{ + "id": "template", + "version": "0.1.0", + "entry": "main", + "modules": { + "main": "scripts/main.lua", + "state": "scripts/state.lua", + "ui": "scripts/ui.lua", + "runtime_ui": "runtime:runtime_ui.lua", + "runtime_widgets": "runtime:runtime_widgets.lua", + "runtime_commands": "runtime:runtime_commands.lua", + "layout": "runtime:layout.lua" + } +} +``` diff --git a/docs/validation.md b/docs/validation.md new file mode 100644 index 0000000..5911944 --- /dev/null +++ b/docs/validation.md @@ -0,0 +1,82 @@ +# Validation and release checks + +Run validation from the package root unless noted otherwise. + +## Package checks + +```bash +flutter pub get +flutter analyze +flutter test test +dart run tool/generate_lua_runtime_defs.dart --check +``` + +## Example checks + +```bash +cd example +flutter pub get +flutter analyze +flutter test +``` + +## Publish dry run + +```bash +flutter pub publish --dry-run +``` + +A warning about missing `homepage` or `repository` is acceptable until real public metadata is configured. Do not add fake metadata. + +## Manual smoke runs + +```bash +cd example +flutter run --dart-define=LUA_GAME_ID=showcase +flutter run --dart-define=LUA_GAME_ID=template +flutter run --dart-define=LUA_GAME_ID=ludo +flutter run --dart-define=LUA_GAME_ID=flight +``` + +## Lua static checks + +Lua static checks require `lua-language-server`. + +If available, run the host/static-check workflow that points at game packages and `.luarc.json`. + +If unavailable, state explicitly that LuaLS is not installed instead of claiming static verification passed. + +## Windows builds + +Flutter Windows builds must be run on a Windows host. + +Example: + +```powershell +fvm flutter build windows --debug --dart-define=LUA_GAME_ID=template +``` + +If CMake has stale target names after project renames, delete the Windows build cache first: + +```powershell +Remove-Item -Recurse -Force build\windows -ErrorAction SilentlyContinue +``` + +## Git release flow + +For private Git dependency usage, prefer tags over `main`: + +```bash +git tag v0.1.0 +git push origin v0.1.0 +``` + +Consumers can depend on: + +```yaml +dependencies: + flame_lua_runtime: + git: + url: https://gitea.sdws.shop/xim/flutter_lua_runtime.git + ref: v0.1.0 +```