Skip to main content

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:entity、spawn、env、camera、input、inputFilter、chip、mechanic、world、variables、uicontrol、print
  • ✅ SDK 目录:object_physics_by_id.json(495 条尺寸,Python spawn_entity/add_item)+ 真机菜单 alias 表(spawn.create("plastic_plate"))
  • ✅ Agent 文档对:docs/persona.md + docs/API.md
  • ✅ 类型化输入输出:inputs.num.x、outputs.string.status、outputs.vec.dir、outputs.color.tint 等
  • ✅ 完整生命周期:OnInit、OnTick、OnActivated、OnDeactivated、OnSpawned、OnDestroy
  • ✅ Box2D 真实 2D 物理:重力、碰撞、addForce、setVelocity、freeze、gravityScale
  • ✅ 无真实时间等待,适合快速批量 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(如 mechanic、uicontrol、inputFilter)在沙盒中返回 mock 值,适合验证逻辑而非真实 UI/输入行为。

Metadata

Release files for melon-lua 5.3.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for melon-lua 5.3.0
File Size Uploaded
melon_lua-5.3.0.tar.gz 2.4 MB Details

Built distribution (wheel)

Table of built distributions (wheels) for melon-lua 5.3.0
File Interpreter ABI Platform
melon_lua-5.3.0-py3-none-any.whl Python 3 none any Details

Total release size: 5.1 MB

Release files / melon_lua-5.3.0.tar.gz

Download URL melon_lua-5.3.0.tar.gz
Size 2.4 MB
Tags Source
SHA-256 checksum
How to use checksums
a96db9efe2ac75877ead942dcfa1d652565f098aa1b73c616c3aaab6153e82fd
BLAKE2b-256 checksum
How to use checksums
f10cb50a9f5b4ed4ac17aa9023088e0f6a4596c9b053db5c484b03af34e99da7
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 10, 2026.

Transparency log

Release files / melon_lua-5.3.0-py3-none-any.whl

Download URL melon_lua-5.3.0-py3-none-any.whl
Size 2.7 MB
Tags Python 3
SHA-256 checksum
How to use checksums
eaca73483dbba83874c5b9b5a18a438ab509a546fc4f12bb818eb07009e185c8
BLAKE2b-256 checksum
How to use checksums
09316ad74f22189db42d8123d899ad7dc099352e2e6224c5b7e55a3d8b3d3f12
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 10, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

5.3.0 This release

2 release files

5.2.5

2 release files

5.2.4

2 release files

5.2.3

2 release files

5.2.1

2 release files

5.2.0

2 release files

5.1.1

2 release files

5.1.0

2 release files

5.0.1

2 release files

5.0.0

2 release files

4.0.0

2 release files

3.5.0

2 release files

3.4.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page