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
@@ -97,12 +97,46 @@ An adaptation may change APIs or representation, never gameplay rules, branch ou
When a verified entry becomes stale, retain its previous evidence and history. Do not delete the entry or recreate it under a new ID.
## History events
A contract's `evidence.tests` and `implementation.files` must be reachable from the runtime
(loaded by `AppFlow`/`GameScene`/the native extension in a normal session). A file used only by its
own test is not an implementation and its test is not evidence.
Append one compact JSON object per meaningful state change to `audit/history.jsonl`:
## Port-map entries
One JSON file per 40250 source unit at `audit/port-map/<Lib>/<File>.json`:
```json
{"time":"2026-09-19T00:00:00Z","event":"status_changed","id":"combat.local.normal_attack","from":"MAPPED","to":"TEST_VERIFIED","reason":"call chain audited and tests passed"}
{
"reference": "UserInterface/InstanceBaseMovement.cpp",
"reference_sha256": "<sha256 of the reference file>",
"priority": "P0",
"contracts": ["movement.keyboard.motion", "movement.remote_sync_state"],
"functions": {
"CInstanceBase::SetMoveSpeed": {
"status": "PORTED",
"impl": ["project/player_controller.gd:set_server_speed", "extension/src/net/entity_store.cpp:motion_move_speed"],
"note": ""
},
"CInstanceBase::__EnableSkipCollision": {"status": "TODO"}
}
}
```
- Function keys are the reference's qualified names (`Class::Method`, or the free-function name).
- `status` is one of `TODO`, `PORTED`, `ADAPTED`, `N_A`, `DIVERGENT`, `NEEDS_LIVE` (meanings in `SKILL.md`).
- `impl` is required for `PORTED`/`ADAPTED`/`NEEDS_LIVE`; `note` is required for `ADAPTED`, `N_A`,
`DIVERGENT` and `NEEDS_LIVE`. `ADAPTED` also needs a `test` path.
- When `reference_sha256` no longer matches the file, every non-`TODO` function in the unit must be
rechecked before the hash is updated.
## History events
Append one compact JSON line per round to `audit/history.jsonl`:
```json
{"time":"2026-09-22T00:00:00Z","event":"port_round","unit":"UserInterface/InstanceBaseMovement.cpp","ported":["CInstanceBase::SetMoveSpeed"],"deleted":["player_controller.gd clampf(0.25,3.0)"],"divergent":[],"needs_live":[],"tests":["project/keyboard_motion_timeline_test.gd PASS"],"commit":"c5c183da"}
```
Contract status changes still use `{"event":"status_changed","id":...,"from":...,"to":...,"reason":...}`.
Never store credentials, packet payload secrets, binary captures, or generated screenshots in the ledger.
@@ -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`.