Add package documentation for AI agents

This commit is contained in:
gem
2026-06-07 23:08:21 +08:00
parent 733b2fb798
commit 5ebe6ee786
7 changed files with 649 additions and 0 deletions

150
AGENTS.md Normal file
View File

@@ -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`

View File

@@ -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.

103
docs/architecture.md Normal file
View File

@@ -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.

110
docs/lua-package-format.md Normal file
View File

@@ -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/<gameId>/
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/
```

93
docs/protocol.md Normal file
View File

@@ -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
```

100
docs/quick-start.md Normal file
View File

@@ -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"
}
}
```

82
docs/validation.md Normal file
View File

@@ -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
```