docs/OPENKH_REFERENCE.md

OpenKH Reference Guide

OpenKH (~/openkh) is an open-source KH2 modding toolkit. It is primarily a file-format parser and asset editor, not a runtime memory manipulation project. However, several components are directly useful for our co-op mod.

This document maps what OpenKH has to what we need and when to consult it.


High-Value Resources

Panacea — DLL Injection Framework

Path: openkh/OpenKh.Research.Panacea/

A C++ DLL that injects into the running KH2 process and hooks game functions. Provides per-frame callbacks and a DLL loader system.

FileWhat it has
OpenKH.cppPattern scanning to find game functions via byte signatures (version-resilient)
Panacea.cppHook<TFunc> template for function hooking; MyAppVtbl with onFrame, onInit, onSoftReset vtable; DLL loader that calls OnInit/OnFrame exports
KingdomApi.hC++ struct types for game file I/O internals; VarPtr<T> / ArrayPtr<T,N> for resolving game variable pointers
dllmain.cppDLL entry point and initialization

When to consult: If we decide to move from external ReadProcessMemory to in-process DLL injection for better performance (eliminates camera flicker, avoids cross-process overhead). Our multiplayer DLL could be loaded as a Panacea plugin with OnInit/OnFrame exports.

Motion / Animation IDs

Path: openkh/OpenKh.Kh2/MotionSet.cs

Partial enum of the KH2 animation indexes. The damage block (10-24) was checked against OpenKH/OpenKh b67a7434 (VUH-2912, Ione 5fb4a767); the boss target ledger pins Axel II's damage motions from it:

IDLE=0, WALK=1, RUN=2, JUMP=3, FALL=4, LAND=5, LINK_IDLE=6,
DAMAGE_S_FRONT_HIGH=10, DAMAGE_S_FRONT_LOW=11, DAMAGE_S_BACK_HIGH=12, DAMAGE_S_BACK_LOW=13,
DAMAGE_AIR_FRONT=14, DAMAGE_AIR_BACK=15, DAMAGE_BLOW_FRONT=16, DAMAGE_BLOW_FRONT_LAND=17,
DAMAGE_BLOW_BACK=18, DAMAGE_BLOW_BACK_LAND=19, DAMAGE_TORNADO_FRONT=20, DAMAGE_TORNADO_BACK=21,
DAMAGE_TORNADO=22, DAMAGE_LARGE_FRONT=23, DAMAGE_LARGE_BACK=24,
REFLECT=41, AUTOGUARD=42, APPEAR=44, LEAVE=45,
TURN_L=48, TURN_R=49, TALK=50, CHANGEFORM=52,
MAGIC_FIRE1-3=56-58, MAGIC_BLIZZARD1-3=59-61,
MAGIC_THUNDER1-3=62-64, MAGIC_CURE1-3=65-67,
DEAD_LAND=131, DEAD_AIR=132,
EX000-EX100=151-251 (extended/custom),
RTN_00-RTN_09=283-292 (return animations)

When to consult: When implementing animation sync between clients (M4+). These IDs map to the animation state value in the entity struct, which we'll need to read/replicate.

Object Type Taxonomy

Path: openkh/OpenKh.Kh2/Objentry.cs

Defines object types used by the game engine:

TypeValueDescription
PLAYER0Sora / Roxas / player-controlled
FRIEND1Donald, Goofy, world partners
NPC2Non-combat NPCs
BOSS3Boss entities
ZAKO4Regular enemies
WEAPON5Weapon models
E_WEAPON6Enemy weapons
SP7Special objects
F_OBJ8Field objects
BTLNPC9Battle NPCs
CHEST10Treasure chests
MAPTOOL11Map interaction objects
WORLD_MAP12World map
PRIZEBOX13Prize boxes / drops
SUBMEMBER14Sub-members
SHOP15Shop keepers

Also defines ObjectForm: Sora=0, Valor=1, Wisdom=2, Limit=3, Master=4, Final=5, Anti=6.

When to consult: During entity discovery RE — to identify entity type bytes in memory and distinguish player from friend/NPC/enemy entities.

Member Table (MEMT)

Path: openkh/OpenKh.Kh2/SystemData/Memt.cs

Defines how party slots are mapped per world/story-flag:

  • MemberIndices: Player, Friend1, Friend2, FriendWorld (byte indices)
  • Each entry maps WorldId + StoryFlag to a Members[] array
  • Members array positions: Sora, Donald, Goofy, WorldChar, Valor, Wisdom, Limit, Master, Final, Anti, Mickey, SoraHigh, etc.

When to consult: When implementing Friend1/Friend2 entity discovery — this tells us which character object ID occupies each party slot in each world.

