skill: switch 40250 parity skill to file-by-file 1:1 porting

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>
This commit is contained in:
shenlei
2026-09-22 17:12:16 +09:00
co-authored by Claude Opus 5
parent c5c183da37
commit ad6ea9ad7e
4 changed files with 189 additions and 123 deletions
@@ -1,49 +1,70 @@
# Project map
## Reference client
## Reference client (40250)
- Root: `../40250/Server Client TMP4/ClientVS22/source`
- High-level game and packet flow: `UserInterface`
- actors, motion, maps, flying objects: `GameLib`
- rendering, input, collision primitives: `EterLib`
- effects: `EffectLib`
- Granny integration: `EterGrnLib`
- audio: `MilesLib`
- terrain: `PRTerrainLib`
- Root: `MT_40250_SOURCE`, else `reference_root` in `audit/manifest.json` — on this machine
`../40250/Server Client TMP4/ClientVS22/source` relative to the repo (quote it: the path has spaces).
- Active sources: the `ClCompile`/`ClInclude` items in `../vs_files/*/*.vcxproj`; files not listed
there are not product code.
- Many `UserInterface/` files contain CP949 bytes in comments: use `grep -a` / `grep -arn`, or plain
grep silently reports no match.
- Python UI and game scripts are **not** in the source tree: they are in this repo at
`assets/root/*.py` (e.g. `uitarget.py`, `uitaskbar.py`) and `assets/uiscript/`.
- Server source (for protocol questions only, not client behavior): `../40250/Server Client TMP4/Server`.
Use the Visual Studio project and active preprocessor flags to distinguish reachable product code from disabled, obsolete, and third-party code.
| Library | Lines | Content |
| --- | ---: | --- |
| `UserInterface` | 64.7k | network stream + phases, `CPythonPlayer`, `CInstanceBase`, managers, Python modules |
| `EterLib` | 48.7k | device/render state, camera, input/IME, net stream, resources, collision primitives |
| `GameLib` | 30.7k | `CActorInstance` (motion, battle, attach, events), flying objects, map/terrain, race data |
| `EterBase` | 6.3k | utilities, timer, CRC, file |
| `EffectLib` | 6.1k | effect/particle instances |
| `EterGrnLib` | 5.9k | Granny models, motion, LOD |
| `EterPack` | 3.4k | pack format |
| `MilesLib` | 2.3k | audio |
| `EterLocale` | 1.1k | codepages, locale strings |
| `PRTerrainLib` | 1.0k | terrain texture/height data |
## Current client
- GDScript runtime and tests: `project/`
- native extension: `extension/`
- format readers: `formats/`
- shared/native libraries: `libgr2/`
- extracted assets and tables: `assets/`
- numerical reference oracle: `oracle/`
- host-side tools: `tools/`
- GDScript runtime: `project/` (entry `project/app_flow.gd`, world `project/game_scene.gd`); UI in `project/ui/`.
- Native extension: `extension/src/` (network in `extension/src/net/`, classic 40250 protocol in `extension/src/net/classic/`).
- Format readers: `formats/`; Granny: `libgr2/`; assets/tables: `assets/`; Granny oracle: `oracle/`; tools: `tools/`.
## Existing evidence
### Known counterparts
- `docs/CLIENT-GAP.md`: historical broad gap analysis; migrate useful claims into contracts rather than trusting status text.
- `docs/CLIENT-PARITY-AUDIT-AND-FIX-GUIDE.md`: existing methodology and high-risk domains.
- `docs/CLIENT-40250-PORT.md`: porting context.
- `docs/PARITY-GAP.md`: visual/rendering gap notes.
| 40250 | Current |
| --- | --- |
| `CPythonNetworkStream*` phases, `CAccountConnector` | `extension/src/net/classic/classic_session.cpp`, `classic_stream.cpp`, `classic_parser.cpp` |
| packet structs / `CMainPacketHeaderMap` | `extension/src/net/classic/wire_classic.h` |
| `EterLib/NetStream.cpp` sequence + cipher | `extension/src/net/classic/sequence_table.h`, `classic_cipher.cpp` |
| `CPythonCharacterManager`, `CInstanceBase` state from packets | `extension/src/net/entity_store.cpp`, `project/net_world.gd` |
| `CPythonPlayer` input/move (`PythonPlayerInput*.cpp`), main `CInstanceBase` movement | `project/player_controller.gd` |
| `PythonPlayerEventHandler.cpp` (OnMove/OnMoving/OnWaiting/OnStop -> `SendCharacterStatePacket`) | `project/net_play.gd` |
| `CPythonPlayer` skill use | `project/player_skill.gd` |
| `CFlyingObject*` | `project/fly_object.gd` |
| `EterLib/Camera.cpp` + `PythonApplicationCamera` | `project/game_camera.gd` |
| `ui*.py` windows | `project/ui/*_ui.gd` |
### Code that is not a counterpart
About 100 of the 111 `project/*_system.gd` files are loaded only by their own
`project/test_*_parity.gd` (never by the runtime). They are not implementations of 40250
behavior and their tests are not evidence; delete them, or replace them by porting the real 40250
code path when that path exists.
## Existing evidence (historical)
- `docs/CLIENT-GAP.md`, `docs/CLIENT-PARITY-AUDIT-AND-FIX-GUIDE.md`, `docs/CLIENT-40250-PORT.md`,
`docs/PARITY-GAP.md`: background only; trust the port-map, not their status text.
- `oracle/run-diff-suite.sh`: Granny numerical comparison suite.
- `project/test_*_parity.gd` and `project/*_test.gd`: existing tests; inspect assertions before treating them as evidence.
## Typical verification commands
Run a narrow Godot test with:
## Verification commands
```bash
godot --headless --path project --script project/test_name.gd
godot --headless --path project --script <test>.gd # most project tests
cmake --build build-debug -j4 && ctest --test-dir build-debug --output-on-failure -j2
```
Some scripts expect the path relative to `project/` instead:
```bash
godot --headless --path project --script test_name.gd
```
Follow the convention already used by the selected test. Always finish code changes with `git diff --check`.
If `build-debug/CMakeCache.txt` points at another checkout path, reconfigure first:
`cmake -S . -B build-debug -DCMAKE_BUILD_TYPE=Debug`. Always finish with `git diff --check`.