Skip to content

Builds — retail vs GoG#

This page summarizes the two Lords of the Realm 2 executables tracked in this repository: what they share, what differs, and how evidence and spec work should treat each build.

Binary fingerprints: METADATA.md.

Builds in scope#

Build Filename Ghidra export Typical source
Retail LORDS2.EXE src/LORDS2.EXE.c Original CD / retail install
GoG Lords2-gog.exe src/Lords2-gog.exe.c GOG.com release

Both are 32-bit Windows PE images from the same game era. They implement the same campaign core but diverge in multiplayer stack, some embedded data tables, and GoG-only skirmish mode.

Canonical policy#

flowchart LR
  retail["LORDS2.EXE retail"]
  gog["Lords2-gog.exe GoG"]
  names["lotr2_* names retail canonical"]
  map["Behavioral symbol map"]
  spec["docs/spec normative rules"]
  retail --> names
  names --> map --> gog
  retail --> spec
  gog --> spec
  • Retail LORDS2.EXE is the canonical source for lotr2_* symbol names, struct VA validation, and DirectPlay networking evidence.
  • GoG Lords2-gog.exe is a behavioral mirror: the same logical names are applied via fingerprint and call-graph mapping, not by matching retail virtual addresses.
  • Normative spec (docs/spec/) describes game behavior. Where builds differ, spec pages must call out build-specific rules (see auto-calculation).

Symbol sync workflow: architecture/RENAME_WORKFLOW.md (retail track + GoG parallel track).

Binary fingerprints#

Field Retail GoG
SHA-256 ff33c884…b034b (full hash in METADATA) TBD
File size 1,152,000 bytes TBD
Export layout LORDS2.EXE.c, LORDS2.EXE.h Lords2-gog.exe.c only
Ghidra export date TBD TBD

See METADATA.md for the authoritative fingerprint table and re-export notes.

Feature matrix#

Area Retail GoG Notes
Campaign (map, diplomacy, siege) yes yes Shared core; evidence mostly from retail
Tactical battles (campaign) yes yes Same combat tick / pathfind / projectile logic
Skirmish mode no yes GoG-only; see skirmish/
Multiplayer stack DirectPlay 3 (DPLAYX.DLL) ASIGS session strings No DirectPlay strings in GoG export
Auto-calc casualty tables retail VA / values GoG VA / values Different thresholds — see below
DirectDraw / DirectSound / WinMM yes yes Same API imports per decompilation
String data (L2.ENG) shared shared Edition-agnostic hash in METADATA
Symbol rename coverage complete (FUN_*lotr2_*) in progress (~3.8k FUN_* remain) gog-sync-progress.md
Networking spec spec/networking/, protocols/dplay.md evidence only (skirmish MP) ASIGS protocol not yet documented

Shared behavior#

These areas are treated as the same game logic on both builds unless a spec page or struct note proves otherwise.

Campaign and combat core#

  • Turn flow, province map, army movement, diplomacy, and siege resolution share the same subsystem structure once GoG symbols are mapped.
  • Real-time tactical combat (figures, projectiles, battle AI) uses the same code paths; skirmish adds session gates on GoG globals such as lotr2_skirmish_active — see skirmish/state-and-globals.md.

Multimedia stack#

Both builds import and use:

API Usage
DirectDraw DirectDrawCreate
DirectSound DirectSoundCreate
WinMM mmioOpenA / mmioRead, timeSetEvent / timeKillEvent

Confirmed for retail in METADATA.md; GoG export shows the same import pattern.

Shared data files#

  • L2.ENG — English UI strings (SHA-256 in METADATA).
  • Campaign assets (.PL8, .ENG, Smacker, etc.) are not duplicated per build in this repo; both clients read the same on-disk formats.

Symbol namespace#

Once mapped, GoG uses the same lotr2_* names as retail. Retail renames in architecture/symbol-map.md are the name source; GoG mapping reports live under architecture/gog-symbol-map.md.

Known differences#

Networking#

Build Stack Evidence
Retail DirectPlay 3, DPLAYX.DLL, IDirectPlay3 architecture/net/MODULE.md, protocols/dplay.md
GoG No DirectPlay / DPLAYX strings; ASIGS session configuration skirmish/multiplayer-pvp.md

Retail lotr2_net_* symbols are intentionally excluded from GoG symbol sync until ASIGS equivalents are identified (architecture/gog-symbol-map.md).

The normative networking spec under spec/networking/ covers retail DirectPlay only today.

