mcpField
M
msw-defaultplayer

msw-defaultplayer

github.com/msw-git开发3810.0k 次安装3 周前更新
代码仓库

关于 msw-defaultplayer

msw-defaultplayer 是面向 MapleStory Worlds 的技能,使用 ModelBuilder 检查和修改 DefaultPlayer 模型,供游戏创作者配置玩家组件及移动、物理、HP 和摄像机设置。

主要功能

  1. 01检查并修改 DefaultPlayer 模型
  2. 02管理玩家组件
  3. 03配置移动与物理属性
  4. 04调整 HP 和摄像机设置
  5. 05了解玩家运行时层级

适用场景

  1. 01修改玩家移动或跳跃设置
  2. 02调整摄像机跟踪和 HP
  3. 03添加或移除玩家组件

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/msw-git/msw-ai-coding-plugins-official --skill msw-defaultplayer

安装后在 Claude Code 中输入/msw-defaultplayer确认已加载。

详细介绍

MSW 默认玩家

使用 msw-general ModelBuilder 检查或修改 DefaultPlayer 模型文件、管理组件,并配置移动/物理/HP/摄像机。

对于服装/虚拟形象装备,请参阅 msw-avatar 技能。服装不仅适用于 DefaultPlayer,也适用于任何实体,因此归入单独的技能。


DefaultPlayer 概览

什么是 DefaultPlayer?

MapleStory Worlds Maker 工作区默认提供的玩家角色模型。

  • 任何用户进入世界时,都会基于此模型创建一个玩家实体。
  • 要使用的模型 ID 由 DefaultUserEnterLeaveLogic 的 PlayerUri 属性指定。
文件位置和结构

DefaultPlayer 由两个 .model 文件组成:

文件路径作用
Player.model./Global/Player.model基础模型。定义 Components 列表和 Properties 链接
DefaultPlayer.model./Global/DefaultPlayer.model继承 Player(BaseModelId: "player")。覆盖 Values

重要:这两个文件都位于 ./Global/ 中。自定义脚本文件创建于 ./RootDesk/MyDesk/ 下。

通过 ModelBuilder 修改 DefaultPlayer

DefaultPlayer 通过同级目录中的 msw-general/scripts/model/msw_model_builder.cjs 管理,而不是直接编辑原始 JSON。

  • 更改属性值:ModelBuilder.read("./Global/DefaultPlayer.model").value(...)
  • 添加/移除组件:component() / removeComponent()
  • 查看基础组件列表:ModelBuilder.snapshot("./Global/Player.model")

文件结构详情

Player.model(基础模型)
Path: ./Global/Player.model
EntryKey: model://player
  • Components:玩家默认组件的完整列表(MOD.Core.* 原生组件)
  • Properties:模型属性 → 组件属性链接定义(可在检查器中编辑的属性)
  • Values:为空(默认值由引擎提供)
DefaultPlayer.model(覆盖模型)
Path: ./Global/DefaultPlayer.model
EntryKey: model://defaultplayer
BaseModelId: "player"
  • Components:仅包含 DefaultPlayer 上新增的组件(例如 script.PlayerHit、script.PlayerAttack)
  • Values:被覆盖设置值的数组

DefaultPlayer 默认组件列表

从 Player.model 继承的原生组件:

组件作用
TransformComponent位置、旋转、缩放
MovementComponent移动速度和跳跃力度控制
RigidbodyComponent物理(重力、踏脚点)、MapleStory 风格的移动
KinematicbodyComponent在 RectTileMap 上进行上下左右移动
SideviewbodyComponent在 SideViewRectTileMap 上进行横版移动
StateComponent状态机(Walk、Jump、Dead 等)
AvatarRendererComponent虚拟形象渲染、颜色、表情
AvatarStateAnimationComponent状态 → 虚拟形象动画映射
CostumeManagerComponent装备/服装管理 → 详情请参阅 msw-avatar 技能
CameraComponent摄像机跟踪设置
PlayerControllerComponent输入到动作的映射、条件处理
PlayerComponentHP、死亡/复活、PVP、地图移动
ChatBalloonComponent聊天气泡
NameTagComponent名称标签
DamageSkinSettingComponent伤害皮肤
DamageSkinSpawnerComponent伤害皮肤生成
HitEffectSpawnerComponent受击效果生成
TriggerComponent碰撞检测
InventoryComponent背包

DefaultPlayer.model 中添加的脚本组件:

组件作用
script.PlayerHit玩家受击处理逻辑
script.PlayerAttack玩家攻击逻辑

快速参考 — 关键组件

组件作用关键属性 / 方法
PlayerComponentHP、死亡 / 复活、PVP、地图移动Hp, MaxHp, PVPMode, RespawnDuration, RespawnPosition, UserId, IsDead(), ProcessDead(), ProcessRevive(), MoveToMapPosition()
PlayerControllerComponent输入 → 动作映射、条件控制SetActionKey(key, actionName), ActionAttack(), ActionJump(), LookDirectionX
MovementComponent高级移动速度 / 跳跃接口InputSpeed(默认值为 1.0)、JumpForce(默认值为 1)、Jump(), Stop()
RigidbodyComponentMaple 侧视物理(重力 / 落脚点)Gravity, WalkAcceleration, WalkSpeed, AddForce(), IsOnGround()
KinematicbodyComponentRectTile 上的俯视上下左右移动(仅限 RectTile 地图模式)
SideviewbodyComponentSideViewRectTile 上的侧视移动(仅限 SideViewRectTile 地图模式)
AvatarRendererComponentAvatar 渲染 / 颜色 / 表情SetColor(), SetAlpha(), PlayEmotion(), PlayRate
StateComponent状态机(Walk/Jump/Dead)CurrentStateName, ChangeState(), DeadEvent/ReviveEvent
NameTagComponent名称标签Name, FontSize, FontColor, NameTagRUID
ChatBalloonComponent聊天气泡Message, ChatModeEnabled, ShowDuration
CameraComponent摄像机跟踪DeadZone, SoftZone, Damping, ScreenOffset
TriggerComponent碰撞检测BoxSize, Offset, CollisionGroup

DefaultPlayer Values 结构

DefaultPlayer.model 的 Values 数组中每个条目的格式:

{
  "TargetType": "<component name> or null",
  "Name": "<property name>",
  "ValueType": {
    "$type": "MODNativeType",
    "type": "<type info>"
  },
  "Value": <value>
}
TargetType 规则
  • null:Player.model 的 Properties 中定义的模型属性(通过 Properties 链接到实际组件属性)
  • "MOD.Core.<ComponentName>":直接覆盖特定原生组件上的属性
  • "script.<ScriptName>":自定义脚本组件的属性
模型属性(TargetType: null)

通过 Player.model 的 Properties 中定义的链接,映射到实际组件属性。

模型属性名称源组件.属性说明默认值
speedMovementComponent.InputSpeed移动速度1.0
jumpForceMovementComponent.JumpForce跳跃高度1.0
walkAccelerationRigidbodyComponent.WalkAcceleration加速 / 减速1.0
gravityRigidbodyComponent.Gravity重力1.0
cameraDeadZoneCameraComponent.DeadZone摄像机死区{x: 0.052, y: 0.08}
cameraSoftZoneCameraComponent.SoftZone摄像机软区{x: 0.268, y: 0.7}
cameraDampingCameraComponent.Damping摄像机平滑跟随{x: 2.5, y: 3.9}
cameraScreenCameraComponent.ScreenOffset死区中心点{x: 0.5, y: 0.655}
cameraDutchCameraComponent.DutchAngle摄像机旋转0.0
cameraOffsetCameraComponent.CameraOffset摄像机位置偏移{x: 0.0, y: 0.0}
messageChatBalloonComponent.Message聊天气泡消息""
chatModeEnabledChatBalloonComponent.ChatModeEnabled是否处理聊天(例如显示气泡)true
nameTagNameTagComponent.Name名称标签""
damageSkinIdDamageSkinSettingComponent.DamageSkinId伤害皮肤类型DataRef
damageDelayPerAttackDamageSkinSettingComponent.DelayPerAttack伤害延迟0.05
triggerBodyBoxSizeTriggerComponent.BoxSize碰撞检测区域大小{x: 0.66, y: 0.7}
triggerBodyBoxOffsetTriggerComponent.BoxOffset碰撞检测区域偏移{x: 0.0, y: 0.35}
triggerBodyColliderOffsetTriggerComponent.ColliderOffset碰撞体偏移{x: 0.0, y: 0.35}
maxHpPlayerComponent.MaxHp最大 HP1000
直接覆盖组件(TargetType:特定组件)

直接覆盖组件属性,而不通过模型属性链接的值:

TargetTypeNameDescriptionDefault
MOD.Core.CameraComponentZoomRatioMax摄像机最大缩放比例500.0
MOD.Core.MovementComponentJumpForce跳跃力度(直接覆盖)1.0
MOD.Core.MovementComponentInputSpeed移动速度(直接覆盖)1.0
script.PlayerHitCollisionGroup命中碰撞组CollisionGroup ID
script.PlayerHitBoxSize命中碰撞区域大小{x: 0.45, y: 0.7}
script.PlayerHitColliderOffset命中碰撞偏移量{x: 0.0, y: 0.35}

各地图模式下的移动组件

瓦片地图模式与 Body 的映射表请参阅 msw-general/references/platform.md §4。根据地图模式,RigidbodyComponent / KinematicbodyComponent / SideviewbodyComponent 中的一个会处于激活状态。


识别玩家(供脚本引用)

  • entity.PlayerComponent ~= nil → 判断实体是否为玩家
  • _UserService.LocalPlayer → 我的玩家实体(仅客户端)
  • _UserService:GetUserEntityByUserId(userId) → 特定用户的玩家实体

玩家实体的运行时结构(根实体与子实体)

生成的玩家并非单个扁平实体。运行时,引擎会在玩家根实体下构建一个小型层级结构,且头像动作选择器位于孙级实体上,而非根实体上。这会影响组件的查找方式以及触发头像姿势的方式。

组件 → 实体映射
Component所在位置查找方式
PlayerComponent根实体player:GetComponent("PlayerComponent")(或 player.PlayerComponent)
StateComponent根实体player:GetComponent("StateComponent")
MovementComponent根实体player:GetComponent("MovementComponent")
AvatarRendererComponent根实体player.AvatarRendererComponent
AvatarStateAnimationComponent根实体player:GetComponent("AvatarStateAnimationComponent")
PlayerControllerComponent根实体player.PlayerControllerComponent
AvatarBodyActionSelectorComponent根实体的 Body 孙级实体(位于头像根实体下)无法通过 player:GetComponent(...) 访问——见下文
AvatarFaceActionSelectorComponent根实体的 Face 孙级实体无法通过 player:GetComponent(...) 访问——见下文

player:GetComponent("AvatarBodyActionSelectorComponent") 会返回 nil,且 LSP 不会发出警告(签名为 Component,而非可空类型)。只有在运行时才能看到此失败。

如何访问选择器
-- ClientOnly context (recommended — the direct API)
local body  = self.Entity.AvatarRendererComponent:GetBodyEntity()
local face  = self.Entity.AvatarRendererComponent:GetFaceEntity()
local bodySelector = body and body:GetComponent("AvatarBodyActionSelectorComponent")
local faceSelector = face and face:GetComponent("AvatarFaceActionSelectorComponent")

-- Server or "either side" context (GetBodyEntity / GetFaceEntity are ClientOnly)
local bodySelector = self.Entity:GetFirstChildComponentByTypeName(
    "AvatarBodyActionSelectorComponent", true)

AvatarRendererComponent:GetBodyEntity() 和 GetFaceEntity() 声明为 @ExecSpace("ClientOnly")——从服务端方法调用时会返回 nil。跨端的备用方案是使用 GetFirstChildComponentByTypeName(name, recursive=true)。


触发头像姿势——使用 StateComponent,绝不要直接写入选择器

运行中的玩家每个 tick 都会执行一个状态机:PlayerControllerComponent 评估输入/移动 → StateComponent 转换状态(IDLE / MOVE / 等)→ AvatarStateAnimationComponent.ReceiveStateChangeEvent 将其转换为 BodyActionStateChangeEvent → 选择器的 ActionState 被重写。

这意味着直接写入 AvatarBodyActionSelectorComponent.ActionState 会被静默覆盖:该值只生效一帧,接着下一个状态机 tick 会将当前 StateComponent 状态映射回选择器,你写入的值便消失了。赋值后,日志会立即打印 ActionState=Attack,但在游戏模式下,姿势只会闪现一帧,随后消失。

正确的入口点
local state = self.Entity:GetComponent("StateComponent")
state:ChangeState("ATTACK")   -- ActionSheet keys are UPPERCASE

状态键来自玩家的 ActionSheet。DefaultPlayer 自带 11 个大写键,每个键都映射到一个默认动画:

StateComponent:ChangeState(...) 键默认动画
"IDLE"stand
"MOVE"walk
"ATTACK"attack
"HIT"hit
"CROUCH"crouch
"FALL"fall
"JUMP"fall
"CLIMB"rope
"LADDER"ladder
"DEAD"dead
"SIT"sit