Character Slot Indices

Path: openkh/OpenKh.Kh2/Battle/Lvup.cs

Character index mapping (used in battle tables and unit slots):

Sora=0, Donald=1, Goofy=2, Mickey=3, Auron=4,
Ping/Mulan=5, Aladdin=6, Sparrow=7, Beast=8,
Jack=9, Simba=10, Tron=11, Riku=12

These 13 indices correspond to the character slots in the battle system.

When to consult: When mapping our SlotType (Player/Friend1/Friend2) to the game's internal character index system.

Attack Parameters

Path: openkh/OpenKh.Kh2/Battle/Atkp.cs

Complete attack parameter struct: Power, Element, KnockbackStrength, Team, HitSfx, various flags (ComboFinisher, AirCombo, Reaction, etc.)

When to consult: When implementing damage synchronization (M5 — enemy replication). Needed to understand how attacks interact with the HP system.

World ID Constants

Path: openkh/OpenKh.Kh2/Constants.cs

All 19 world IDs with names and short codes:

0=WorldZz, 1=EndOfSea, 2=TwilightTown ("tt"), 3=DestinyIsland ("di"),
4=HollowBastion ("hb"), 5=BeastCastle ("bb"), 6=TheUnderworld ("he"),
7=Agrabah ("al"), 8=LandOfDragons ("mu"), 9=HundredAcreWood ("po"),
10=PrideLands ("lk"), 11=Atlantica ("lm"), 12=DisneyCastle ("dc"),
13=TimelessRiver ("wi"), 14=HalloweenTown ("nm"), 15=WorldMap ("wm"),
16=PortRoyal ("ca"), 17=SpaceParanoids ("tr"), 18=WorldThatNeverWas ("eh")

When to consult: For debugging room transitions and world-specific behavior.


Reference-Only Resources

These are useful as background knowledge but not directly used at runtime.

Hypervisor (C# Memory Reader)

Path: openkh/Hypervisor/Hypervisor.cs

C# equivalent of our GameBridgePC — uses ReadProcessMemory / WriteProcessMemory with base offset. Confirms our approach is correct. Uses EOSSDK-Win64-Shipping.dll module for Epic Games Store version detection.

Binarysharp.MSharp (Process Memory Library)

Path: openkh/Binarysharp.MSharp/

Full .NET memory editing library. Has pointer chain resolution (RemotePointer), remote allocation (RemoteAllocation), and memory protection handling. Useful reference for our C++ pointer chain code.

Save Data Layout

Path: openkh/OpenKh.Kh2/SaveData/SaveDataFinalMix.cs

Complete FM save file offsets:

  • 0x0C: WorldId, 0x0D: RoomId, 0x0E: SpawnId
  • 0x24F0: Characters[13] (0x114 bytes each)
  • 0x32F4: DriveForms[10]
  • 0x36E0: Experience

When to consult: If we ever implement save-state synchronization.

File Format Documentation

Path: openkh/docs/kh2/

Extensive markdown docs for on-disk file formats:

  • file/type/00objentry.md — Object entry table
  • file/type/00battle.md — Battle system tables
  • file/type/03system.md — System tables (CMD, ARIF, MEMT)
  • file/type/areadata.md — Area data scripts
  • dictionary/ — Character, object, and enemy dictionaries

These describe file formats, not runtime memory layouts. The in-memory representation may differ from the on-disk format.


What OpenKH Does NOT Have

What we needOpenKH has?Notes
Runtime entity position offsetsNoWe found these via CE (Session 3)
Camera struct layoutNoWe found this via CE (Camera RE Session)
Input injection addressesNoIInput is an abstract interface
Enemy list pointer chainNoOnly file-format enemy tables
Entity struct vtable layoutNoOnly file-level object definitions
Buffer array layoutNoWe found this via CE (Session 3)

Our KH2Offsets.hpp and Cheat Engine sessions are the authoritative source for runtime memory layouts. OpenKH complements this with game-design-level knowledge (what types of objects exist, how party slots work, animation IDs).


Architecture Consideration: Panacea vs External Process

Current approach: External process (ReadProcessMemory / WriteProcessMemory)

  • Pros: Simple, no injection risk, easy to develop/debug
  • Cons: Cross-process overhead, camera writes flicker, can't hook functions

Potential future approach: Panacea DLL plugin

  • Pros: In-process access (zero overhead), per-frame hooks, can intercept game functions directly (e.g., redirect camera copy at instruction level)
  • Cons: More complex development, crash risk, version coupling

Decision deferred — external process works for M1-M2. Consider Panacea for M3+ if input injection or camera stability requires in-process hooks.