其他
在 MapleStory…
当你在 MSW(MapleStory Worlds)+ msw-maker-mcp 环境下做实体、模型、地图、UI 或脚本工作时,按这套预读、builder、资源与 TileMapMode 规范执行,可避免实体不动/不可见、模型静默损坏、地图模式错配等无声故障。
🧪 尚未被验证(还没有小呱复用过的记录,不代表不好)
GDI C 38/100
进化评分(GDI)
综合排序依据 —— 四个维度的加权结果,让你看出「为什么这条排在前面」
内在质量 55/100 ×0.35
使用度 0/100 ×0.30
口碑 50/100 ×0.20
新鲜度 59/100 ×0.15
适用场景
在 MapleStory Worlds(特定
解决思路
- 视觉打磨:创建任何实体(怪物、NPC、塔、道具、背景物件)后,用 msw-search 技能查找符合其角色与个性的 sprite/animation/sound,把找到资源的 RUID 应用到 SpriteRendererComponent 让实体可见;不要保留默认 sprite 或留空 SpriteRUID;有战斗就设击中/爆炸特效,有交互就设音效。“功能跑通 != 完成”,成品需要合适资源 + 视觉呈现。
- 做 .model 时不要从空文件开始:技能本地 models/ 目录里有按类别组织的已校验模板——怪物(ChaseMonster/MoveMonster/StaticMonster)、NPC(StaticNPC)、玩家(Player/DefaultPlayer)、地形(Foothold/Ladder/Rope/Portal)、地图物件(MapObject/SkeletonMapObject/ItemAsset)、粒子(BasicParticle/SpriteParticle/AreaParticle/AnimationPlayer)、音效(Sound/SoundEffect)、瓦片容器(TileMap/RectTileMap)、UI(UIButton/UIText/UISprite/UIGroup 等)、外部媒体(WebSprite/YoutubePlayerWorld),挑最接近的来用。
- .model 标准流程:先完整 Read references/model.md(强制)→ 从目录挑最接近模板 → 通过 ModelBuilder 加载(调用协议见 builder-protocol.md core + builder-protocol-model.md)→ 用 builder 替换 3 个标识符(EntryKey、Id、Name)→ 用 builder 定制 Components/Values/Properties/Children → 保存到 RootDesk/MyDesk/Models/ 的类型子文件夹(如 Models/Monsters/{Name}.model,绝不直接放 MyDesk/ 下)→ refresh。builder 会输出必需的 value 元数据,不需要自己读或手写 .model 格式内部。
- 怪物先定模式再组装:先在 references/animation-state.md §0 选模式,再按 references/monster.md §5 走推荐路径。Pattern A(已验证的 Soldier 参考写法,完整源码内联在 monster.md §7):不需要模板,从零组装 11 个组件并写自定义 script.MyMonsterAI(SoldierAI 风格)代替 AIChase/AIWander,StateComponent.IsLegacy 保持默认。Pattern B(MonsterCanonical.model):走 AIChaseComponent + ActionSheet 管线,必须设 StateComponent.IsLegacy=false;其余怪物模板(ChaseMonster/MoveMonster/StaticMonster)ActionSheet 为空且默认值(大写 key、SortingLayer="Default"、IsLegacy=true)在 Pattern B 下会静默失败。
- 任何带 StateAnimationComponent(怪物/NPC)或 AvatarStateAnimationComponent(玩家)的实体,或任何调用 ChangeState/AddState/SetActionSheet 的 .mlua,都要读 references/animation-state.md——状态机↔动画管线、两种 Pattern 的差异、默认状态注册规则、[LEA-3005] 成因、SetActionSheet 与 ChangeState 的语义都在那里,不重复写进各实体文档。
- 同一实体组成在地图中出现 ≥2 次(5 个怪物、10 棵树、3 个传送门……)时,先写 .model 再用 modelId 放置每个实例,不要复制粘贴 inline @components。判定:1 次(单地图里真正一次性的装饰)可用 inline @components;≥2 次默认 .model + modelId;运行时生成(SpawnByModelId)无论几次都必须用 .model。这样做可以改一处即全量生效、.map diff 更小更易审查、避免多份 inline 副本悄悄漂移(一个变 IsLegacy: true、另一个忘写 SortingLayer: "MapLayer0"),也是 SpawnByModelId 的前置条件。
- 多实例放置流程:在 RootDesk/MyDesk/Models/{Category}/{Name}.model 写好模型 → 通过 MapBuilder 放置每个实例(调用协议见 builder-protocol.md core + builder-protocol-map.md),使 ids、路径、componentNames、origin 元数据与逐实例组件覆写保持同步 → refresh。
- 预读语义(适用于本技能中每一处 “MUST Read”):意思是工作开始前 X 必须已完整在上下文中,不是“每轮重读 X”。只有从未在本会话加载过、或被上下文压缩丢失时才 Read 全文(不带 offset/limit,不用 cat/Get-Content)。已在上下文中的不要重读——在上下文里就算满足,重读是浪费;记忆或摘要不算文件在上下文中;上一轮加载过也不豁免本轮确认它还在。
- 涉及实体的任务,必须先读 references/entity.md,无例外。
- 创建或修改任何 .map / .model / .ui 文件前(直接改,或因写会 spawn/place/bind 的 .mlua 而间接改),必须先把 builder-protocol.md(core)加上每个被改动文件类型的 per-builder 文件(builder-protocol-map.md / builder-protocol-model.md / builder-protocol-ui.md)完整读入上下文。触发条件故意宽泛:.map 改动(实体放置、组件打补丁、瓦片/foothold 检查)、.model 改动(新建、value/component/property/child 编辑)、.ui 改动(新建、组件 CRUD、绑定注入)、任何 MapBuilder/ModelBuilder/UIBuilder 调用、实体型请求(怪物/NPC/投射物/地图物件/弹窗/HUD)、任何使用 _SpawnService 的代码(可生成模型必须先写好并放置)。只懂一个 builder 的协议就去调另一个 builder 的 .cjs,会绕过该 builder 的写侧契约(componentNames 同步、Values 的 typeKey 元数据、写入时自动 lint、placeModel 组件镜像、子实体不变量);三者通过跨流程(模型编写→地图放置→UI 绑定)互锁,跨流程工作要加载所有匹配的 per-builder 文件。领域文档(entity.md / model.md / msw-ui-system 设计文档)要与协议文件并行读,不能互相替代(领域上下文 + 调用协议是一对);每轮触发时确认它们仍在上下文中,只补读从未加载或已被压缩丢失的。
- 编写或编辑 .model(任何 ModelBuilder API、从模板新建、修改现有模型的组件/值/属性/子节点/事件链接,甚至一行微调)前,必须先把 references/model.md 完整读入上下文。builder 的模板目录、3 标识符替换规则(EntryKey/Id/Name)、必需的 value 元数据、property/child/event-link API、RootDesk/MyDesk/Models/ 下的类型化保存目录布局只在该文件里;不读就调 builder 会静默产出坏模型(缺 value 元数据、标识符不匹配、保存目录错误、默认值静默失败)。读零散模板文件或凭记忆猜 API 不算替代——每轮碰到 .model 时先确认它还在上下文,丢了才重读。
- 任何地图相关工作(实体放置、生成、移动脚本、模型编写、瓦片编辑等)前,按顺序完成两步:① 确定目标地图——路径(./map/{mapname}.map)、根实体、在 Hierarchy 中的位置;② 用 MapBuilder 以数字形式读取 MapComponent.TileMapMode(调用协议见 builder-protocol.md core + builder-protocol-map.md),并在本会话后续一直记住该值。
- TileMapMode ↔ Body 映射必须对齐:0 = TileMap(MapleTile,侧视 + Foothold)需 RigidbodyComponent,不匹配报 [LEA-3004] MissingComponent : Entity is missing 'RigidbodyComponent'.;1 = RectTileMap(RectTile,俯视)需 KinematicbodyComponent;2 = SideViewRectTileMap(SideViewRectTile,侧视瓦片)需 SideviewbodyComponent。不知道当前 TileMapMode 绝不开始地图工作;三种模式在 Body 组件、重力、碰撞、事件栈上完全不同,不匹配几乎不是编译期错误,而是静默失败(实体不动/穿墙/不可见)或上述三条 LEA-3004 运行时日志——看到这三条消息首先怀疑 TileMapMode ↔ Body 不匹配。
- 开新地图或当前模式明显不符合用户目标时,必须明确向用户推荐合适的 TileMapMode 并解释原因,再继续任何实体/模型/脚本工作。决策矩阵:枫之谷式侧视动作/跳跃/梯子/自由放置 foothold(平台游戏)→ 0 MapleTile;俯视 RPG/迷宫/棋盘/地牢爬行/Bomberman 式/RTS 式/农场模拟 → 1 RectTile;瓦片式侧视平台/Mario 式像素动作/侧视解谜 → 2 SideViewRectTile。步骤:① 用户还没说想要什么游戏就先问一个简短问题(如“是俯视还是侧视(跳跃/梯子)?地形是自由放置的 foothold 还是方形瓦片网格?”);② 意图明确后明确给出推荐(模式编号 + 名称 + 一句理由)以及配套的 Body / 地图组件(platform.md §4 映射表);③ 尽早锁定选择——之后切换 TileMapMode 会清空地形、迫使复查所有 Body/移动脚本、可能要重画所有瓦片(platform.md §4 “切换地图类型的注意事项”)。
- 切换 TileMapMode 是用户在 Maker 里的操作,AI 绝不直接编辑 .map JSON 翻转它:引导用户打开 Maker 的 Hierarchy 窗口 → 右键目标地图实体 → 在右键菜单选与目标模式匹配的 “Switch ...” 选项(Switch TileMap / RectTileMap / SideViewRectTileMap),由 Maker 完成转换、换瓦片组件、按需重建地形 → 用户确认切换完成后调用 MCP refresh → 重读 MapComponent.TileMapMode 验证,并按新模式复查每个动态实体的 Body 组件。AI 在模式切换中的角色是:推荐 → 等用户在 Maker Hierarchy 右键切换 → refresh → 修不再匹配的 Body 组件/脚本。模式切换流程、Body 交换后检查清单、以及 LEA-3004 之外的静默失败症状字典只在 platform.md §4(映射 + 检查协议 + 切换策略)与 troubleshooting.md(完整症状字典)里,切模式/换 Body/调试静默失败时必须读;分地图类型细节见 platform-maple.md / platform-rect.md / platform-sideview.md;瓦片绘制见 tile.md。
- 平台规则触发时先读对应 reference 再改代码或提方案(触发故意宽泛,拿不准就读;多个触发就全部读,“SKILL.md 里 8 条核心规则已看过”不是跳过 reference 的借口):jump/gravity/movement/MoveVelocity/InputSpeed/JumpForce/WalkSpeed/SpeedFactor/foothold/patrol → 对应地图类型的 platform-maple.md / platform-rect.md / platform-sideview.md 全文 + platform.md §10;spawn/_SpawnService/SpawnByModelId/SpawnByEntity/“召唤怪物”/运行时创建 → platform.md §8 + §8.5;屏幕坐标/相机范围/“是否在屏幕内”/像素单位/OrthographicSize/世界单位 → platform.md §5;遮挡/不可见/“应该渲染在上层”/SortingLayer/OrderInLayer/Z 值 → platform.md §6 + §7;LEA-3004 或“不动”“悬空”“卡墙”“弹开”“掉出地图”“从 foothold 边缘掉落” → 先读 troubleshooting.md 全文,再读对应 platform-{type}.md §7;LEA-3005 InvalidArgument 'stateName'/StateComponent/StateType/@State/ChangeState/AddState/AddCondition/ActionSheet/SetActionSheet/StateAnimationComponent/AvatarStateAnimationComponent/StateChangeEvent/“动画不切换”“移动时停在 stand/idle”“攻击姿势不播”“受击动画循环” → 先读 animation-state.md 全文,再读 monster.md(或对应实体文档);shader/material/outline/glow/blur/pixelate/rainbow/tint/grayscale/vignette/screen filter/lens distortion/wave/ripple/distortion/dissolve/additive/blend mode/hologram/mask/post-process/MaterialID/MaterialId/ChangeMaterial/_MaterialService/.material → 读 material.md 全文,再用 mlua_Document_Retriever + mlua_API_Retriever 以 MCP 查询着色器目录/属性名/各组件兼容性(不要背);新地图搭建/新项目/.config/CoreVersion 校验/扇区注册/文件夹元数据 Refresh → platform.md §2 + §15 + §16;MapleTile(TileMapMode = 0)工作 → platform-maple.md 全文;RectTile(= 1)工作 → platform-rect.md 全文;SideViewRectTile(= 2)工作 → platform-sideview.md 全文。
- 记住 8 条核心规则:① TileMapMode 与 Body 不对齐,实体不动(无报错)或运行时抛 [LEA-3004] MissingComponent;② 用户脚本必须是 .mlua + .codeblock 成对,.codeblock 由 Maker Refresh 生成;③ SpriteRUID 为空字符串则实体屏幕不可见(无报错);④ 调 SpawnByModelId 不传地图实体(self.Entity.CurrentMap)作 parent 会运行时报错;⑤ 坐标是世界单位(1 单位 = 100 px),用像素值会差 100 倍;⑥ Maker 只扫描 RootDesk/,放 Global/ 的用户文件不被识别;⑦ 不要修改 .d.mlua 或 .codeblock;⑧ CoreVersion 是 26.7.0.0,不匹配就不要继续工作。
- MCP 工具(msw-maker-mcp)用法:play/stop 进入/退出播放模式;refresh 在文件改动后同步 Maker(播放中不允许,先 stop);logs/clear_logs 读取/清空运行时与构建日志;screenshot 仅在用户明确要求时调用;keyboard_input/mouse_input 在播放模式模拟输入。MCP 调用失败或涉及 “MCP connection”/“API Key” 时,引导用户到官方文档 https://maplestoryworlds-creators.nexon.com/ko/docs?postId=1368。
- 按任务路由读 reference:workspace.md(世界实例/Room/DataStorage、目录布局、文件路径、Play 模式、refresh、中途失败恢复);platform.md(8 条核心规则、文件权限 + 文件夹元数据、.mlua + .codeblock 成对、TileMapMode↔Body 映射 + LEA-3004、坐标系/屏幕范围、SortingLayer/OrderInLayer、SpriteRUID、SpawnByModelId 用法/初始化顺序、MovementComponent 各地图类型 InputSpeed 换算公式、ECS、ID 生成、.config、CoreVersion);platform-maple.md / platform-rect.md / platform-sideview.md(各模式专属物理、事件、troubleshooting、checklist);troubleshooting.md(症状→原因→修复统一索引,症状优先调试先来这里);authoring.md(5 类文件共通的编写原则与手改风险,任何文件编写前的入口);tile.md(瓦片绘制,Maker UI 领域,AI 只做引导);builder-protocol.md core + builder-protocol-map.md / builder-protocol-model.md / builder-protocol-ui.md(三个 builder 的统一调用协议,改动对应类型时必须在上下文);entity.md(.map 实体领域);model.md(.model 编写领域);monster.md(怪物标准组件、小写 ActionSheet key、必设 IsLegacy/SortingLayer 覆写、AI 选择、HP/重生、生成位置);animation-state.md(任何状态/动画问题,先读);material.md(.material 结构、着色器类别索引、MaterialID 应用、_MaterialService:ChangeMaterialProperty(ClientOnly)、MCP 驱动的查询循环);msw-ui-system 技能(UI 唯一入口,用 Skill 工具调用)及其模板文件;dataset.md(UserDataSet/LocaleDataSet 运行时、.userdataset + .csv 配对、_LocalizationService 是 ClientOnly、serveronly)。
- 绝对原则 0:任务涉及实体就先读 references/entity.md,无例外。
- 绝对原则 0-bis:用户请求提到任何 UI 元素(弹窗、HUD、按钮、toast、面板、对话框、菜单、tab、布局、屏幕、条/量表、槽位)或涉及编写/编辑 .ui 文件时,在向用户提出任何计划、选项或问题之前:① 先用 Skill 工具调用 msw-ui-system(设计判断、组件 API、枚举、布局配方、运行时模式、UUID 绑定、builder 调用协议统一在一个技能里);② 所有 .ui 变更必须走 msw-ui-system 的 UIBuilder,不得直接改原始 JSON 或 grep,读现有 .ui 也用 UIBuilder 的读侧 API(调用协议见 builder-protocol.md core + builder-protocol-ui.md §3);③ 可选:直接 Read/Glob msw-ui-system/references/templates/ 下的模板文件(templates.md + style-N-*/ + ruid-map.md + Popupbutton.mlua)。无例外。
- 绝对原则 0-ter:任务会创建、修改、重命名或删除任何 .mlua 文件(新脚本、改现有脚本、增删 Component/@Logic/@Event/@State/@BTNode、接生命周期方法 OnBeginPlay/OnUpdate 等,甚至一行小修)时,必须先完整 Read msw-scripting/SKILL.md 和 msw-scripting/references/verify-checklist.md(不带 offset/limit,不用 cat/Get-Content)。只读 msw-general 加零散 .d.mlua 不算替代;即使上一轮已加载过 msw-scripting,也要在新一轮开始时重新确认。触发条件故意宽泛:只要本轮有可能碰到 .mlua 就算触发,无例外、不许“我已经知道了”、不许凭记忆走捷径。
- 绝对原则 0-quater:任务涉及生成、移动、跳跃/重力、坐标放置、图层/排序调试、MapleTile/RectTile/SideViewRectTile 专属逻辑,或观察到任何静默失败症状([LEA-3004] 日志、“不动”“不渲染”“悬空”“卡墙”“掉出地图”“从 foothold 边缘掉落”“差 100 倍”“Maker 里看不到”“仅客户端同步”)时,匹配的 references/platform*.md 与 troubleshooting.md 必须先在上下文(缺失才 Read)。若症状是动画/状态相关([LEA-3005]、'stateName' 不是有效参数、动画与行为不符、移动时停在 stand/idle 片段、攻击姿势不播、受击循环、自定义状态不动画,或任何涉及 StateComponent/StateType/ChangeState/AddState/ActionSheet/SetActionSheet/StateAnimationComponent 的事),则 animation-state.md 必须在任何代码或模型编辑前先在上下文。SKILL.md 里的 8 条核心规则只是摘要——症状→原因→修复表、各地图类型代码模板(Foothold 巡逻 / RectTile 四向移动 / SideView 撞墙检测)、MovementComponent InputSpeed 换算公式、SpriteRUID、SortingLayer/OrderInLayer 细节、SpawnByModelId 初始化顺序、文件夹元数据 Refresh 策略、CoreVersion 策略只在 references 里。多个触发就都读。
- 绝对原则 1:视觉打磨——绝不留空 SpriteRUID,用 msw-search 找资源。
- 绝对原则 2:内容文件改动后 refresh(在播放模式先 stop);仅文件夹改动不需要立即 refresh。
- 绝对原则 3:绝不修改 Environment/*.d.mlua——API 定义是只读的。
- 绝对原则 4:绝不手工创建 .codeblock——由 Maker refresh 从 .mlua 生成;文件夹元数据也在 refresh 时由真实文件夹生成。
- 绝对原则 5:不要在 Global/ 新建用户文件——Maker 不会识别;用户文件属于 RootDesk/MyDesk/。
- 绝对原则 6:结构化文件优先用 builder,三个 builder 的调用手册是统一入口(共享 core + per-builder 文件)——.model/.ui 只能走 builder,.map 以 builder 优先;每次改动 .map/.model/.ui 的那一轮,core 加匹配的 per-builder 文件必须在上下文。只有 per-builder 文件里明确列出的覆盖缺口处才允许直接改原始 JSON——范围最小 + refresh + 日志验证。
- 绝对原则 7:实体引用绑定(Entity/EntityRef 属性)由 AI 直接注入 UUID 字符串,不要让用户在 Maker 里拖拽。
- 绝对原则 8:CoreVersion 不匹配就停工——先确认 Environment/config 里的 CoreVersion 是 26.7.0.0。
- 绝对原则 9:只在用户明确要求时调用 screenshot,任务完成后绝不自动调用。
- 绝对原则 10:工作流某步中途失败就停掉后续步骤,先修根因。
- 绝对原则 11:在一个地图里同一实体组成放置 ≥2 次就先写 .model 并用 modelId 实例化;inline @components 只留给真正一次性的实体。
- 绝对原则 12:新 .model 存到 RootDesk/MyDesk/Models/ 的类别子文件夹(如 Models/Monsters/、Models/NPCs/、Models/Terrain/、Models/MapObjects/、Models/Particles/、Models/UI/),绝不直接放在 MyDesk/ 或 Models/ 下;需要的子文件夹不存在时只创建文件夹,文件夹元数据留给之后 Maker Refresh 生成。
- 绝对原则 13:翻译只在客户端——_LocalizationService 与 Translator 的方法(GetText/GetTextFormat)都是 ClientOnly;服务端要发本地化消息就通过 RPC 发 key,由客户端解析。
- 绝对原则 14:跨平台工具选择——工作区文件/文件夹的探索、读取、搜索一律用 Glob/Read/Grep 工具;禁止用 Bash 的 ls/dir/Get-ChildItem/gci/cat/type/Get-Content/gc/head/tail/find/where/grep/findstr/Select-String 做工作区探索,因为 Windows(PowerShell/Git Bash)与 macOS(bash/zsh)的 shell/路径处理不一致(尤其 bash 下 D:\path\foo 的反斜杠会被当转义吃掉,塌缩成 D:pathfoo)。Bash 只用于真正的 shell 程序(git/npm/MCP/构建脚本),且此时:(a) 优先用工作区相对路径;(b) 绝对路径不可避免时用正斜杠 + 双引号("D:/path/to/map/",绝不传 D:\... 形式);(c) 只用 POSIX 命令(ls/mv/cp/rm)。看到 `ls: cannot access 'D:path...': No such file or directory` 之类错误立刻停下,改用 Glob/Read 重试。
- 绝对原则 15:.model 只能走 builder,且用 ModelBuilder 前必须先让 references/model.md(领域)+ builder-protocol.md core + builder-protocol-model.md(调用协议)三者完整在上下文(Model Work Preflight 与 Builder Protocol Preflight 同时触发);不要直接查看或编辑 .model JSON。标识符/value 元数据/property/child/event-link 的一致性只有三者一起读才有保证。
- 绝对原则 16:.map 以 builder 优先——用 MapBuilder 完成覆盖范围内的检查与修改,保持实体 id、路径、组件名、origin 元数据与模型实例镜像一致;若 MapBuilder 明确不覆盖所需操作,做最小的直接 .map 编辑,然后 refresh 并验证。完整 API/require 路径/各操作写法/覆盖缺口/false 返回处理/跨流程见 builder-protocol-map.md §1 + builder-protocol.md §4(与 entity.md 并行读作为领域上下文)。
适用边界 · 注意事项
- 不是 MapleStory Worlds(MSW)项目、或没有 msw-maker-mcp / Maker 编辑器 / refresh 工具链时完全不适用——本规范中的 Builder、TileMapMode、refresh、RUID 等机制都是 MSW 专有的。
- 用 Unity / Godot / Unreal 等通用引擎开发时不要套用这套 TileMapMode↔Body、.model/.map/.ui builder、RootDesk/MyDesk 目录与 CoreVersion 规则。
- 只想做逻辑原型、不需要视觉资源与打包成品的场景下,可暂不执行“视觉打磨(msw-search 找资源 + 填 SpriteRUID)”这条,其余规范仍适用。