动作结束后,状态机将自动返回 IDLE,无需手动设置计时器恢复状态。

大小写陷阱:传给 ChangeState 的字符串键必须是大写("ATTACK")。直接写入 selector.ActionState 的枚举值(NPC 路径——见下文)则是 MapleAvatarBodyActionState.Attack,采用 PascalCase。这是独立的 API,但对应相同的底层状态。字符串键大小写错误("attack" / "Attack")会导致 ActionSheet 映射失效,且不会发出警告。

何时可以直接写入 selector?

仅适用于没有运行中的 PlayerControllerComponent + StateComponent + AvatarStateAnimationComponent 组件栈的实体,例如使用 avatar 渲染器显示视觉效果、但没有输入控制器驱动状态机的 NPC / 怪物。对于这些实体,selector.ActionState = MapleAvatarBodyActionState.<Pose> 会生效。对于 DefaultPlayer 结构的实体,则应改为调用 StateComponent:ChangeState(...)。

常用服务一览(脚本参考)
服务作用主要 API
_UserService用户管理、进入 / 离开LocalPlayer、UserEntities、GetUserEntityByUserId()、UserEnterEvent/UserLeaveEvent
_TeleportService传送 / 地图移动TeleportToEntity()、TeleportToMapPosition()、WarpUserToWorldAsync()
_CameraService摄像机控制SwitchCameraTo()、ZoomTo()、ZoomReset()
DefaultUserEnterLeaveLogic用户进入 / 离开逻辑PlayerUri(玩家模型 ID)、StartPoint(起始地图)

如何修改 DefaultPlayer

修改属性值(Values)

使用 ModelBuilder.read() 加载 ./Global/DefaultPlayer.model,然后通过 value() 更新值。

示例:将移动速度设为 2.0

const { ModelBuilder } = require("../msw-general/scripts/model/msw_model_builder.cjs");

const b = ModelBuilder.read("./Global/DefaultPlayer.model");

b.value(null, "speed", 2.0, "float")
  .value("MovementComponent", "InputSpeed", 2.0, "float")
  .write("./Global/DefaultPlayer.model");

注意:模型属性(TargetType: null、Name: "speed")和直接组件覆盖项(TargetType: "MOD.Core.MovementComponent"、Name: "InputSpeed")可能同时存在。请通过 value() 将二者设置为一致的值。

示例:跳跃力度设为 1.5,HP 设为 2000

const b = ModelBuilder.read("./Global/DefaultPlayer.model");

b.value(null, "jumpForce", 1.5, "float")
  .value("MovementComponent", "JumpForce", 1.5, "float")
  .value(null, "maxHp", 2000, "int")
  .write("./Global/DefaultPlayer.model");
添加新的 Values 条目

使用 ModelBuilder.value(targetType, name, value, typeKey)。构建器会生成 ValueType 描述符;不要手动编写类型字符串。

常见的 typeKey 值:bool、int、float、double、string、vector2、vector3、data_ref、collision_group。

添加组件

对 ./Global/DefaultPlayer.model 使用 component()。

只添加未从 Player.model 继承的组件。对于继承的原生组件(PlayerComponent、MovementComponent、CameraComponent、StateComponent 等),请使用 value(...) 覆盖值,而不是重新声明组件。如果添加的组件已从 BaseModelId: "player" 继承,ModelBuilder 会发出警告(M040)。

添加自定义脚本组件:

const b = ModelBuilder.read("./Global/DefaultPlayer.model");

b.component("script.MyCustomComponent")
  .write("./Global/DefaultPlayer.model");

自定义脚本(.mlua)必须创建在 ./RootDesk/MyDesk/ 下。先编写脚本,再由 Maker 执行 refresh,然后使用构建器添加 "script.<ScriptName>"。

添加未继承的原生组件:

const b = ModelBuilder.read("./Global/DefaultPlayer.model");

b.component("SpriteRendererComponent")
  .write("./Global/DefaultPlayer.model");
移除组件

对 DefaultPlayer.model 使用 removeComponent()。构建器会移除相关的 Values 条目。

注意:从 Player.model(基模型)继承的组件不会出现在 DefaultPlayer.model 的 Components 中。移除基模型组件需要通过 ModelBuilder 修改 Player.model,通常不建议这样做。


常见陷阱(常见错误)