Skirmish mode (GoG only)#

Skirmish is a single tactical battle with no campaign map — SP vs AI or MP PvP.

The retail export has no Skirmish strings, no gateway wizard steps 0xb / 0xc, and post-battle flow always returns to campaign siege resolve. A reimplementation targeting GoG skirmish parity should not expect retail to implement this mode.

Full evidence tree: skirmish/README.md.

Auto-calculation casualty tables#

Auto-battle resolution uses static threshold tables embedded in each executable. Retail and GoG use different breakpoint values and survivor percentages.

Build Table VA Spec
Retail 0x004f9f10 spec/combat/auto-calculation.md
GoG 0x004de710 same page (GoG section)

Regenerate with:

python3 tools/ghidra/dump_combat_tables.py --all

Interop rule: a compatible client must use the tables from the same build as the session binary — mixing retail tables with a GoG session (or vice versa) will produce wrong casualties.

Addresses and code layout#

All code and data virtual addresses differ between builds. Never assume retail VA equality on GoG.

Examples of structural divergence:

Pattern Retail GoG
Window procedure lotr2_ui_wndproc + separate lotr2_ui_wndproc_impl merged into lotr2_ui_wndproc
Map AI standard ordering two symbols deferred due to AI step reorder
Combat MP stubs a few unmatched symbols tied to GoG MP stubs

See dual-address columns in module docs (e.g. architecture/ui/MODULE.md) and per-subsystem GoG maps (architecture/gog-symbol-map-*.md).

Symbol sync status#

GoG rename progress (approximate):

Metric GoG Retail
lotr2_* refs ~17,380 ~30,177
FUN_* refs remaining ~3,796 0

Phases completed for ui, startup, game, gfx, map, combat; net deferred. Live queue: architecture/gog-sync-progress.md.

Evidence workflow#

Retail rename track#

  1. Identify behavior in src/LORDS2.EXE.c.
  2. Rename to lotr2_<area>_<purpose> per architecture/RENAME_WORKFLOW.md.
  3. Record in architecture/symbol-map.md.

GoG parallel track#

  1. Map behaviorally from retail names:
python3 tools/ghidra/map_gog_symbols.py --subsystem <ui|startup|game|gfx|map|combat>
  1. Apply renames to GoG export:
python3 tools/ghidra/apply_gog_renames.py --subsystem <name>
  1. Update architecture/gog-sync-progress.md.

Do not rename lotr2_net_* on GoG until ASIGS mapping exists.

Build-specific table dumpers#

Tool Builds Purpose
dump_combat_tables.py --all retail + GoG Auto-calc multiplier and casualty tables
dump_skirmish_tables.py GoG only Skirmish preset army / scenario tables

These dump PE sections from on-disk binaries (bin/LORDS2.EXE, gog/Lords2.exe when present); they are not general binary diff tools.

Interop notes for reimplementers#

  1. Pick a target build (retail, GoG, or both) before implementing build-specific tables, MP stack, or skirmish.
  2. Campaign + tactical combat — high behavioral parity expected between builds once the same formulas and tables are keyed to the correct binary.
  3. Multiplayer — retail DirectPlay and GoG ASIGS are not wire-compatible; separate protocol implementations are required.
  4. Skirmish — GoG-only; retail clients cannot join skirmish sessions.
  5. Saves and assets — treat as shared until proven otherwise; flag any format divergence in spec interop notes when found.
Topic Path
Binary hashes and exports METADATA.md
Retail symbol map architecture/symbol-map.md
GoG symbol map index architecture/gog-symbol-map.md
GoG sync progress architecture/gog-sync-progress.md
Skirmish (GoG) skirmish/README.md
Auto-calc spec (both builds) spec/combat/auto-calculation.md
Retail DirectPlay protocols protocols/dplay.md
Architecture modules architecture/README.md

Open gaps#

  • GoG SHA-256, file size, and Ghidra export metadata — TBD in METADATA (PE not in repo; only Ghidra .c export).
  • ASIGS protocol — no docs/protocols/asigs.md yet; skirmish MP evidence in skirmish/multiplayer-pvp.md.
  • Incomplete GoG symbol coverage — ~3,796 FUN_* remain; net subsystem entirely deferred.
  • Struct validation — many layouts validated at retail VAs; GoG re-validation noted only where touched (e.g. structs/lotr2_player_record.md).
  • Normative skirmish spec — evidence under docs/skirmish/; not yet under docs/spec/.