关于 loenn-mcp
loenn-mcp 是面向 Celeste 地图编辑的 MCP 服务,也提供用于脚本和 CI 的 `pcgscene` 命令行工具。它可读取、编辑、分析、验证和生成 `.bin` 地图,并通过备份、预览和写入保护降低修改风险。
主要功能
- 01读取与编辑 `.bin` 地图
- 02实体、房间与效果分析
- 03地图验证和自动修复
- 04程序化生成与图像转地图
- 05写入备份及编辑器保护
- 06交互式 HTML 地图预览
适用场景
- 01通过 MCP 客户端编辑 Celeste 地图
- 02验证地图可玩性并修复问题
- 03从图像或种子生成地图
- 04在 CI 中脚本化地图处理
MCP 相关
该 MCP 服务向 MCP 客户端提供 Celeste `.bin` 地图的读取、编辑、分析、生成和预览工具。写入操作会保留带时间戳的备份,并在地图由 Lönn 打开时拒绝修改。
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
我们还没有获取到这个服务的安装包或远程地址,请按项目 README 中的说明安装。
工具
本地服务需要在你的电脑上运行后才能读取工具,维护者暂未提供工具列表。
详细介绍
loenn-mcp
面向 AI Agent 的 Celeste 地图编辑器——一个 Model Context Protocol(MCP)服务,可让 Claude、GitHub Copilot 和其他 MCP 客户端完整编辑 Celeste .bin 地图,并提供独立的 pcgscene CLI,用于脚本编写和 CI。无需打开 Lönn,即可读取、编辑、分析、生成和预览地图。
“面向 AI Agent”描述的是谁与此服务交互(任何 MCP 客户端),而非其中运行的内容——这里的每个工具都是确定性的程序化工具。请参阅内部不含 AI。
可与 Everest 模组以及来自 Lönn 或 Ahorn 的地图配合使用。
目录
- 功能
- 安全性:备份、副本和提交
- 在 Lönn 中打开地图
- Sprite Fusion 灰盒房间
- Summer Engine 灰盒房间
- 共享 PCG 核心(CelPcg)
- seleCte 关卡
- 工具参考
- 安装与设置
- JSON 往返与创作
pcgsceneCLI- 程序化生成
- 图像转地图
- 带种子的地形生成
- 分析与洞察
- 内部不含 AI(v7.0.0)
- 配置
- 架构
- 要求
- 许可证
功能
提供用于完整地图操作的 MCP 工具(完整列表见工具参考),以及用于脚本编写和 CI 的 pcgscene 命令行工具。每次写入都会保留带时间戳的备份;在 Lönn 中打开的地图会受到保护,不会被 MCP 写入;在 Sprite Fusion 中绘制的灰盒房间可直接导入。
核心工具
读取与查询
list_maps— 列出所有.bin文件read_map_overview— 汇总房间、实体、触发器和风格地面read_room— 房间完整详情(图块、实体、触发器、贴花)get_room_tiles— 原始图块网格(前景或背景)read_map_metadata— 无需完整读取即可快速获取元数据search_entities— 按类型、位置和房间查找实体search_triggers— 按类型查找触发器compare_rooms— 并排比较房间
编辑
add_entity/remove_entity— 放置或删除实体update_entity/move_entity— 修改实体属性或位置add_trigger/remove_trigger— 放置或删除触发器set_room_tiles— 替换图块网格add_room/remove_room— 创建或删除房间create_map— 创建新的.bin文件update_room— 修改房间属性(音乐、黑暗、风等)clone_room— 复制房间batch_add_entities— 一次添加多个实体resize_room— 更改房间尺寸
JSON 与内容创作(参见 JSON 往返转换与内容创作)
map_to_json/json_to_map— 将任意.bin转换为类型化 JSON 并还原,字节完全一致;拒绝有损写入check_authoring_json— 解析手写内容:从 Lönn 插件填充默认值,并标记未知名称merge_json_into_map— 向地图添加实体、触发器和房间;提供试运行差异与高亮预览、全地图唯一 ID、放置检查,且仅添加内容run_author_script— 运行 JavaScript 内容创作脚本(js/,采用 lucid-dream 风格)并合并其输出
贴花与效果
list_decals/add_decal/remove_decal— 管理前景和背景贴花list_stylegrounds/add_styleground/update_styleground/remove_styleground— 管理地图效果
定义与目录
list_entity_definitions/get_entity_definition— 浏览实体类型;按地图中使用的名称查询定义(例如MyMod/CloudBoss)find_missing_definitions— 查找地图中没有已安装 Lönn 插件定义的带命名空间实体和触发器audit_plugin_coverage— 查找没有 Lönn 插件的 C#[CustomEntity]名称,以及没有 C# 代码的插件(读取 .csproj 编译列表)list_trigger_definitions/get_trigger_definition— 浏览触发器类型list_effect_definitions/get_effect_definition— 浏览效果类型
分析与洞察
基础分析
analyze_map— 实体数量、类型细分和世界边界visualize_map_layout— ASCII 迷你地图preview_map_section— 详细的 ASCII 预览
高级分析
analyze_entity_usage— 分析整个地图中的实体统计数据analyze_difficulty— 估算房间或地图的难度find_entity_references— 查找某实体类型的所有实例detect_map_patterns— 识别设计原型(线性、枢纽等)analyze_room_connectivity— 分析邻接图
建议与改进
suggest_improvements— 提供可执行的房间改进建议compare_maps— 比较地图结构差异
Wiki 与缓存
wiki_save/wiki_search/wiki_list/wiki_get— 保存并检索分析结果
项目管理
get_mod_info— 项目元数据和结构validate_map/batch_validate_and_fix— 验证地图可玩性并自动修复game_status/game_reload_map/game_teleport/game_log— 通过 Everest 的调试服务驱动正在运行的游戏:查看当前位置、重新加载已编辑的地图、跳转到某个房间、读取加载错误game_play_tas— 从房间出生点开始播放 CelesteTAS 输入,并报告结束时的房间、位置、死亡次数和冲刺次数:验证房间是否可通关,或快捷路线是否行不通validate_audio— 检查地图引用的每个音频事件是否存在于 GUIDs.txt 和游戏的 FMOD 音频库中,并提供最接近的匹配建议export_room_json/import_room_json— 以 JSON 格式交换房间
差异比较
summarize_map_diff— 通过快照追踪地图演变
渲染
render_map_html— 交互式 HTML 地图预览,包含图块、颜色编码的实体标记、缩放/平移、搜索和小地图;读取.bin或类型化 JSON 转储,并可高亮显示计划中的合并(overlay)
程序化生成
基于模式生成
build_pattern_library— 从现有地图中提取模式generate_room_from_pattern— 使用策略和种子生成房间ingest_external_map— 从 GameBanana 下载并提取模式
图像和地形生成
generate_map_from_image— 将颜色映射图像转换为可游玩的地图generate_terrain_map— 使用 Perlin 噪声和 Voronoi 生物群系生成程序化地图preview_terrain_biomes— 在生成前预览生物群系布局
安全:备份、副本和提交
不会在未提示的情况下覆盖地图。
- 每次写入都会在替换文件前创建带时间戳的备份,并存储在 Mod 文件夹之外
(这样 Everest 就不会加载它,Mod 的 Git 工作区也会保持干净):
%LOCALAPPDATA%\loenn-mcp\backups\<mod>\<path>\<name>.<YYYYMMDD-HHMMSS-micro>.bin。 每个工具的结果末尾都会列出写入的文件及其备份。 - 替换任何内容前,都会重新解析新字节,然后写入临时文件并以原子方式替换。
- 章节地图请先复制:使用
map_copy,编辑副本,再运行map_diff,然后运行map_commit(先进行试运行;可只提交部分房间;如果房间未通过验证,例如缺少玩家出生点,则会拒绝提交)。 LOENN_MCP_PROTECT(以;分隔的 glob 列表,相对于 Mod 路径)会将匹配的地图设为只读,但map_commit除外。CEL 推荐配置:Maps/CEL/Area/*.bin;Maps/CEL/BSide/*.bin;Maps/CEL/CSide/*.bin;Maps/CEL/DSide/*.bin;Maps/CEL/ZSide/*.bin。- 如果地图正在由通过
editor_open启动的编辑器打开,或正在你自己的 Lönn 中打开,则会拒绝写入,因为 Lönn 下次保存时会覆盖这些写入。 map_backups会列出备份,map_restore会还原其中一个备份(先备份当前文件)。map_diff比较的是内容,而不是字节:房间、几何结构、前景/背景图块单元格、按 ID 匹配的实体和触发器、装饰、风格地面及元数据。Lönn 保存时会重新编码整个文件,因此字节差异没有实际参考价值。
往返转换均经过测试。要检查文件夹中的每张地图(.bin 转为树状结构再转回 .bin,以及 .bin 转为类型化 JSON 再转回 .bin,两种方式都必须字节完全一致):
LOENN_MCP_TEST_MAPS="<Maps folder>" python -m unittest discover -s tests -k RealMaps
在 Lönn 中打开地图
editor_open(map, room) 会在 Lönn 中打开指定地图和房间。editor_wait 会阻塞,直到你保存(并报告保存内容的语义差异)或关闭 Lönn。editor_close 会先询问 Lönn,然后将其关闭;force 会强制终止它。
此功能依赖以下机制,这些机制已通过阅读 Lönn 1.0.10 的源代码并在 Windows 上测试:
| 机制 | 行为 |
|---|---|
Lönn.exe <map.bin> | 打开指定地图,而不是上次打开的地图。 |
--storage-directory <dir> | 使用 <dir> 存储设置、持久化数据、备份和插件设置。MCP 使用隔离副本(%LOCALAPPDATA%\loenn-mcp\loenn-storage,从你的设置和插件设置复制而来),因此不会影响你的最近文件。storage="user" 使用你常用的 Lönn 文件夹。 |
| 房间选择 | 不存在命令行选项。Lönn 加载时会选中 persistence.lastSelectedRoomName,因此 MCP 会在启动前写入该键和摄像机状态。 |
| 检测编辑完成 | Lönn 会将内容保存到 <map>.bin.saving,验证后再将其重命名并覆盖地图。MCP 会监视地图的大小、修改时间和哈希值,在 .saving 存在时忽略该地图,并且只统计可解析的字节。 |
| 在运行中的 Lönn 中重新加载 | 无法实现:Lönn 没有 IPC 或单实例锁。请先关闭再重新打开(editor_close,然后 editor_open)。 |
编辑器端采用适配器(loenn_mcp/editors):目前提供 LoennAdapter,而 RysyAdapter 会使用相同的监视机制启动 Rysy(通过 --map),因此无需更改工具接口即可切换到基于 Rysy 的配置。
Sprite Fusion 灰盒房间
在 Sprite Fusion 中绘制灰盒房间,并将其导入为 Celeste 房间。
sf_make_tileset()会将celeste_graybox.png、图例和 README 写入%LOCALAPPDATA%\loenn-mcp\sprite-fusion。- 在 Sprite Fusion 中,以 16 的图块大小导入
celeste_graybox.png。将地图设为 40x23 个单元格,作为一个屏幕 (一个单元格 = 一个 8x8 的 Celeste 图块)。在启用了 Collider 的图层上绘制地面,在名为bg的图层上绘制 背景墙,并在任意位置放置玩家、尖刺、弹簧、补充道具、草莓、可穿越平台或梦境方块。 - 导出为 JSON(
map.zip),然后调用sf_import(export_path, map_path, room, output_path=...),先进行试运行。
详情:
- 导出文件中的图块 ID 对应导出的精灵图,因此会按像素将图块与图块集匹配 (需要 Pillow);匹配失败时则使用 ID。
- 尖刺和可穿越平台会按连续区段合并,梦境方块会合并为矩形。实体使用 Lönn 的默认设置。
- 只会放置具有 Lönn 定义的实体(优先使用精灵)。图块可以带有 Sprite Fusion 属性
entity、anchor和实体数据,以放置其他实体;不接受未知名称。 - 不在图块集中的非碰撞图层图块会被视为装饰并忽略,报告中会显示数量:请在灰盒效果良好后再到 Lönn 中添加装饰。
- 新房间会被添加(默认添加到现有房间的右侧)。只有设置
replace=true时才会修改现有房间;此操作会替换其前景/背景图块和实体,并保留触发器、贴花和设置。 - 自定义图例(
legend_path)可以将你自己的图块集图块映射到类型和前景图块字符。
Summer Engine 灰盒房间
Summer Engine 是 Godot 4.7 的一个分支。你可以在那里将房间绘制为场景,再将其转换为 Celeste 房间;也可以将 Celeste 房间(或 Sprite Fusion 导出内容)导入 Summer 进行完善。
summer_init()会在Documents\CEL-Graybox创建项目:灰盒图块集会作为 GodotTileSet(自定义数据kind,实心图块启用碰撞)导入;同时创建rooms/_template.tscn(包含bg、fg、gameplay图层和橙色 40x23 屏幕边框),以及celeste/中的桥接脚本。summer_open(scene)会在房间场景中启动 Summer 编辑器。Summer 启动时会显示 AI 聊天面板并要求你登录;切换到 2D 标签页即可绘制。导出前请按 Ctrl+S 保存。summer_export_room(scene, map_path, room, ...)会将场景转换为 Celeste 房间,执行与sf_import相同的检查、试运行和安全写入。replace=true会更新现有房间并保留每个实心单元格的图块集。summer_import_room(map_path, room)会将现有 Celeste 房间导入项目;summer_from_sprite_fusion则会对 Sprite Fusion 导出内容执行相同操作。- 非灰盒图块的实体会以
Marker2D节点形式传递,并带有元数据entity及其字段。 - 一个图块就是一个 8x8 的 Celeste 图块,无论 Godot 图块大小是多少;其他图块集也可使用(名为
fg/solid/terrain的图层,或任何带碰撞的图块,都会被视为实心)。
运行方式:Summer.exe --path <project> --summer-editor-script <script.gd> --summer-editor-script-out <dir>
会在导入扫描后于无头编辑器中运行 GDScript,并写入 result.json。每次调用约需 4 秒。
此操作无需登录或联网。
共享 PCG 核心(CelPcg)
csharp/ 存放可供 MCP、CEL mod 和 Summer Engine 共用的程序生成核心
(设计文档:docs/PCG-CORE-DESIGN.md)。
CelPcg.Core(netstandard2.0,无依赖):PCG32 随机数和种子派生、房间模型、 可达性模型(移植自 CEL 的overworld_gen/reach.py:向上跳 3 格/横向 6 格、冲刺 4 格、弹簧、补给点、 可穿越平台;不支持攀爬)、验证器(结构检查,以及从入口可到达每个出口)和平台链生成器。CelPcg.Cli(celpcg):celpcg generate --exits left:16:4,right:10:4 --difficulty 4 --seed 42会输出 celpcg-room JSON 文档;celpcg validate --room room.json会重新验证一个房间。CelPcg.Tests:dotnet test csharp/CelPcg.Tests(确定性、可达范围限制,以及 1,200 个生成的房间,这些房间都 必须通过仅使用原版实体的验证)。
pcg_generate_room(map_path, room, exits, difficulty, seed, ...) 首次使用时会构建 CLI(需要 .NET 8
SDK 或更高版本),然后生成房间,并通过与灰盒导入器相同的检查路径写入。只有在证明每个出口都可到达后才会返回房间;布局失败时会使用派生种子重试,因此相同请求始终会生成相同房间。种子会存储在房间上(celpcg_seed、celpcg_generator、celpcg_difficulty)。
首个版本的限制:入口必须是左侧或右侧出口;房间只有一种平台链风格;尚无模板或 MdMC/WFC 填充(设计文档的第 4 阶段)。
seleCte 关卡
seleCte(Louis Robinet,FDG '25)使用多维马尔可夫链学习 Celeste 原版房间的图块模式。它会绘制关卡布局,从模型中采样填充每个房间,并通过 Maple 库上的 Julia 脚本将房间编码为一个 .bin,该文件从一个出生点开始,以水晶之心结束。
selecte_generate(name, nb_rooms, proba, width, height, seed, ...) 会在一次调用中运行整个流程:Python
生成器(uv run)、Julia 编码器,然后对结果运行 pcgscene 的就绪检查清单。关卡的
data.json、room_<n>.csv、两个日志文件和 .bin 都会存放在 <state dir>\selecte\<name> 中。output_path 还会通过受保护的写入(备份、受保护地图、打开的编辑器)将 .bin 复制到 mod 中,除非检查清单发现问题(allow_problems=true 时仍会复制)。
- 设置:克隆 seleCte,然后在其中运行
uv sync和julia --project=. -e "using Pkg; Pkg.instantiate()"(需要 Julia 1.11 或更高版本;训练好的模型随克隆一并提供,不需要 Celeste 本体)。MCP 会依次从SELECTE_DIR、本仓库旁的seleCte文件夹和~/seleCte中查找克隆目录。 width/height为 22x14 时只需几秒;40x23(一屏)则每个房间需要几分钟。proba为 0 时会生成走廊,接近 1 时会生成迷宫。tries_limit会对未通过 seleCte 可玩性检查的房间重新采样;reset_skeleton会重新绘制布局,而不是保留不可玩的房间。seed和model需要使用打过补丁的克隆(上游 seleCte 不支持--seed,并且始终使用pe_d5_full);如果克隆缺少这些功能,工具会报告生成器自身的错误。- seleCte 的可玩性检查不考虑重力、跳跃和冲刺,因此无法证明房间一定能通关:请使用
game_play_tas或pcg_generate_room的可达性模型进行检查。只有重启游戏后,Everest 才会注册新的.bin。
工具参考
107 个工具;默认列出 89 个。标记为 extra 的工具会被隐藏,除非设置 LOENN_MCP_TOOLS=all。由 tools/gen_tool_reference.py 生成。
地图读取工具
| 工具 | 功能 |
|---|---|
list_maps | 列出项目中的所有 .bin 地图文件。 |
read_map_overview | 解析 .bin 地图文件,并返回房间和结构的概要。 |
read_room | 获取特定房间的详细数据:图块、实体、触发器。 |
get_room_tiles | 以文本形式获取房间的完整图块网格。 |
地图编辑工具
| 工具 | 功能 |
|---|---|
add_entity | 向房间添加一个实体并保存地图。 |
remove_entity | 根据实体 ID 从房间中移除实体。 |
add_trigger | 向房间添加一个触发器并保存地图。 |
remove_trigger | 根据触发器 ID 从房间中移除触发器。 |
set_room_tiles | 设置房间的图块数据。每一行是一串字符('0' = 空气)。 |
add_room | 向地图添加一个新的空房间。 |
remove_room | 从地图中移除一个房间。 |
create_map | 创建一个新的空白 Celeste .bin 地图文件。 |
风格背景工具
| 工具 | 功能 |
|---|---|
list_stylegrounds | 列出地图中的所有风格背景(前景和背景效果)。 |
add_styleground | 向地图添加一个风格背景效果。 |
remove_styleground | 根据风格背景在图层中的索引将其移除。 |
update_styleground | 将属性合并到现有风格背景中,而不替换它。 |
实体 / 触发器目录工具
| 工具 | 功能 |
|---|---|
list_entity_definitions | 列出项目中可用的 Lönn 实体定义。 |
get_entity_definition | 读取 Lönn 实体 Lua 定义并提取其属性。 |
list_trigger_definitions | 列出可用的 Lönn 触发器定义。 |
list_effect_definitions | 列出可用的 Lönn 效果定义。 |
find_missing_definitions | 列出地图中没有任何已安装 Lönn 插件定义的命名空间实体和触发器。 |
audit_plugin_coverage | 比较模组的 C# [CustomEntity] 名称与其 Lönn 插件定义。 |
validate_audio | 根据声音库检查地图引用的每个音频事件。 |
分析工具
| 工具 | 功能 |
|---|---|
analyze_map | 获取地图文件的详细统计信息。 |
visualize_map_layout (extra) | 生成地图中所有房间位置的 ASCII 可视化图。 |
地图预览工具
| 工具 | 功能 |
|---|---|
preview_map_section | 生成地图局部区域的 ASCII 预览,类似 Lönn 小地图。 |
render_map_html | 渲染交互式 HTML 地图预览,支持缩放、平移、搜索和详情面板。 |
程序化生成工具
| 工具 | 功能 |
|---|---|
build_pattern_library (extra) | 扫描本地 .bin 地图,并将房间模式提取到可复用的库中。 |
generate_room_from_pattern (extra) | 使用库中的模式和随机策略生成新房间。 |
validate_room | 检查房间是否存在常见的可玩性问题。 |
ingest_external_map (extra) | 从外部 URL 下载 Celeste 地图并提取房间模式。 |
图像转地图与地形生成工具
| 工具 | 功能 |
|---|---|
generate_map_from_image (extra) | 将颜色映射图像转换为完整、可玩的 Celeste 地图。 |
generate_terrain_map (extra) | 使用 Perlin 噪声和 Voronoi 生物群系生成程序化 Celeste 地图。 |
preview_terrain_biomes (extra) | 预览地形生成的生物群系布局,而不创建地图。 |
地图读取扩展
| 工具 | 功能 |
|---|---|
read_map_metadata | 读取地图的高级元数据,而不列出所有房间内容。 |
search_entities | 按类型和/或位置搜索所有房间(或指定房间)中的实体。 |
search_triggers | 按类型搜索所有房间中的触发器。 |
compare_rooms | 并排比较同一地图中的两个房间。 |
地图编辑扩展
| 工具 | 功能 |
|---|---|
update_entity | 根据 ID 更新现有实体的属性。 |
move_entity | 将实体移动到新位置。 |
update_room | 更新房间级属性(音乐、黑暗、风等)。 |
clone_room | 将现有房间克隆到新名称和位置。 |
batch_add_entities | 一次调用即可向房间添加多个实体。 |
贴花
| 工具 | 功能 |
|---|---|
list_decals | 列出房间中的所有贴花(前景或背景)。 |
add_decal | 向房间添加贴花。 |
remove_decal | 按索引移除贴花。 |
高级分析
| 工具 | 功能 |
|---|---|
analyze_entity_usage (额外) | 分析整个地图中的实体使用情况。 |
analyze_difficulty | 根据危险元素密度、导航辅助设施和图块覆盖范围估算房间或地图的难度。 |
find_entity_references (额外) | 查找整个地图中某种实体类型的所有出现位置。 |
detect_map_patterns (额外) | 检测游戏设计原型(线性、枢纽、收藏品丰富等)。 |
analyze_room_connectivity | 分析房间邻接图,显示孤立房间、死胡同和枢纽。 |
建议
| 工具 | 功能 |
|---|---|
suggest_improvements (额外) | 根据分析结果为房间提出改进建议。 |
compare_maps (额外) | 比较两张地图并显示结构差异。 |
Wiki / 缓存
| 工具 | 功能 |
|---|---|
wiki_save (额外) | 将分析结果或笔记保存到本地 Wiki 缓存。 |
wiki_search (额外) | 按键、内容或标签搜索 Wiki 缓存。 |
wiki_list (额外) | 列出 Wiki 缓存中的所有条目。 |
wiki_get (额外) | 按键获取指定的 Wiki 条目。 |
Mod 项目
| 工具 | 功能 |
|---|---|
get_mod_info | 获取当前 Mod 项目信息。 |
validate_map | 验证整张地图是否存在可玩性问题。 |
目录扩展
| 工具 | 功能 |
|---|---|
get_trigger_definition | 读取 Lönn 触发器定义 .lua 文件的源代码。 |
get_effect_definition | 读取 Lönn 效果定义 .lua 文件的源代码。 |
导入 / 导出
| 工具 | 功能 |
|---|---|
export_room_json | 将房间导出为 JSON 文件,以便外部编辑或共享。 |
import_room_json | 将 JSON 文件中的房间导入地图。 |
差异与修复
| 工具 | 功能 |
|---|---|
summarize_map_diff (额外) | 创建地图的结构快照或比较结构快照。 |
batch_validate_and_fix | 验证地图中的所有房间,并可选择自动修复问题。 |
房间设置
| 工具 | 功能 |
|---|---|
get_room_settings | 获取房间的所有可编辑设置(音乐、物理、风、镜头、标志)。 |
update_room_settings | 通过合并 JSON 对象更新房间设置(音乐、物理、风、镜头、标志)。 |
rename_room | 重命名地图中的房间。 |
move_room | 将房间移动到新的世界坐标位置。 |
resize_room | 调整房间大小(对齐到 8 像素网格,并保留图块数据)。 |
地图元数据与依赖项设置
| 工具 | 功能 |
|---|---|
get_map_metadata | 读取地图级元数据块(Everest/celeste.yaml 元数据设置)。 |
set_map_metadata | 设置地图级元数据属性(Everest 元数据块)。 |
replace_audio_event | 查找并替换地图中任意位置的 FMOD 音频事件路径。 |
get_map_dependencies | 从地图的 everest.yaml 或 meta 节点读取 Mod 依赖项列表。 |
set_map_dependencies | 写入或更新地图 everest.yaml 中的 Mod 依赖项列表。 |
ML 资源分析
| 工具 | 功能 |
|---|---|
analyze_map_assets (额外) | 使用 Maddie480 图形转储对地图资源进行 ML 风格的分析。 |
JSON 往返与创作
| 工具 | 功能说明 |
|---|---|
map_to_json | 将 .bin 地图转换为带类型的 JSON,再转换回去后可与原文件逐字节一致。 |
json_to_map | 将带类型的 JSON(由 map_to_json 生成,也可以经过编辑)转换回 .bin 地图。 |
check_authoring_json | 在没有地图的情况下解析创作 JSON:显示每个对象,并根据 Lönn 定义填入默认值,同时标记未知名称。 |
merge_json_into_map | 将创作 JSON 中的实体、触发器和房间添加到现有地图。 |
run_author_script | 运行 JavaScript 创作脚本(js/ 包,lucid-dream 风格)并使用其输出。 |
实时游戏连接
| 工具 | 功能说明 |
|---|---|
game_status | 查看正在运行的游戏状态:地图 SID、关卡侧、房间和玩家位置。 |
game_reload_map | 让正在运行的游戏重新读取磁盘上已编辑的地图。 |
game_teleport | 在正在运行的游戏中加载地图的某个房间(启动新的调试会话)。 |
game_play_tas | 从房间的出生点开始播放 CelesteTAS 输入,并报告玩家最终位置。 |
game_log | 查看游戏 log.txt 的最新内容:错误、警告和关卡加载记录。 |
安全:副本、提交、备份、差异
| 工具 | 功能说明 |
|---|---|
map_copy | 将地图复制为工作副本,确保编辑不会触及原文件。默认目标路径:Maps//wip/.copy.bin。 |
map_commit | 将工作副本应用到实际地图:可应用整个文件,也可仅应用列出的房间。试运行会先显示差异。 |
map_backups | 按时间戳列出地图的备份,最新的排在最前。 |
map_restore | 从某个备份恢复地图(会先备份当前文件)。 |
map_diff | 对两张地图进行语义差异比较:房间、几何结构、前景/背景图块、实体、触发器、贴花、风格背景、元数据。 |
资源
| 工具 | 功能说明 |
|---|---|
check_assets | 检查地图是否仅使用已存在的资源:具有 Lönn 定义的实体/触发器名称、贴花和视差纹理。 |
check_sprites_xml | 检查 Sprites.xml:确保文件可解析、ID 唯一,且每个 Anim/Loop 在图集内都有帧。如果精灵未在游戏中显示,请先运行此检查。 |
编辑器
| 工具 | 功能说明 |
|---|---|
editor_open | 在 Lönn(或 Rysy)中打开地图,可选打开指定房间。在编辑器关闭前,MCP 会拒绝对该地图进行写入。 |
editor_wait | 等待用户在编辑器中保存(或关闭编辑器),然后报告发生的更改。再次调用可继续等待。 |
editor_status | 列出此服务的编辑器会话以及其他正在运行的 Lönn。 |
editor_close | 关闭编辑器会话。如果不使用强制模式,编辑器可能会询问是否处理未保存的更改,并保持打开状态。 |
Sprite Fusion
| 工具 | 功能说明 |
|---|---|
sf_make_tileset | 为 Sprite Fusion 写入 Celeste 灰盒图块集(PNG、图例 JSON、README)。 |
sf_import | 将 Sprite Fusion JSON 导出文件(map.zip)作为 Celeste 房间导入:包括实心/背景图块和灰盒实体。 |
Summer Engine
| 工具 | 功能说明 |
|---|---|
summer_init | 创建或刷新 Summer Engine 灰盒项目(带碰撞的图块集、房间模板、桥接脚本)。 |
summer_open | 在 Summer Engine 中打开灰盒项目,可选打开指定房间场景。 |
summer_rooms | 列出 Summer 灰盒项目中的房间场景。 |
summer_export_room | 将 Summer 房间场景转换为 Celeste 房间(新建,或使用 replace=true 替换)。与 sf_import 使用相同的检查和安全写入机制。 |
summer_import_room | 将 Celeste 房间复制到 Summer 项目中作为场景(前景/背景图块、作为图块的灰盒实体,其他对象作为标记)。 |
summer_from_sprite_fusion | 将 Sprite Fusion 导出文件(map.zip)转换为 Summer 房间场景,以便先在 Summer 中完善,再进行导出。 |
共享 Pcg 核心
| 工具 | 功能说明 |
|---|---|
pcg_generate_room | 使用共享的 C# PCG 核心生成灰盒房间并写入地图(先进行试运行)。 |
已选关卡
| 工具 | 功能说明 |
|---|---|
selecte_generate | 使用 seleCte 生成完整关卡(房间从原版地图的马尔可夫模型中采样),用 Julia 编码并验证 .bin。 |
安装与设置
安装 Python 包
PyPI 包 loenn-mcp 自 5.2.0 以来就没有更新过,因此执行 pip install loenn-mcp 会安装旧版本。
请改为安装最新发布版本中附带的 wheel:
pip install https://github.com/Magedeline/loenn-mcp/releases/download/v7.2.0/loenn_mcp-7.2.0-py3-none-any.whl
或从源代码安装:
git clone https://github.com/Magedeline/loenn-mcp
cd loenn-mcp
pip install -e .
安装 MCPB 捆绑包(无需 PyPI,无需设置 Python)
每个发布版本都会附带 loenn-mcp-<version>.mcpb,这是适用于支持
MCPB 的宿主的捆绑包,例如 Claude Desktop。它使用 uv 运行时:宿主会对捆绑包运行
uv run,而 uv 会自行安装 Python 和依赖项,因此机器上只需安装
uv 即可。从发布页面下载捆绑包,在宿主中打开,并将
“Celeste mod folder”设置指向你的 mod。python tools/build_mcpb.py 可从代码检出构建相同的捆绑包
(源代码位于 mcpb/),而 server.json 会将其列入 MCP Registry,名称为 io.github.Magedeline/loenn-mcp。
连接到 Claude Desktop
将以下内容添加到 claude_desktop_config.json:
{
"mcpServers": {
"loenn-mcp": {
"command": "python",
"args": ["-m", "loenn_mcp.server"],
"env": {
"LOENN_MCP_WORKSPACE": "/absolute/path/to/your/mod"
}
}
}
}
连接到 GitHub Copilot(VS Code)
将以下内容添加到 .vscode/mcp.json:
{
"servers": {
"loenn-mcp": {
"type": "stdio",
"command": "python",
"args": ["-m", "loenn_mcp.server"],
"env": {
"LOENN_MCP_WORKSPACE": "${workspaceFolder}"
}
}
}
}
在本地预览地图
python -m loenn_mcp.preview_map Maps/01_City_A.bin
python -m loenn_mcp.preview_map Maps/01_City_A.bin g- # filter by prefix
交互式 HTML 预览支持缩放、平移、房间详情、搜索和带键盘快捷键的小地图。
JSON 往返与创作
地图可以离开二进制格式再返回,且不会丢失任何字节;也可以手动或用 JavaScript 编写新内容,并将其合并到现有地图中。 这些操作在运行时都不需要 Ruby 或 Node;只有运行 JS 创作脚本时才需要 Node。
类型化 JSON:map_to_json / json_to_map
map_to_json("Maps/MyMod/1-City.bin") → Export/1-City.json
json_to_map("Export/1-City.json", "Maps/MyMod/1-City-copy.bin")
每个属性都会保留其二进制类型,因此往返转换后逐字节一致:
{
"format": "celeste-map-json", "version": 1,
"header": "CELESTE MAP", "package": "1-City",
"source": {"file": "1-City.bin", "sha256": "…", "tree_sha256": "…"},
"lookup": ["Map", "levels", "level", "…"],
"root": {"name": "Map", "children": [
{"name": "levels", "children": [
{"name": "level", "attrs": {
"name": ["lookup", "lvl_a-00"],
"x": ["i16", -40], "width": ["i32", 320], "dark": ["bool", false],
"music": ["string", "event:/music/lvl1/main"], "alpha": ["f32", 0.3]},
"children": [{"name": "solids", "attrs": {"innerText": ["rle", "0000…"]}}]}]}]}
}
- 类型:
bool、u8、i16、i32、f32、lookup(字符串表字符串)、string(普通字符串)、rle(游程编码的图块数据,以解码形式显示)。 - 值就是文件中的值。 名为
lvl_a-00的房间仍会保持为lvl_a-00。 lookup是文件中按原顺序排列的字符串表;编辑时只会向其追加内容。 规范化写入器无法复现的文件特性(重复的表项、 非常规的 RLE 拆分)会作为可选附加信息保留([type, value, {"key_index": 12}])。- 拒绝写入。 如果某个值不符合其类型(
["u8", 300])、未编辑的转储无法逐字节复现源文件 (通过source.sha256检查),或输出内容读回后与原地图不一致,json_to_map都不会写入任何内容。写入是原子性的(临时文件 + 替换),并会保留带时间戳的备份(见安全性)。 - 手写文档可以省略
lookup/source,并直接提供裸值 ("x": 8);这些值会采用 Celeste 自身打包器选用的类型。
创作 JSON
一种更宽松的自创内容格式。只需提供名称和位置:
{"rooms": [
{"room": "a-05",
"entities": [{"name": "strawberry", "x": 120, "y": 64},
{"name": "CEL/GreenBerry", "x": 200, "y": 40}],
"triggers": [{"name": "CEL/PinkPlatBerryCollectTrigger", "x": 0, "y": 0,
"width": 16, "height": 184}]},
{"room": "a-99", "x": 0, "y": 2400, "width": 320, "height": 184,
"solids": "1111…\n1000…", "attrs": {"dark": true},
"entities": [{"name": "player", "x": 24, "y": 160}]}
]}
- 默认值来自 Lönn 插件定义:你的 mod 中的
Loenn/、其他已安装的 mod(当工作区位于Celeste/Mods中时),然后是原版 Lönn。 上面的strawberry会获得winged、moon、checkpointID和order。"placement": "normal_winged"会选用另一个放置项的默认值;其他任何键(位于顶层或"data"下)都会设置一个属性;"nodes": [[x, y], …]会添加节点。 - 未知名称会被标记(拼写错误、被列为实体的触发器、未安装的辅助项)。
check_authoring_json会在没有地图的情况下显示解析后的结果。 - 只会向现有房间添加内容。 只有在创建房间时(提供
x、y、width、height),才会接受房间属性和图块。 - 房间名称无论带不带
lvl_前缀都可以匹配。
合并:merge_json_into_map
merge_json_into_map("Maps/MyMod/1-City.bin", "plan.json") # dry run + preview
merge_json_into_map("Maps/MyMod/1-City.bin", "plan.json", dry_run=false) # write
- 默认试运行。 它会输出逐房间差异,并生成 HTML 预览,为每个新增对象标上圆圈(洋红色;检查失败时为红色)。
- ID 在整张地图中唯一:新 ID 从所有房间中最高 ID 之后开始;如果显式指定的
"id"已被使用,则会拒绝。 - 放置检查会针对每个新增对象进行:对象必须位于房间内,不能位于实心瓦片内,也不能位于与所有房间边缘和出生点隔绝的气穴中。现有房间验证器(
validate_room、validate_map)会在合并前后运行,并报告合并引入的任何问题。存在问题时会拒绝写入,除非设置allow_problems=true;未知名称需要设置allow_unknown=true。 - 仅添加内容。 输出字节会被重新读取并与原始内容比较;如果任何已有内容发生变化,就不会写入任何内容。
使用 JavaScript 编写地图
js/ 是一个无依赖的 Node 包,其 API 遵循
lucid-dream(参见
THIRD_PARTY_NOTICES.md)。它会生成用于创作的 JSON;所有 .bin 写入操作均由 Python 服务完成。
// add-berries.js
const { Plan, Room, Entity, Trigger, Tiles, line } = require('loenn-mcp-author'); // or require('./js')
const plan = new Plan();
plan.room('a-05').add(Entity.Strawberry({ x: 120, y: 64 })); // existing room
for (const [x, y] of line(64, 96, 192, 96, 3)) plan.room('a-06').add(Entity.Strawberry({ x, y }));
plan.room('l-07').add(Trigger('CEL/PinkPlatBerryCollectTrigger', { x: 1700, y: 300, width: 56, height: 104 }));
// a new room, lucid-dream style: pixel position, size in tiles, tiles as text
plan.addRoom(new Room([0, 2400], { name: 'a-99', size: [40, 23], fgTiles: new Tiles(`...`),
entities: [Entity.Player({ x: 24, y: 160 })] }));
module.exports = plan; // or: module.exports = async (api) => plan; or: plan.emit();
Entity.Strawberry(...)会将属性名转换为驼峰式并作为放置名称 (strawberry);带命名空间的名称使用调用形式,例如Entity('CEL/GreenBerry', {...})。- 通过服务运行(试运行并生成预览):
run_author_script("add-berries.js", map_path="Maps/MyMod/1-City.bin")。 - 或在 shell 中运行:
node js/bin/loenn-author.js add-berries.js --out plan.json, 或loenn-json author add-berries.js --map Maps/MyMod/1-City.bin [--write]。 - 测试:
node js/test/test.js。示例:js/examples/。
JSON 驱动的预览
render_map_html 既可接收类型化 JSON 转储,也可接收 .bin;还可接收 overlay
(创作 JSON),仅在内存中合并并高亮显示。这是基于现有渲染器构建的查看器,思路来自
maddievision/celestial。
loenn-json CLI
loenn-json map2json Maps/MyMod/1-City.bin -o city.json
loenn-json json2map city.json Maps/MyMod/1-City.bin --overwrite
loenn-json --mod . merge Maps/MyMod/1-City.bin plan.json # dry run
loenn-json --mod . merge Maps/MyMod/1-City.bin plan.json --write
loenn-json --mod . author add-berries.js --map Maps/MyMod/1-City.bin
更多示例:examples/authoring/。
pcgscene CLI
这是一款以批处理为先的命令行工具,可在 MCP 客户端之外扫描和修复地图——安装一次,即可用于脚本、提交前钩子或 CI。所有会处理 .bin 文件的命令,都会通过与 MCP 服务相同的原子化、备份和往返验证流程写入,因此即使运行出错,也绝不会损坏地图。
pip install loenn-mcp
pcgscene scan MyMap.bin # score every room + map connectivity
pcgscene validate MyMap.bin # in-game readiness checklist (exit 0/1)
pcgscene fix MyMap.bin --dry-run # preview safe auto-repairs
pcgscene fix MyMap.bin # apply them (backed up first)
pcgscene diff before.bin after.bin # what changed between two maps
| 命令 | 功能 |
|---|---|
scan | 为每个房间评分(趣味性、难度、出口连通性、出生点是否存在、公平性门槛),并评估从起始房间出发的整张地图可达性。 |
score | 查看单个房间的详细报告(--room NAME)。 |
validate | 游戏内就绪情况检查清单——包括名称错误、出生点缺失、出口封闭、房间无法到达等问题,并返回适用于 CI 的退出码。 |
fix | 安全自动修复:添加缺失的出生点、清理错误的房间名称、将 strawberry{golden} 转换为真正的 goldenBerry 实体。支持 --dry-run 和 --only spawns,names,berries。 |
diff | 比较两张地图之间的房间、实体和瓦片变化。 |
generate | 基于预设生成(quick / simple_fair / explore / challenge),并支持可复现的 --seed。需要完整版/Pro 版本(loenn-mcp-delta)中的 pcg_helper 模块——此版本的 generate 会优雅地拒绝执行并说明原因。 |
每个命令都接受 --json(以及 --out FILE)以输出机器可读内容,因此编辑器插件或 CI 步骤可以直接处理报告。
程序化生成
生成策略
| 策略 | 说明 |
|---|---|
balanced | 探索与挑战兼顾(默认) |
exploration | 开阔空间、轻松的平台跳跃、较少的危险 |
challenge | 密集的瓦片、众多危险、紧凑的跳跃 |
speedrun | 线性路线、最少的平台、快速流畅 |
模型配置
| 配置 | 行为 | 用例 |
|---|---|---|
creative | 每次调用使用随机种子 | 最大多样性 |
deterministic | 根据策略生成稳定的种子 | 可复现的布局 |
architect | 使用随机种子 | 强调形状/连通性 |
快速入门示例
# 1. Build pattern library from existing maps
build_pattern_library()
# 2. Create a new map
create_map("Maps/PCG/Generated.bin", "PCG/Generated")
# 3. Generate rooms
generate_room_from_pattern(
map_path="Maps/PCG/Generated.bin",
room_name="a-01",
strategy="exploration",
seed=42,
model_profile="deterministic"
)
# 4. Validate and preview
validate_room("Maps/PCG/Generated.bin", "a-01")
render_map_html("Maps/PCG/Generated.bin")
种子生成
使用 seed=<int> + model_profile="deterministic" 以获得可复现的输出:
# Both calls produce identical rooms
generate_room_from_pattern(..., strategy="challenge", seed=1234, model_profile="deterministic")
generate_room_from_pattern(..., strategy="challenge", seed=1234, model_profile="deterministic")
GameBanana 集成
从社区模组中下载并提取模式:
# Dry-run (preview only)
ingest_external_map(
source_url="https://gamebanana.com/mods/53774",
attribution="Spring Collab 2020",
confirm_download=False
)
# Download and extract
ingest_external_map(
source_url="https://gamebanana.com/mods/53774",
attribution="Spring Collab 2020 (various authors)",
confirm_download=True,
tags="community,expert"
)
模式会连同署名一起保存到 PCG/Datasets/。请务必确认模组许可证允许衍生使用。
图像转地图
将颜色映射图像直接转换为可玩的 Celeste 地图。每个像素对应一个 8×8 图块。
默认颜色映射
| 颜色 | 十六进制 | 映射为 |
|---|---|---|
| 黑色 | #000000 | 实心图块 |
| 白色 | #FFFFFF | 空气(空) |
| 红色 | #FF0000 | 尖刺危险物 |
| 绿色 | #00FF00 | 玩家出生点 |
| 蓝色 | #0000FF | 可跳穿平台 |
| 黄色 | #FFFF00 | 草莓 |
| 品红色 | #FF00FF | 弹簧 |
| 青色 | #00FFFF | 补充水晶 |
| 橙色 | #FF8000 | 崩塌方块 |
| 灰色 | #808080 | 背景实心块 |
用法
# Basic conversion
generate_map_from_image(image_path="Assets/my_level.png")
# Custom colors and scale
generate_map_from_image(
image_path="Assets/large_map.png",
output_path="Maps/Custom/level.bin",
scale=4, # 4×4 pixel blocks → 1 tile
color_map_json='{"#FF0000":"solid","#00FF00":"spawn"}'
)
需要 Pillow:pip install loenn-mcp[image]
带种子的地形生成
使用 Perlin 噪声和 Voronoi 生物群系生成完整地图。灵感来自 AliShazly/map-generator。
生物群系
| 生物群系 | 地形 |
|---|---|
mountain | 密集图块、紧凑平台、尖刺 |
forest | 中等密度、许多平台、弹簧 |
plains | 开阔空间、平缓平台、收集品 |
lake | 稀疏图块、可跳穿平台、补充物 |
cave | 封闭区域、崩塌方块、黑暗房间 |
summit | 稀疏平台、风力效果 |
快速示例
# Generate a 4×3 map with seed 42
generate_terrain_map(seed=42, difficulty=3, width_rooms=4, height_rooms=3)
# Preview biome layout before generating
preview_terrain_biomes(seed=42, width_rooms=4, height_rooms=3)
# Output:
# [P] [^] [^] [F]
# [~] [P] [^] [M]
# [C] [~] [P] [F]
参数
| 参数 | 默认值 | 描述 |
|---|---|---|
seed | -1(随机) | 用于生成可复现输出的整数种子 |
width_rooms | 4 | 水平方向的房间数 |
height_rooms | 3 | 垂直方向的房间数 |
frequency | 8.0 | Perlin 噪声频率(越低越平滑) |
voronoi_points | 12 | 生物群系区域中心点的数量 |
biome_set | all | 以逗号分隔的生物群系名称 |
difficulty | 3 | 危险物密度等级,范围为 1-5 |
分析与洞察
用于地图设计、难度和模式的高级分析工具。
快速示例
# Analyze difficulty
analyze_difficulty(map_path="Maps/MyMod/1-City.bin")
# Detect gameplay patterns
detect_map_patterns(map_path="Maps/MyMod/1-City.bin")
# → "standard-level (7-15 rooms)", "linear-horizontal", "checkpointed"
# Get room suggestions
suggest_improvements(map_path="Maps/MyMod/1-City.bin", room_name="lvl_a-01")
# Track map evolution
summarize_map_diff(map_path="Maps/MyMod/1-City.bin") # save snapshot
# ... edit map ...
summarize_map_diff(map_path="Maps/MyMod/1-City.bin") # show diff
# Cache results for instant re-use
wiki_save(key="city_difficulty", content="Avg 4.2/10, 3 hard rooms", tags="analysis")
wiki_search(query="difficulty")
# Batch validation
batch_validate_and_fix(map_path="Maps/MyMod/1-City.bin", auto_fix=True)
# Search and clone
search_entities(map_path="Maps/MyMod/1-City.bin", entity_type="strawberry")
clone_room(map_path="Maps/MyMod/1-City.bin", source_room="lvl_a-01", new_name="lvl_a-01-copy")
# Export/import rooms
export_room_json(map_path="Maps/MyMod/1-City.bin", room_name="lvl_a-01")
import_room_json(map_path="Maps/MyMod/2-Resort.bin", json_path="Export/lvl_a-01.json")
Wiki 缓存
分析结果会以 JSON 文件形式保存在 .loenn_mcp_wiki/ 中,以便在不同会话间即时重复使用。
不含 AI(v7.0.0)
从 v7.0.0 起,loenn-mcp 中的每个工具都是确定性的程序化工具——
使用马尔可夫链、波函数坍缩、噪声和 BFS/图分析。服务不会调用任何 AI/大模型 API,无需 API 密钥,也不包含 AI 模型。此前的 ai_analyze_map / ai_describe_room / ai_suggest_entities 工具和 anthropic 依赖项均已移除。
**免责声明:**本项目在开发过程中使用了 Claude(Anthropic)作为编码工具提供的协助,所依据的算法发表于 Robinet 等人所著的 “Towards a Celeste AI Framework”(FDG '25,DOI 10.1145/3723498.3723796)。所有输出均已在 Lönn 和游戏内经过人工测试。
配置
| 变量 | 默认值 | 描述 |
|---|---|---|
LOENN_MCP_WORKSPACE | 当前目录 | Celeste Mod 项目的根目录。所有地图路径都相对于此目录。禁止路径遍历。 |
LOENN_MCP_LOENN | (随附的表) | Lönn 安装目录(包含 Lönn.exe 的文件夹,或其 src/),用于读取原版实体/触发器默认值,而非使用 loenn_mcp/data/vanilla_defs.json |
LOENN_MCP_NODE | PATH 中的 node | 用于 run_author_script 的 Node.js 可执行文件 |
LOENN_MCP_AUTHOR_CLI | 随附的 js/bin/loenn-author.js | 替代创作 CLI |
LOENN_MCP_STATE_DIR | %LOCALAPPDATA%\loenn-mcp | 备份、隔离的 Lönn 存储、Sprite Fusion 瓦片集 |
LOENN_MCP_PROTECT | (无) | 以 ; 分隔的地图 glob;只有 map_commit 可以更改这些地图 |
LOENN_MCP_TOOLS | core | all 还会列出额外的分析工具和旧版生成器工具 |
LOENN_MCP_LOENN_STORAGE | isolated | editor_open 的默认 Lönn 存储位置(isolated 或 user) |
LOENN_EXE | Olympus 的 Lönn.exe | Lönn 可执行文件 |
RYSY_EXE | Documents\GitHub\Rysy 下最新的 Rysy.exe | Rysy 可执行文件 |
SUMMER_EXE | %LOCALAPPDATA%\SummerEngine\current\Summer.exe | Summer Engine 可执行文件 |
LOENN_MCP_SUMMER_PROJECT | Documents\CEL-Graybox | Summer 灰盒项目 |
CELPCG_CLI | 已构建的 csharp/CelPcg.Cli | 使用其他 celpcg 构建版本(exe 或 dll) |
SELECTE_DIR | 此仓库旁的 seleCte,否则为 ~/seleCte | 用于 selecte_generate 的 seleCte 克隆目录 |
UV_EXE | PATH 中的 uv | 运行 seleCte 生成器的 uv 可执行文件 |
JULIA_EXE | PATH 中的 julia | 运行 seleCte 编码器的 Julia 1.11+ 可执行文件 |
LOENN_MCP_DEBUGRC | http://localhost:32270 | game_* 工具使用的 Everest 调试服务 |
架构
核心模块
celeste_bin.py — 独立的 .bin 解析器
- 纯 Python(无需 Everest/Lönn)
- 无损读写:未经编辑的地图写回后逐字节一致(保留字符串表顺序、值类型和 RLE 数据),编辑内容只会追加到字符串表
- 支持全部 7 种值类型:bool、uint8、int16、int32、float32、查找字符串、原始字符串、RLE 编码字符串
- 递归元素树与 Lönn/Maple 格式匹配
map_json.py — .bin 地图的类型化 JSON
- 每个值都会保留其类型;未经编辑的转储可转换回逐字节一致的内容(已在导出时验证)
- 拒绝无法往返还原的写入;通过
celeste_bin原子写入
lua_defs.py — 无需运行 Lua 的 Lönn 插件定义
- 对插件文件进行词法分析并评估字面量表(放置项、字段类型、节点限制)
- 收录本 Mod、自行安装的其他 Mod 以及原版的定义(
data/vanilla_defs.json,由 Lönn 通过tools/gen_vanilla_defs.py生成)
authoring.py — 创作 JSON 与合并
- 填充默认值、标记未知名称、分配地图范围内的 ID、检查放置项
- 对重新读取后的输出字节进行仅增量验证
js/ — loenn-mcp-author,JavaScript 创作包(Node,无依赖)
pcg.py — 程序化生成
- 从房间中提取模式(大小、实体密度、图块主题、玩法标签)
- 带去重功能的 JSON 模式库
- 基于策略生成(平衡、探索、挑战、速通)
- 使用带种子的随机数,确保输出可复现
- 模型配置(确定性、创意、建筑师)
image_map.py — 图像转地图
- 颜色到角色的映射(可配置调色板)
- 自动拆分房间
- 根据像素颜色放置实体
- 支持缩放(缩小)
- 模糊颜色匹配
terrain_gen.py — 带种子的地形生成
- 使用分形倍频的 Perlin 噪声
- Voronoi 生物群系划分
- 完全基于种子(相同种子 = 相同输出)
- 难度缩放(1-5)
- 感知生物群系的实体
gdep_tools.py — 游戏分析
- Wiki 缓存(
.loenn_mcp_wiki/) - 模式检测(线性、枢纽、收藏品丰富等)
- 难度分析(1-10 级)
- 房间连通图
- 使用快照对比地图差异
- 批量验证与自动修复
- 可执行的建议
server.py — MCP 服务
- 基于 FastMCP 构建
- 路径遍历防护
- 地图原子写入
- 明确的下载确认
safety.py — 写入策略:防护措施、带时间戳的备份存储、每次调用的写入报告
mapdiff.py — 两张地图的语义差异对比(房间、图块、按 ID 区分的实体、贴花、风格地面、元数据)
editors/ — 带保存监视功能的 EditorAdapter;LoennAdapter(启动、预选房间、隔离存储)、RysyAdapter
assets.py — 纹理索引(Mod、已安装的 Mod、原版图集 .meta)、Sprites.xml 和地图资源检查
summer.py — Summer Engine 桥接:项目设置、无头编辑器脚本、场景转储为房间及反向转换
pcg_core.py — 构建并调用 celpcg CLI,将其房间转换为可导入的格式
selecte.py — seleCte 桥接:查找克隆仓库,运行其生成器(uv)和 Julia 编码器,汇总日志,验证 .bin
sprite_fusion.py — 灰盒图块集、Sprite Fusion 导出读取器、像素匹配、转换为房间
cli.py — pcgscene 命令行工具
- 扫描 / 评分 / 验证 / 修复 / 差异对比,均支持
--json - 共用
celeste_bin的原子写入路径——无需另设可能产生偏差的写入逻辑
要求
- Python 3.9+
fastmcp >= 3.0.0Pillow >= 9.0(可选:用于图像转地图,以及 Sprite Fusion 导入的像素匹配)- Node.js 14+(可选,仅用于 JavaScript 创作脚本)
安装所有可选功能:
pip install loenn-mcp[image]
无需安装 Celeste。
许可证
MIT — 详见 LICENSE。lucid-dream、Lönn 和 maddievision/celestial 的致谢:THIRD_PARTY_NOTICES.md。
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。