在 DefaultPlayer.model 中添加组件和更改值时的常见错误。

组件列表相关错误
#错误现象解决方法
C1添加的 script.XXX 消失或未生效如果某个脚本组件未注册在同一目录中对应的 .codeblock 元数据里,加载时会被静默丢弃;如果在此状态下保存,该组件将永久丢失编写 .mlua 后,使用 Maker Refresh 自动生成 .codeblock。或者在实体生成后立即通过 entity:AddComponent("Name") 在运行时添加
C2重复添加 Player.model 上已有的原生组件(例如 MOD.Core.MovementComponent)只会发出重复组件警告,不会阻止添加 → 工作区警告不断累积,行为变得不确定添加前检查基础组件列表(§65-89)。如果组件已存在,只需通过 Values 更改设置
C3移除 script.PlayerHit / script.PlayerAttack这是 DefaultPlayer 附带的仅有额外脚本。移除它们会导致失去受击免疫 / 攻击逻辑如果想禁用这些功能,请切换脚本内的逻辑,或在 Values 中设置 Enable=false
C4禁用 AvatarRendererComponent 并添加 SpriteRendererComponent(或替换为其他渲染器)如果 Avatar 和 Sprite 渲染器同时处于活动状态,就会出现 Z-fighting / 服装未应用的问题仅在禁用 Avatar 后添加 Sprite(参见 §395 中的模式)
C5自定义伤害流程只减少 HP 属性(或只广播伤害外观事件)——引擎的受击 / 死亡流程不会触发Avatar 状态机响应的是 StateChangeEvent,而不是属性写入。伤害数字 / 粒子都能正常显示,但 Avatar 在受击 / 死亡 / 复活期间仍保持空闲状态——视觉效果无声失效,且不会记录错误日志首选方案:通过 HitComponent:OnHit(attacker, damage, isCrit, attackInfo, hitCount) 处理伤害。随后 script.PlayerHit 会自动处理受击 / 死亡 / 重生状态转换。必须手动处理伤害时(持续引导 / 光环 / 脚本控制):将 StateComponent:ChangeState("HIT") 用于受击姿势,并配合 PlayerComponent:ProcessDead() / ProcessRevive() 处理死亡和复活流程。不要只修改 HP——Avatar 不会有任何反应。
C6在启用了 AvatarRendererComponent 的实体(例如 DefaultPlayer)上设置 SpriteRendererComponent.Color / FlipX组件确实存在,GetComponent 返回非 nil,但 Sprite 输出被 Avatar 渲染器自身的渲染流程遮挡——颜色 / 翻转写入会静默失效。同样的操作在纯 Sprite 渲染的实体上有效,因此首次复制粘贴时会失败,且不会出现任何警告使用 AvatarRendererComponent:SetColor(r, g, b, a)(0–1 浮点数)调整色调,并使用 :SetAlpha(a) 淡出。两者均为 ClientOnly。如需改变朝向,请通过 MovementComponent.MoveDirection(或游戏逻辑中的朝向 API)控制角色,而不是使用 sprite.FlipX
Values 变更注意事项 — 只有 jumpForce / speed 需要额外注意

大多数 Values 条目都采用 TargetType=null(别名)形式,可以通过 ModelBuilder.value(null, ...) 设置。只有以下两个字段例外——别名条目和原生条目(TargetType="MOD.Core.MovementComponent")同时存在:

字段别名条目原生条目
跳跃力jumpForce(TargetType=null)JumpForce(TargetType="MOD.Core.MovementComponent")
移动速度speed(TargetType=null)InputSpeed(TargetType="MOD.Core.MovementComponent")

生成实体时,Values 会按数组顺序应用,且两者都会写入同一个原生字段;原生条目在数组中出现得更晚,因此原生值会生效。

  • 错误:只修改别名一侧(jumpForce / speed)→ 会被后面的原生条目覆盖并忽略
  • 正确:将两者都改为相同的值,或只修改原生一侧(JumpForce / InputSpeed)

其他仅有别名的条目(walkAcceleration、gravity、与摄像机相关的条目(cameraDeadZone 除外)、nameTag、damageSkinId、damageDelayPerAttack、triggerBody*、maxHp 等)可以直接通过别名修改。


隐藏 DefaultPlayer

DefaultPlayer 的组件继承自基础模型,因此无法删除。唯一的选择是通过 Enable=false 禁用它们。

