docs(port-plan): close migration prerequisite gaps

This commit is contained in:
shen
2026-09-22 03:01:57 -07:00
parent dcefc83211
commit ae68ec5944
9 changed files with 111 additions and 65 deletions
+1
View File
@@ -485,3 +485,4 @@
{"time": "2026-09-22T03:15:00Z", "event": "implementation_fix_round", "result": "PARTIAL", "ids": ["movement.keyboard.motion/server-speed-scale-clamp"], "files": ["project/player_controller.gd", "project/keyboard_motion_timeline_test.gd", "audit/contracts/movement.keyboard-motion.md", "audit/manifest.json", "audit/history.jsonl", "audit/remediation-roadmap.md", "audit/reports/coverage.md"], "tests": ["40250 reference source inspection (PASS: InstanceBaseMovement.cpp CInstanceBase::SetMoveSpeed(UINT uMovSpd) only guards uMovSpd>1100 -> 0; otherwise applies uMovSpd/100.0f unclamped)", "extension/src/net/entity_store.cpp EntityStore::motion_move_speed re-read (PASS: already-fixed remote-entity path mirrors the same >1100 -> 0 / mount_vnum!=0 -> 0 guards, no [0.25,3.0]-style band)", "pre-fix player_controller.gd::set_server_speed (FAIL by construction: clampf(moving_speed/100.0, 0.25, 3.0) silently floors/ceils haste or slow stacks outside the reference's 25..300 movSpd band)", "post-fix godot --headless --path project --script keyboard_motion_timeline_test.gd (PASS, incl. new set_server_speed(10/500/1200/100) assertions)", "godot --headless --path project --script test_wasd_steering_parity.gd (PASS)", "godot --headless --path project --script test_no_auto_move_regression.gd (PASS)", "godot --headless --path project --script game_camera_test.gd (PASS)", "godot --headless --path project --script movement_parity_test.gd (PASS)", "godot --headless --path project --script player_move_test.gd (PASS)", "godot --headless --path project --script mouse_controller_test.gd (PASS)", "godot --headless --path project --script test_alignment_parity.gd (PASS)", "godot --headless --path project --script netplay_test.gd (PASS; unrelated mock set_server_speed in netplay_test.gd has no clamp, unaffected)", "git diff --check (PASS)", "audit_ledger.py refresh --write/report --write/validate (PASS)"], "reason": "在同一合同下追查『根运动 vs 连续速度』假设时发现这是假线索——entity_store.cpp::advance_walk_by_motion 与本地 _process() 的位移积分在种类上同构(都是恒速直线插值);真正的差异是 set_server_speed() 把 moving_speed/100.0 塞进无参考依据的 clampf(0.25, 3.0),而参考实现 CInstanceBase::SetMoveSpeed 和本项目已修复的 EntityStore::motion_move_speed 都只有 moving_speed>1100 -> 0 这一个门。移除该私有夹钳,改为 0.0 if moving_speed > 1100 else moving_speed/100.0,两处调用方(net_world.gd、net_play.gd)均不额外夹钳,改动范围限于 player_controller.gd。新增回归断言覆盖旧边界内外和 1100 冻结门。副产品发现:CInstanceBase::SHORSE::SetMoveSpeed 是坐骑上玩家的独立速度设定,只在 IsMounting() 时生效,与远端 mount_vnum!=0 -> 0 的处理方式不同——本轮未下定论,留作独立候选。未修改根运动/AccumulationMovement 适配层、资源与网络事件完整顺序、同步/受击门叠加或真实模型测试,合同保持 PARTIAL。"}
{"time": "2026-09-22T06:00:00Z", "event": "port_round", "unit": "UserInterface/PythonPlayerEventHandler.cpp", "ported": ["CPythonPlayerEventHandler::OnMove", "CPythonPlayerEventHandler::OnMoving", "CPythonPlayerEventHandler::OnStop"], "deleted": ["net_play.gd _tick_on_waiting idle FUNC_WAIT resend"], "divergent": ["CPythonPlayerEventHandler::OnWaiting (walking-but-stalled path not ported)"], "needs_live": [], "tests": ["project/netplay_test.gd PASS", "project/keyboard_motion_timeline_test.gd PASS", "project/movement_parity_test.gd PASS", "project/player_move_test.gd PASS"]}
{"time":"2026-09-22T12:00:00Z","event":"dead_code_removal","deleted_system_files":106,"deleted_tests":106,"lines_removed":36221,"manifest_refs_removed":76,"contracts_touched":18,"reason":"project/*_system.gd reachable only from their own test_*_parity.gd; not implementations of 40250 behavior (SKILL.md: unreachable code is not evidence)","tests":["full headless Godot suite: 192 PASS, 7 FAIL and 5 render tests hanging in headless, all identical on the pre-deletion tree"]}
{"time":"2026-09-22T13:00:00Z","event":"port_map_rebaseline","unit":"UserInterface/PythonPlayerEventHandler.cpp","reset_to_todo":["CPythonPlayerEventHandler::GetSingleton","CPythonPlayerEventHandler::~CPythonPlayerEventHandler","CPythonPlayerEventHandler::OnMoving","CPythonPlayerEventHandler::OnMove","CPythonPlayerEventHandler::OnStop","CPythonPlayerEventHandler::CPythonPlayerEventHandler"],"reason":"new mirror architecture owns the CPythonPlayerEventHandler singleton in native code; prior GDScript counterparts are migration sources, not final mirror implementations","tests":["port_map.py check"]}
@@ -7,12 +7,10 @@
],
"functions": {
"CPythonPlayerEventHandler::GetSingleton": {
"status": "N_A",
"note": "singleton/ctor/dtor plumbing; NetPlay is a scene node"
"status": "TODO"
},
"CPythonPlayerEventHandler::~CPythonPlayerEventHandler": {
"status": "N_A",
"note": "singleton/ctor/dtor plumbing; NetPlay is a scene node"
"status": "TODO"
},
"CPythonPlayerEventHandler::OnClearAffects": {
"status": "TODO"
@@ -31,23 +29,13 @@
"note": "reference fires only inside CInstanceBase::Transform() while IsWalking() and this frame's displacement <=1.0 (InstanceBase.cpp:1922-1930), 100ms throttle vs m_kPPosPrevWaiting; not ported. The old idle-standing resend (_tick_on_waiting) was removed 2026-09-22."
},
"CPythonPlayerEventHandler::OnMoving": {
"status": "PORTED",
"impl": [
"project/net_play.gd:_on_local_moved"
]
"status": "TODO"
},
"CPythonPlayerEventHandler::OnMove": {
"status": "PORTED",
"impl": [
"project/net_play.gd:_on_local_moved"
],
"note": "first moved frame after _was_moving=false; resets the 300ms moving window"
"status": "TODO"
},
"CPythonPlayerEventHandler::OnStop": {
"status": "PORTED",
"impl": [
"project/net_play.gd:_on_anim_state"
]
"status": "TODO"
},
"CPythonPlayerEventHandler::OnWarp": {
"status": "TODO"
@@ -71,8 +59,7 @@
"status": "TODO"
},
"CPythonPlayerEventHandler::CPythonPlayerEventHandler": {
"status": "N_A",
"note": "singleton/ctor/dtor plumbing; NetPlay is a scene node"
"status": "TODO"
},
"CPythonPlayerEventHandler::CNormalBowAttack_FlyEventHandler_AutoClear::OnSetFlyTarget": {
"status": "TODO"
+6 -3
View File
@@ -20,9 +20,12 @@ python3 .agents/skills/metin2-40250-parity-audit/scripts/port_map.py queue --lim
| 2R | 资源包盘点:EPK 压缩/加密类型、密钥来源、覆盖顺序、路径大小写、移动端交付 | 下一步(可与 2A 并行) |
| 2P | CPython 2.7.18 编进 libmtgodot,五个平台各自 `pyconfig.h` 并分别验证 | 2A 之后(Android 独立程序已验证 b02c49bb |
| 2D | 数据源切到 40250msm 路径、protoTEA + `TItemTable`)、严格资源测试、资源根 | proto 在 2A 之后,资源根在 2R 之后 |
| 2V | 最小纵向切片:PythonLauncher → system.py → wndMgr → 登录/选角 → GamePhase → 本地移动 | 需要 2A、2P、2D |
| 2 | 其余 P0 角色/移动单元,按 `#include` 依赖拓扑移植 | 2V 之后 |
| 3 | P1 战斗/技能 → P2 游戏阶段封包 → P3 物品;Python 层按 2P 的结论进行 | 未开始 |
| 2V0 | UI 壳:真实 PythonLauncher/wndMgr/grp/app + platform UI,桩玩法模块,显示并操作 Logo/Popup | 需要 2A、2P、root/uiscript 资源 |
| 2V1 | 登录/选角:真实 net phase、登录/选角脚本和所需模块,进入 Loading | 2V0 之后 |
| 2V2 | GamePhase:真实角色管理/主角创建/最小渲染,进入游戏并显示角色 | 2V1 和 2D 之后 |
| 2V3 | 本地移动:真实 player/input/event/movement 链,输入、位置和移动封包由新路径负责 | 2V2 之后 |
| 2 | 2V3 未覆盖的其余 P0 角色/移动单元,按 `#include` 依赖拓扑移植 | 2V3 之后 |
| 3 | 剩余 Python 模块和窗口 → P1 战斗/技能 → P2 游戏阶段封包 → P3 物品 | 未开始 |
| 4 | `NEEDS_LIVE` 真服验证批 | 未开始 |
## 批次 2 单元(顺序由 2A 的依赖图重新生成;下表仅为候选)