- keep 40250 widths/overflow semantics (Win32 long = 32-bit), fixed-width
serialized structs with static_assert, instead of copying C type names
- 2A base batch (types, header closure, port_logic target, platform stubs,
header gate, port-map re-baseline) and include-order porting
- 2R pack inventory: six EPK compression types, HybridCrypt key source,
index override order, path case, mobile delivery
- 2P: shared source list, per-platform pyconfig.h, all five platforms
- 2V minimal vertical slice; old and new paths coexist until wired
- strict asset tests (MT_ASSETS vs M2_ASSETS), RUN_AS_IS instead of N_A,
void the 6 pre-architecture 'done' functions
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Records the root/uiscript/locale comparison: npclist, msm contents and
motion/combo registration match; msm location differs; item_proto and
mob_proto use a different record layout and TEA instead of XChaCha20,
so proto.cpp cannot read them; pack contents not yet compared.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Records the decisions (mirror-layout logic port, embedded CPython 2.7 UI),
layers and code layout, batch route and status, and the directory/toolchain
setup needed to resume on another machine. Marks the older refactor plan as
superseded and points CLAUDE.md/AGENTS.md/roadmap at it.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
libpython2.7.a cross-builds with NDK 27.2 (API 24) after disabling
HAVE_LANGINFO_H; 30 C modules built in. On a OnePlus 13 (API 36) the
harness runs system.py -> prototype.RunApp() and imports the root modules
with results identical to macOS (66/74; the 8 failures are stub values or
dev-only scripts). py_embed_spike.py now isolates __main__ like
CPythonLauncher and reports stdlib usage.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
These files were loaded only by their own test_*_parity.gd and never by
the runtime (transitively checked, incl. client_phase_integration_system).
Removes 76 manifest implementation/evidence references across 18
contracts; contract docs get a note that conclusions based on them are
void. Live systems kept: chest, consumable, item_attr, metin_socket,
whisper_chat.
Full headless suite: no new failures (7 failing + 5 headless-hanging
render tests are identical before the deletion).
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
- refroot.py: one reference-root resolver (MT_40250_SOURCE, then manifest)
used by every audit script; missing tree or fingerprint input is an error
- port_map.py: per-function inventory of active 40250 units plus the
40250 Python root, status/queue/init/show/check, 40250: tag scan
- manifest: fix 18 wrong reference paths (Python UI now points at the
40250 Client/Eternexus/root, not the m2dev assets/root), drop 2 deleted
implementation files, move 64 prose test entries to evidence.commands
- first port-map entry: PythonPlayerEventHandler.cpp
- roadmap replaced by a batch/unit queue
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
40250 only calls OnWaiting inside CInstanceBase::Transform() while
IsWalking() (InstanceBase.cpp:1922-1930); it never resends position
while standing. Remove _tick_on_waiting and its throttle state.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Unit of work is a 40250 source unit; current-only logic is a defect;
unreachable code is not evidence. Adds per-function port-map schema,
priority by player-visible gameplay, parallel worktree rules, and a
corrected project map.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
CInstanceBase::SetMoveSpeed only guards moving_speed > 1100 -> 0; the local
player's set_server_speed() was additionally floor/ceil-clamping the scale to
an arbitrary [0.25, 3.0] band with no basis in the reference or in this
project's already-fixed remote-entity equivalent (EntityStore::motion_move_speed).
A heavy haste stack or slow debuff on the local player would silently diverge
from what everyone else sees. Removed the extra clamp; kept the moving_speed<=0
early-return guard against pre-spawn/malformed values.
audit: movement.keyboard.motion/server-speed-scale-clamp closed with reference
citation, regression test, and full related-suite pass; contract stays PARTIAL.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Investigated the prior round's flagged gap ("CanAct()'s Paralysis/Faint/Sleep
movement doors not wired into net_play.gd") via exhaustive reachability
tracing of the 40250 reference source. All three resolve to non-gaps:
- Paralysis: its only setter (__Shaman_SetParalysis, InstanceBaseEffect.cpp:821)
has zero callers anywhere in the reachable source -- dead code, never true
in live gameplay.
- Sleep: the AFFECT_SLEEP case in SetAffect() is commented out; the only live
setter is the AFFECT_STUN case (SetSleep(), InstanceBaseEffect.cpp:932-933),
i.e. IsSleep() is just an alias for AFFECT_STUN -- already covered by the
existing `stunned` field and _can_process_network_state()'s dead/stunned/
knock_down gate.
- Faint: only setter is chrFaintTest(), a debug-only Python binding operating
on GetSelectedInstancePtr(); unverifiable from the available 40250 checkout
(no root/ UI scripts) -- evidence-blocked, left unresolved per the skill's
reachability rule.
Byproduct finding while tracing IsStun(): main-character GC_STUN routes to
Die() in the reference (RecvStunPacket), not Stun(); verified this causes no
movement.keyboard.motion discrepancy since CanAct() blocks movement equally
on IsDead()/IsStun() and the current client already blocks movement equally
on dead/stunned. The Die()-vs-Stun() distinction only affects death-system
semantics, already tracked under combat.affect-status.md (Remaining #2, rows
63/67) -- not duplicated here.
No implementation code changed. Removed the resolved item from manifest.json
and movement.keyboard-motion.md's Remaining list; documented full evidence
in the contract doc and remediation roadmap. Contract stays PARTIAL
(AccumulationMovement root-motion, OnMove/OnMoving event-source parity,
sync/hit/death/warp gate stacking, and real-model bone-flip test remain open
for future rounds).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
40250 parity: CPythonPlayer::NEW_MoveToDirection's m_isCmrRot branch
continuously rolls the camera toward the held movement direction every
frame while a direction key is down, independent of whether a new
translation target was just set. Add _camera_auto_rotate() to replicate
this (forward/back = no rotation, strafe = max rate, diagonal = half
rate), called unconditionally after the frozen/locked/shop/emotion gate
in _process(). Godot's yaw-increase handedness is opposite the
reference's D3D Roll(), so the sign is flipped as a platform adaptation;
verified by convergence invariants in keyboard_motion_timeline_test.gd
rather than bit-for-bit angle matching.
Closes movement.keyboard.motion/camera-auto-follow-rotation.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Handle late main-character data, guarded model construction, bounded retries and map correction. Validate player model sources and add lifecycle and real-asset visual regressions.
Include pending material and character-selection changes, updated A1 screenshot, and the detailed rendering repair plan. Hair occlusion, full UI parity and final macOS package acceptance remain unfinished.