组件保留/禁用分类
组件完全隐藏仅隐藏外观备注
TransformComponent保留保留必需
PlayerComponent保留保留必需——禁用会导致进入失败
StateComponent保留保留禁用会导致其他组件报错
MovementComponent保留保留需要移动功能时保留
CameraComponent保留保留需要摄像机时保留
AvatarRendererComponent禁用禁用关键——仅禁用此项即可隐藏外观
AvatarStateAnimationComponent禁用禁用
CostumeManagerComponent禁用禁用
PlayerControllerComponent禁用保留取决于是否需要阻止移动
ChatBalloonComponent禁用禁用
NameTagComponent禁用禁用
DamageSkinSettingComponent禁用禁用
DamageSkinSpawnerComponent禁用禁用
HitComponent禁用禁用
HitEffectSpawnerComponent禁用禁用
TriggerComponent禁用禁用
InventoryComponent禁用禁用
RigidbodyComponent禁用根据地图模式保留在 MapleTile 地图上时
SideviewbodyComponent禁用根据地图模式保留在 SideViewRectTile 地图上时
KinematicbodyComponentEnableShadow=falseEnableShadow=false仅移除阴影
Builder 编辑 — 在 Values 中添加 Enable=false

通过 ModelBuilder.value() 设置组件值。对于尚无 Enable 条目的组件,Builder 会添加该条目。

const { ModelBuilder } = require("../msw-general/scripts/model/msw_model_builder.cjs");

const b = ModelBuilder.read("./Global/DefaultPlayer.model");

b.enable("AvatarRendererComponent", false)
  .value("KinematicbodyComponent", "EnableShadow", false, "bool")
  .write("./Global/DefaultPlayer.model");

保存后,必须执行 Maker Refresh。


DefaultPlayer 组件扩展模式

  • 非外观玩家:禁用 AvatarRendererComponent → 添加 SpriteRendererComponent → 设置 SpriteRUID。
  • 碰撞设置:调整 TriggerComponent 的 Values 中的 ColliderType 和 CollisionGroup。
  • SpawnLocation:在地图(.map)文件中放置 Special → SpawnLocation(复活位置)。

工作流

修改玩家基本属性(移动速度、跳跃力、HP 等)
1. Load ./Global/DefaultPlayer.model with ModelBuilder.read()
2. Update values with value(targetType, name, value, typeKey)
3. If both the model property (TargetType: null) and the direct component override exist, set both consistently
4. write("./Global/DefaultPlayer.model")
为玩家添加自定义脚本
1. Write a new .mlua script under ./RootDesk/MyDesk/ (see the msw-scripting skill)
2. Maker refresh so the script type is registered
3. Load ./Global/DefaultPlayer.model with ModelBuilder.read()
4. Add "script.<ScriptName>" with component()
5. If needed, add default property values for the script with value()
6. write("./Global/DefaultPlayer.model")
7. Request Maker Refresh
更改摄像机设置
1. Load ./Global/DefaultPlayer.model with ModelBuilder.read()
2. Set cameraDeadZone, cameraSoftZone, cameraDamping, cameraScreen, cameraDutch, cameraOffset with value()
3. write("./Global/DefaultPlayer.model")

限制与注意事项

范围内
  • 通过 ModelBuilder 检查/修改 DefaultPlayer/Player 模型文件
  • 通过 component() / removeComponent() 添加/移除组件
  • 通过 value() 设置移动/物理/HP/摄像机参数
范围外
  • 服装/头像装备 → msw-avatar 技能
  • UI 编辑器 → ./ui/ 下的 .ui 文件(专用技能)
  • 地图编辑 → ./map/ 下的 .map 文件(专用技能,包括 NPC/怪物生成点)
  • 通用脚本/资源 → 各自的专用技能
限制
  1. 谨慎处理 Global/:DefaultPlayer.model 和 Player.model 位于 ./Global/。此文件夹用于存放引擎默认模板,因此不建议在此处创建新文件。
  2. 自定义脚本位置:新脚本文件必须创建在 ./RootDesk/MyDesk/ 下。
  3. 地图模式注意事项:当前使用的移动组件因地图模式(MapleTile/RectTile/SideViewRectTile)而异。
  4. ValueType 正确性:添加 Values 条目时,请使用带有显式 typeKey 的 ModelBuilder.value();不要手动编写 ValueType。
  5. Maker Refresh:添加/修改脚本后,必须执行 Maker Refresh(.codeblock 会自动生成)。

评论

支持 Markdown