# Migration from legacy packs This project is meant to replace legacy `.pck` or EterPack-style content delivery gradually, not through a single risky cutover. ## Target state - Linux builds produce `.m2p` - the client loads `.m2p` first - runtime master key delivery is required - silent fallback to legacy packs is disabled in production ## Suggested migration phases ### Phase 1: parallel loader - keep the legacy loader in the client - add `.m2p` support beside it - verify the new loader against real content sets - keep fallback only in development if needed ### Phase 2: pipeline validation - build `.m2p` from the same source tree as legacy packs - run `verify` for every archive - run `diff` between the source tree and `.m2p` - compare in-game behavior between legacy and `.m2p` ### Phase 3: runtime delivery - stop embedding a real content key in the client - deliver the runtime key through launcher, environment, or mapping - verify startup failure behavior when the runtime key is missing ### Phase 4: production cutover - package only `.m2p` for release clients - disable silent fallback to legacy packs - remove stale pack generation from release CI - keep extract/debug tools only for internal use ## Recommended checks - duplicate normalized paths - invalid relative paths - case-collision problems on Windows - decompression failures - manifest signature failures - key mismatch by `key_id` - runtime smoke against the real client - scenario gate with known-issues baseline ## Practical migration loop 1. Pick one legacy pack group. 2. Rebuild it as `.m2p`. 3. Verify it. 4. Diff it against the source tree. 5. Boot the client with runtime keys. 6. Run the runtime scenario gate. 7. Validate asset loads in logs and in-game. 8. Move to the next pack group. Recommended gate command: ```bash python3 scripts/validate_runtime_gate.py \ --runtime-root /tmp/m2dev-client-runtime-http ``` For release tightening: ```bash python3 scripts/validate_runtime_gate.py \ --runtime-root /tmp/m2dev-client-runtime-http \ --strict-known-issues ``` The shared baseline lives in: - `known_issues/runtime_known_issues.json` This lets the migration fail only on new regressions while still tracking historical client data problems explicitly. ## Confirmed startup-safe pack group The following startup pack set has already been validated against the real client runtime on the Linux VPS: - `root` - `patch1` - `patch2` - `season3_eu` - `metin2_patch_snow` - `metin2_patch_snow_dungeon` - `metin2_patch_etc_costume1` - `metin2_patch_pet1` - `metin2_patch_pet2` - `metin2_patch_ramadan_costume` - `metin2_patch_flame` - `metin2_patch_flame_dungeon` - `locale` - `uiscript` - `uiloading` - `ETC` - `item` - `effect` - `icon` - `property` - `terrain` - `tree` - `zone` - `outdoora1` - `outdoora2` - `outdoorb1` - `outdoorc1` - `outdoorsnow1` - `pc` - `pc2` - `guild` - `npc` - `monster2` - `sound` - `sound_m` - `sound2` - `monster` - `npc2` - `textureset` - `outdoora3` - `outdoorb3` - `outdoorc3` - `outdoordesert1` - `outdoorflame1` - `outdoorfielddungeon1` Validation method: 1. build each pack as `.m2p` 2. remove the matching legacy `.pck` 3. provide the runtime master key through: - `M2PACK_MASTER_KEY_HEX` - `M2PACK_KEY_ID=1` 4. start the Linux-built Windows client with `xvfb-run + wine` Observed result: - `PackInitialize` succeeded - Python startup succeeded - `app.Create(...)` succeeded - client reached `MainStream.SetLoginPhase()` For the world, audio, actor, and gameplay-adjacent packs in this list, the current validation level is startup regression smoke only. Full confidence for those packs still requires map-load or in-game coverage. The repository now also includes a scenario validator for common world packs: - `scripts/validate_runtime_scenarios.py` It verifies that selected `Outdoor*` maps reference valid `textureset` and environment assets across pack boundaries. It also now includes an actor/content validator: - `scripts/validate_actor_scenarios.py` The current actor validator now resolves real `MotionFileName` targets from `.msa` files instead of assuming every motion uses a same-name local `.gr2`. That removed the old false positives from redirected actor motions, and the remaining `orc_lord` mismatch was fixed in the runtime assets by correcting `30_1.msa` to point to `30_1.GR2`. On the current real client runtime, the actor validator now passes cleanly. It still verifies: - `.msm` base model references - `.msm` effect script references - `.msm` default hit effect references - `.msm` default hit sound references It also now includes an effect graph validator: - `scripts/validate_effect_scenarios.py` On the current real client runtime, the effect validator checks 458 text-based effect files and now reports 10 concrete missing references: - `effect/background/moonlight_eff_bat*.mse` missing three `effect/pet/halloween_2022_coffin_bat_0{1,2,3}.dds` textures - `effect/background/mushrooma_{01,03,04}.mse` missing matching `.mde` mesh files - `effect/background/turtle_statue_tree_roof_light01.mse` missing `turtle_statue_tree_roof_light01.mde` Two earlier effect-path issues were cleaned up in the runtime assets by adding safe aliases for already existing textures: - `effect/background/smh_gatetower01.mse` now resolves `effect/monster2/smoke_dust.dds` - `effect/etc/compete/ready.mse` now resolves `effect/etc/compete/ready.dds` The remaining ten effect findings were also checked against the current `m2dev-client` git history and no matching source `*.dds` or `*.mde` assets were found there. They are therefore treated as true content gaps for now, not as simple path regressions. It also now includes an audio scenario validator: - `scripts/validate_audio_scenarios.py` On the current real client runtime, the audio validator checks the full `*.mss` runtime script layer and no longer reports any missing audio references. The previous cross-pack and wrong-path sound references were cleaned up in the runtime assets, and the last remaining `combo7.wav` issue was resolved by aligning `combo_07.mss` with the byte-identical `combo_08` motion variant. The current effect findings are recorded in: - `known_issues/runtime_known_issues.json` Actor and audio are currently clean in that baseline. That file is now the shared runtime baseline used by the validators and the aggregated release gate. Recommended next pack groups: 1. remaining startup-adjacent patch packs 2. remaining late-load gameplay content not covered yet 3. broader scenario-based validation for actor, effect, and sound content ## Risk notes - Do not mix silent fallback with production security claims. - Do not ship a client that accepts `.m2p` without runtime key enforcement. - Do not keep real secret keys inside the repository.