Files
flutter_lua_runtime/docs/quick-start.md
gem 8ddc3be3a7 feat: multi-package loading with base framework support
- Add RuntimeOptions.basePackages for loading framework packages before game package
- Add ScriptEngine.loadPackages() for multi-package module merging
- LuaDardoScriptEngine merges modules from all packages, game overrides framework
- PackageActivationController loads base packages first, then game package
- GamePackageManifest parses optional 'base' field
- Update docs: README, quick-start, lua-package-format, architecture
- Update all test mocks with loadPackages() implementation
2026-06-10 00:04:00 +08:00

3.6 KiB

Quick start

This package embeds manifest-driven Lua game packages in Flutter apps.

Add dependency

For private Git usage, prefer a pinned tag:

dependencies:
  flame_lua_runtime:
    git:
      url: https://gitea.sdws.shop/xim/flutter_lua_runtime.git
      ref: v0.1.0

For local development:

dependencies:
  flame_lua_runtime:
    path: ../flame_lua_runtime

Add game assets to the host app

A minimal host app should provide one game package:

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:

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:

packages/flame_lua_runtime/assets/runtime/lua/

Embed in Flutter

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

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

{
  "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"
  }
}

Multi-package loading (base + game)

When multiple games share common modules (event router, diff utilities, panel stack, network layer), extract them into a framework package and load it before the game package.

Framework package structure:

assets/games/_framework/
  manifest.json
  scripts/
    app.lua
    diff.lua
    event_router.lua
    ids.lua
    net.lua
    panel_stack.lua

Framework manifest:

{
  "gameId": "_framework",
  "name": "Lua Game Framework",
  "version": "1.0.0",
  "runtimeApiVersion": 1,
  "entry": "scripts/app.lua",
  "assetsBase": "assets",
  "modules": {
    "app": "scripts/app.lua",
    "diff": "scripts/diff.lua",
    "event_router": "scripts/event_router.lua",
    "ids": "scripts/ids.lua",
    "net": "scripts/net.lua",
    "panel_stack": "scripts/panel_stack.lua"
  }
}

Game manifest (no framework modules needed):

{
  "gameId": "ludo",
  "base": "_framework",
  "modules": {
    "state": "scripts/state.lua",
    "rules": "scripts/rules.lua",
    "main": "scripts/main.lua"
  }
}

Game code imports framework modules transparently:

local app = runtime.import("app")       -- from framework
local state = runtime.import("state")   -- from game

Embed with base packages:

LuaGameWidget(
  gameId: 'ludo',
  runtimeOptions: const RuntimeOptions(
    runtimeLuaRoot: 'packages/flame_lua_runtime/assets/runtime/lua',
    basePackages: ['_framework'],
  ),
)

Module resolution order: game package modules override framework modules with the same name. The entry script always comes from the last package (game package).