Skip to main content

甜瓜游乐场 Lua 芯片执行器模拟 - Melon Playground Lua chip sandbox

Project description

Melon Lua Sandbox

甜瓜游乐场 Lua 芯片执行器模拟器。

基于 APK 逆向分析提取的真实 LuaPreamble.lua + 完整 Example_ApiReference_en.lua,使用 Python + lupa(LuaJIT)重现已有的 Lua 芯片执行环境。所有 API 名称、参数、返回值均与现实一致。

特性

  • ✅ 真实前置脚本 LuaPreamble.lua(Entity OOP、shared/signal/require 系统)
  • ✅ 甜瓜允许的标准库(stdlib_melon + verify_melon_stdlib.py
  • ✅ 11 个 ApiModule:entityspawnenvcamerainputinputFilterchipmechanicworldvariablesuicontrolprint
  • ✅ SDK 目录:object_physics_by_id.json(495 条尺寸;spawn.create("202") / spawn_entity(object_id=…)
  • ✅ 类型化输入输出:inputs.num.xoutputs.string.statusoutputs.vec.diroutputs.color.tint
  • ✅ 完整生命周期:OnInitOnTickOnActivatedOnDeactivatedOnSpawnedOnDestroy
  • ✅ Box2D 真实 2D 物理:重力、碰撞、addForcesetVelocityfreezegravityScale
  • ✅ 无真实时间等待,适合快速批量 tick 模拟

安装

pip install -e .

依赖:lupa(LuaJIT 绑定)、Box2D(pybox2d)。

已发布到 PyPI:pip install melon-lua

CLI 使用

# 基础运行(5 秒 × 20 TPS = 100 tick)
melon-lua samples/hello_chip.lua

# 精确跑 N tick(推荐)
melon-lua samples/bignum.lua --ticks 1000

# 静态输入
melon-lua samples/adder.lua --inputs inputs.json

# 时间线输入(按 tick 切换)
melon-lua samples/adder.lua --inputs-timeline timeline.json

# 快速 TPS
melon-lua samples/bignum.lua --ticks 100 --tps 60

# 种子实体(物理测试)
melon-lua samples/physics_demo.lua --ticks 80 \
  --seed-entity "crate,0,10" \
  --seed-static "floor,0,0"

# 列出 API
melon-lua --api-list

输入文件格式

静态 inputs.json

{
  "num": {"a": 5, "b": 3},
  "string": {"mode": "attack"}
}

时间线 timeline.json(tick 从 1 开始,设置后持续到下个变化点):

{
  "1": {"num": {"a": 1}},
  "30": {"num": {"a": 10}},
  "60": {"num": {"a": 0}}
}

文档

  • docs/API.md — Python SDK 完整参考(WorldContext、MelonScriptRunner、catalog、preview 等)
  • docs/LUA_GUIDE.md — 甜瓜 Lua 芯片开发完整指南(生命周期、API 速查 + 标准库)
  • docs/stdlib.md — 甜瓜芯片允许的标准库完整清单(含禁用项与验证方法)
  • docs/guide.md — 原始简版教程(已整合进 LUA_GUIDE.md)

建议先读 docs/LUA_GUIDE.md 写芯片,再用 docs/API.md 做 Python 侧集成/模拟。

from melon_lua import (
    MelonScriptRunner, WorldContext,
    get_profile_by_object_id, object_id_for_name, list_spawnables,
)

# 495 物体:objectId + 碰撞尺寸(贴图可选)
print(object_id_for_name("ResizablePlastic"))  # 202
prof = get_profile_by_object_id(202)

world = WorldContext()
# 按 objectId 或 gameObjectName 生成(自动套 APK 尺寸)
world.spawn_entity("202", 0, 5, dynamic=True)       # Plastic plate
world.spawn_entity("Box", 2, 5, dynamic=True)
world.spawn_entity("ground", 0, 0, dynamic=False, scale_x=10.0)

runner = MelonScriptRunner(tps=20, world=world)

source = '''
function OnInit()
    print("chip started")
end

function OnTick()
    local e = Entity(1)
    local x, y = e:getPosition()
    outputs.num.x = x
    outputs.num.y = y
end
'''

runner.compile(source)
runner.run_loop(ticks=100)
print(runner.logs)

手动单步:

runner.call_on_init()
result = runner.run_tick(inputs={"num": {"a": 5}})
print(result["outputs"])

真实 API 示例

function OnInit()
    print("init!")
end

function OnTick()
    -- 读取类型化输入
    local speed = inputs.num.speed or 0

    -- Entity OOP
    local e = Entity(1)
    e:setVelocity(speed, 0)

    -- 物理
    local x, y = e:getPosition()
    outputs.num.x = x
    outputs.num.y = y

    -- 生成请求(异步回调)
    spawn.create("human", x + 2, y)
end

function OnSpawned(requestId, entities)
    print("spawned request", requestId, "got", #entities, "entities")
end

生命周期

function OnInit() end          -- 芯片初始化,调用一次
function OnActivated() end     -- 激活时调用一次
function OnTick() end          -- 每 tick 调用(按 TPS)
function OnDeactivated() end   -- 停用时调用一次
function OnDestroy() end       -- 销毁时调用一次
function OnSpawned(requestId, entities) end  -- spawn.create 完成后回调

Box2D 物理

默认重力 (0, -9.8),y 轴向上为正。创建 entity 时通过 dynamic=True/False 决定是否为刚体。

物理方法:

  • entity:addForce(fx, fy) / addForceAtPosition(fx, fy, px, py) / addTorque(t)
  • entity:setVelocity(vx, vy) / setAngularVelocity(w)
  • entity:setPosition(x, y) / setAngle(deg)
  • entity:freeze(bool) / freezeRotation(bool) / setGravityScale(s)

注意:物理 Tick 与世界 Tick 同步,不按真实时间阻塞,因此可以快速模拟长时间演化。

项目结构

melon_lua/
├── preamble.lua              -- 真实 LuaPreamble.lua(APK 原版)
├── runner.py                 -- 芯片执行引擎
├── world.py                  -- Box2D 物理世界 + 全局状态
├── entity.py                 -- Entity 数据模型
└── backend/                  -- 11 个真实 ApiModule 的 Python 后端
    ├── entity_backend.py
    ├── env_backend.py
    ├── spawn_backend.py
    ├── chip_backend.py
    ├── mechanic_backend.py
    ├── world_backend.py
    ├── camera_backend.py
    ├── input_backend.py
    ├── inputFilter_backend.py
    ├── variables_backend.py
    └── uicontrol_backend.py

限制

  • 物理使用 Box2D,但物体形状目前均为矩形 box(与 sprite 无关),碰撞材质使用默认值。
  • 渲染、音效、网络、真实输入设备无法模拟。
  • 某些 ApiModule(如 mechanicuicontrolinputFilter)在沙盒中返回 mock 值,适合验证逻辑而非真实 UI/输入行为。

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

melon_lua-3.4.0.tar.gz (2.2 MB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

melon_lua-3.4.0-py3-none-any.whl (2.5 MB view details)

Uploaded Python 3

File details

Details for the file melon_lua-3.4.0.tar.gz.

File metadata

  • Download URL: melon_lua-3.4.0.tar.gz
  • Upload date:
  • Size: 2.2 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for melon_lua-3.4.0.tar.gz
Algorithm Hash digest
SHA256 d98b907ddc61a55942e19207e8467f8d2d87009c7180cca35d0bf5c4fa34c763
MD5 51ed2fd98260fbbb3f8b10d68a1b4910
BLAKE2b-256 f2b978f880ea9015fb9cb1096047a1bb4ee3d44158862ec7106597efbca61362

See more details on using hashes here.

Provenance

The following attestation bundles were made for melon_lua-3.4.0.tar.gz:

Publisher: publish.yml on xunxiing/MelonLuaSandbox

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file melon_lua-3.4.0-py3-none-any.whl.

File metadata

  • Download URL: melon_lua-3.4.0-py3-none-any.whl
  • Upload date:
  • Size: 2.5 MB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for melon_lua-3.4.0-py3-none-any.whl
Algorithm Hash digest
SHA256 27ad9b67462901786a1da703436709677018dccfe334b3c35327af89661fc508
MD5 510590a860d3f4dd46e075bc506017db
BLAKE2b-256 d3faa1eb0bea912c3b002a479e899f0c3fca26a8c2ee841c1ee4b37c4527306f

See more details on using hashes here.

Provenance

The following attestation bundles were made for melon_lua-3.4.0-py3-none-any.whl:

Publisher: publish.yml on xunxiing/MelonLuaSandbox

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page