Add package documentation for AI agents
This commit is contained in:
150
AGENTS.md
Normal file
150
AGENTS.md
Normal 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`
|
||||
11
README.md
11
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.
|
||||
|
||||
103
docs/architecture.md
Normal file
103
docs/architecture.md
Normal 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
110
docs/lua-package-format.md
Normal 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
93
docs/protocol.md
Normal 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
100
docs/quick-start.md
Normal 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
82
docs/validation.md
Normal 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
|
||||
```
|
||||
Reference in New Issue
Block a user