Files
m2pack-secure/docs/migration.md
server 9bbcb67351
Some checks failed
ci / headless-e2e (push) Has been cancelled
runtime-self-hosted / runtime-ci (push) Has been cancelled
Add Wine smoke runners and clear runtime baseline
2026-04-14 21:22:50 +02:00

6.2 KiB

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
  • 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:

python3 scripts/validate_runtime_gate.py \
  --runtime-root /tmp/m2dev-client-runtime-http

For release tightening:

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 now passes cleanly.

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 last orphaned background effect scripts with missing local assets were then removed from m2dev-client, so the shared runtime baseline no longer needs any effect exceptions.

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 shared runtime baseline lives in:

  • known_issues/runtime_known_issues.json

World, actor, effect, 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.