Conversation
- Add GameIdentity.hpp/cpp: Runtime game detection from exe name, TDB version mapping, engine parameter derivation (replaces compile-time RE2/RE3/RE4/.../REENGINE_PACKED/REENGINE_AT/TDB_VER macros) - Restructure cmake.toml: Single REFrameworkSDK + REFramework targets replace ~30 per-game SDK+DLL targets. Define REFRAMEWORK_UNIVERSAL. - Add PLAN_V2_MONOLITHIC.md documenting architecture decisions.
…runtime dispatch - Mods.cpp: All conditional mod registration uses GameIdentity runtime checks - REFramework.hpp: get_game_name() delegates to GameIdentity - Main.cpp: Startup guards use GameIdentity; initialize() called early - PluginLoader.cpp: game_name set at runtime in initialize_plugins() - ReClass.hpp: REFRAMEWORK_UNIVERSAL includes RE8 layout as canonical base - TDBVer.hpp: REFRAMEWORK_UNIVERSAL sets TDB_VER=84 so all code paths compile
…in src/ Batch conversion of game-specific preprocessor guards across 25 source files: Camera, FreeCam, FirstPerson, ManualFlashlight: - #ifdef RE8, RE2, RE3, RE4 → runtime gi.is_re8() etc. Graphics, Hooks, REFrameworkConfig, ExceptionHandler: - #ifdef SF6, MHWILDS, RE4, RE7 → runtime checks - Member declarations gated with REFRAMEWORK_UNIVERSAL IntegrityCheckBypass: - Heavy per-game byte pattern ifdefs → runtime if/else if chains RE8VR: - Removed file-level #if defined(RE7)||defined(RE8) guard - Added runtime early return in on_initialize() - Internal RE7/RE8 guards → runtime checks VR.cpp: - Regenny include chain → REFRAMEWORK_UNIVERSAL block - ~35 game guards → runtime checks ObjectExplorer, ChainViewer, LooseFileLoader: - TDB_VER and game guards → runtime checks REFramework.cpp: - DD2/MHRISE/TDB_VER >= 74 guards → runtime checks
…mbers, legacy TDB guards - GameIdentity.hpp: Move static inline members to .cpp (incomplete type error) - REFramework.cpp: Fix brace nesting in ldr_notification_callback - FirstPerson.cpp: Fix missing closing braces in constructor and on_lua_state_created - Graphics.cpp: Fix missing closing braces in on_pre/on_application_entry - ObjectExplorer.cpp: Guard legacy TDB struct member access with #ifndef REFRAMEWORK_UNIVERSAL - CMakeLists.txt: Regenerated by cmkr from updated cmake.toml (single unified target)
REType is 0x60 in most games but 0x68 in MHWILDS/RE9, with fields shifted by 8 bytes after offset 0x28 (super, childType, chainType, fields, classInfo, size, typeCRC all at different offsets). - Add RETypeLayouts.hpp: defines reclass_mhwilds::REType (0x68 layout) and accessor functions in utility::re_type_accessor namespace that check GameIdentity at runtime and cast to the correct layout - Replace all direct REType field accesses in shared/sdk/ and src/ with accessor calls (get_super, get_classInfo, get_fields, get_size, get_typeCRC, get_childType, get_chainType) - REType.cpp, REManagedObject.cpp, REArray.cpp, RETypeDefinition.cpp, PluginLoader.cpp, ObjectExplorer.cpp updated - REObjectInfo->classInfo and ParsedType->super accesses left untouched (different structs, same offset in all layouts)
Games with TDB < 73 (RE2, RE3, RE8, RE7, MHRISE) use 18-bit TYPE_INDEX_BITS, but the universal build compiles with 19-bit. The bitfield packing differs, causing all RETypeDefinition field reads to return garbage on those games. - Add RETypeDefDispatch.hpp: defines tdb_bits18::RETypeDefVersion69 with hardcoded 18-bit field widths, and TDEF_FIELD/TDEF_FIELD_SET macros for runtime dispatch based on GameIdentity::tdb_ver() - Replace ~33 bitfield accesses in RETypeDefinition.cpp with TDEF_FIELD macro (impl_index, declaring_typeid, parent_typeid, generics, index, object_type, member_method, member_field, member_prop, num_member_prop, type, managed_vt) - Non-bitfield fields at same offset (type_flags, size, fqn_hash, type_crc) left as direct access Note: REField and REMethodDefinition also use TYPE_INDEX_BITS bitfields and will need similar treatment for full functionality.
…ld dispatch - RETypeDB: All pointer field accesses (types, methods, fields, etc.) now dispatch through get_*_ptr() helpers that cast to tdb70::TDB for games with TDB < 73 - RETypeDB: Count accessors (get_num_types, etc.) dispatch similarly - REMethodDefinition: get_method() uses byte-offset arithmetic with correct stride (16 bytes for tdb69, 12 bytes for tdb84) - MethodIterator: Refactored to index-based iteration to handle variable stride - REMethodDefinition: get_function() returns direct function pointer for tdb69 - REMethodDefinition: declaring_typeid, impl_id accessed via TMETH_FIELD dispatch - REMethodDefinition: get_param_index() dispatches params vs params_lo/params_hi - REField: declaring_typeid, impl_id accessed via TFIELD_FIELD dispatch - REField: get_type() casts to tdb69::REFieldImpl for field_typeid - REField: get_init_data_index() casts to tdb69::REFieldImpl for init_data split - REField: get_offset_from_fieldptr() reads from tdb69 REField69::offset - ObjectExplorer: All direct tdb-> accesses replaced with dispatched accessors - RETypeDefDispatch.hpp: Added REMethodDef69, REField69, TMETH_FIELD, TFIELD_FIELD
…ect, Renderer, REContext - RETypeDefDispatch.hpp: Added REParamDef69 (18-bit type_id) and TPARAM_FIELD macro - RETypeDB.cpp: All p.type_id accesses use TPARAM_FIELD dispatch for 18 vs 19 bit - RETypeDB.cpp: REField::get_data_raw vtable optimization gated to tdb_ver >= 81 - RETypes.cpp: game_namespace() returns correct prefix per game at runtime - REManagedObject.cpp: is_managed_object/get_type/get_vm_type dispatch tdb_ver >= 71 - Renderer.hpp: Struct offsets (d3d12 resource, scene layers, output state) runtime dispatch - REContext.cpp: Static table fixup gated to tdb_ver >= 71
…matrix dispatch - Application.hpp: Function struct gets accessor methods (get_description, get_priority, get_type_val) that read from correct offsets (TDB < 74: +8 byte shift from extra void*) - Application.cpp: get_function_stride() returns 0xD0 for TDB < 74, 0xC8 for TDB >= 74 - Application.cpp: All Function array iteration uses get_function_at() stride-aware indexing - Application.cpp: All field accesses use accessor methods - Hooks.cpp: entry->description -> entry->get_description() - VR.cpp: func->description -> func->get_description() - RETransform.hpp: Joint matrix access dispatches between RE2/RE3 (jointMatrices at 0xC0) and RE8+ (joints.matrices at 0xE0) via get_joint_matrices() helper
- RETypeDefinition.cpp: get_fieldptr_offset() uses direct managed_vt for TDB < 81 - RETypeDefinition.cpp: has_fieldptr_offset() checks TDEF_FIELD(managed_vt) for TDB < 81 - RETypeDefinition.cpp: get_managed_vt() skips abstract-type parent walk for TDB < 81
Runtime dispatch conversions: - ResourceManager.cpp: TDB_VER < 81/73 byte-pattern scans for create_userdata - Hooks.cpp: TDB_VER < 74 hook_update_before_lock_scene, >= 73 PrimitiveSystem guard - Graphics.cpp: regenny header selection, TDB_VER < 73 backbuffer write - Renderer.hpp: DRAW/UPDATE_VTABLE_INDEX, NUM_PRIORITY_OFFSETS as runtime fns, DirectXResource offset, TargetState::Desc pad, RenderLayer layout, RE4 lod_bias - Renderer.cpp: NUM_PRIORITY_OFFSETS loop - RETypes.cpp: >= 73 type-list finder - VR.hpp: m_allow_engine_overlays, m_enable_asynchronous_rendering defaults - Graphics.hpp: m_ultrawide_custom_fov default - RETypeDB.cpp: REModule get_methods/instantiated/member_references via tdb74 cast - RETypeDB.hpp: REModule stride-aware get_module_at(), get_module_stride() Bug fixes: - REModule array indexing stride mismatch: tdb81 is 0x40 bytes, tdb74 is 0x58. get_module() now uses stride-aware access for universal builds. Cleanup: - Application.cpp: removed temporary debug logging from get()
Window and SceneView structs have different field offsets per game (RE2/RE3/RE8/RE4 etc. all differ). The universal build previously always used RE9 headers, giving wrong offsets for other games. New ViaDispatch.hpp provides runtime accessor functions that dispatch by GameID. Graphics.cpp and VR.cpp updated to use these accessors under REFRAMEWORK_UNIVERSAL.
…lity Instead of hardcoded offset tables, each game's regenny Window/SceneView headers are included inside distinct outer namespaces (ns_re7, ns_re3, ns_re2, etc.). Dispatch functions cast to the correct namespaced struct type at runtime. When Regenny regenerates a header, offsets update automatically through the struct layout — no manual table maintenance. re9 headers use the globally-included versions (already present via Graphics.cpp/VR.cpp) to avoid #pragma once conflicts.
Two bugs causing RE4/SF6/MHRISE/DD2 to fail (Renderer type not found): 1. needs_18bit() threshold was tdb_ver < 73, but TDB 71+ (RE4/SF6/MHRISE/DD2) uses 19-bit TYPE_INDEX_BITS. Changed to tdb_ver < 71. 2. get_type(index) used sizeof(RETypeDefVersion84) = 0x50 as stride, but TDB 71-73 games have sizeof(RETypeDefVersion71) = 0x48 (no unk_new_tdb74_uint64 field). Added get_typedef_stride() and stride- aware access in get_type(). Stride map: TDB 69-70 (RE2/RE3/RE7/RE8): 0x50 (18-bit bitfields, V69 layout) TDB 71-73 (RE4/SF6/MHRISE/DD2): 0x48 (19-bit, no extra uint64) TDB 74+ (MHWILDS/RE9/PRAGMATA): 0x50 (19-bit, has unk_new_tdb74_uint64)
…r strides Architecture change: every TDB version struct now has hardcoded bit widths (no dependency on TYPE_INDEX_BITS / FIELD_BITS macros). This makes each struct self-contained and correct regardless of compile-time macro values. Changes: - V84/V83/V82/V74: hardcoded 19-bit TYPE_INDEX, 20-bit FIELD - V71: hardcoded 19-bit TYPE_INDEX, 19-bit FIELD (no unk_new_tdb74_uint64) - V69: hardcoded 18-bit (was in tdb_bits18 namespace, now the main struct) - V67: split into V67 (DMC5, bitfield variant) and V67_RE3 (plain uint32) - V66/V49: hardcoded 16-bit Dispatch: - TDEF_FIELD: 3-way dispatch (V69 for <71, V71 for 71-73, V84 for 74+) - get_typedef_stride(): sizeof(RETypeDefVersion*) instead of 0x48/0x50 - get_method_stride(): sizeof(tdb69/tdb84::REMethodDefinition) - tdb_bits18 namespace reduced to backward-compat aliases
…nitions Every tdb namespace struct now has hardcoded bit widths: - tdb84 through tdb71: 19-bit TYPE_INDEX (was macro, same value) - tdb69: 18-bit (BUG FIX — was evaluating to 19 under universal build) - tdb67: 17-bit (BUG FIX — was evaluating to 19 under universal build) - tdb66: 16-bit (BUG FIX — was evaluating to 19 under universal build) The tdb69/67/66 fixes are correctness bugs: under REFRAMEWORK_UNIVERSAL TYPE_INDEX_BITS=19, so REField/GenericListData/REMethodDefinition structs in those namespaces had wrong bitfield widths. This caused silent corruption when reading older-format TDB data via dispatch macros.
TDB header accessors (get_num_types, get_num_methods, get_types_ptr, get_modules_ptr, etc.) now switch on tdb_ver() with explicit casts to tdb70/tdb71/tdb73/tdb74/tdb81/tdb82/tdb83/tdb84 TDB structs. Replaces the old needs_18bit()-only two-branch dispatch that was wrong for TDB 71-73 (e.g. RE4 reading 'initialized' instead of numTypes). RETypeImpl field accesses (num_member_methods, num_member_fields) in RETypeDefinition.cpp now use TIMPL_DISPATCH which dispatches to the correct tdb69/tdb71/.../tdb84 RETypeImpl struct. Fixes the RE2 bug where offset 0x18 in tdb69 data read interface_id (0xFFFF=65535) instead of num_member_methods at offset 0x12.
tdb69::TDB has no 'void* unk' field between initData and attributes2, so stringPool/bytePool/internStrings are at different offsets than tdb70. Casting RE8's TDB to tdb70::TDB read garbage stringPool pointer causing infinite loop during initialization.
Root cause: find_type() set map_populated=true BEFORE iterating types. On TDB 67, get_full_name() throws for ~66% of type indices (corrupt/unresolvable names in pre-impl TDB layout). The first exception propagated out, leaving map_populated=true with an empty map. All subsequent find_type() calls returned nullptr immediately. Fix: - Move map_populated=true AFTER the iteration loop completes - Wrap individual type name resolution in try/catch so corrupt indices are skipped without aborting the entire map build - ~21K of 62K types populate successfully, including all critical types (via.Application, via.io.file, etc.) Verified: DMC5 now fully initializes (hooks, D3D11, config save). RE2 regression test passes.
…onversion - Add tmeth_declaring_typeid() / tfield_declaring_typeid() inline functions for 3-tier dispatch: tdb67 (17-bit) / tdb69 (18-bit) / tdb84 (19-bit) - Replace TMETH_FIELD/TFIELD_FIELD(this, declaring_typeid) with new functions in RETypeDB.cpp and ObjectExplorer.cpp - Convert all #ifndef REFRAMEWORK_UNIVERSAL guards in ObjectExplorer.cpp to runtime tdb67:: casts for method params, fields, properties - Fixes ~66% type name resolution failures on DMC5 (TDB 67) caused by reading declaring_typeid with wrong bit width
RE3 has an extra 8-byte pad after cameraControllerInfos (0x58) in RopewayCameraSystem, shifting all subsequent fields +8 vs RE2/RE8: cameraController: 0x98 (RE8) vs 0xA0 (RE3) mainCamera: 0xC0 (RE8) vs 0xC8 (RE3) playerJoint: 0xE0 (RE8) vs 0xE8 (RE3) mainCameraController: 0xE8 (RE8) vs 0xF0 (RE3) Added CameraSystemDispatch.hpp with CAMSYS() macro that dispatches to the correct struct layout at runtime via GameIdentity::is_re3(). Replaced all 58 shifted field accesses in FirstPerson.cpp. Fixes access violation (c0000005) in FirstPerson::update_pointers_from_camera_system that occurred ~6s after RE3 startup.
…troller + RETransform joints RE2 RopewayPlayerCameraController has fields shifted -0x10 vs RE8/RE3: activeCamera: 0xA8 (RE2) vs 0xB8 (RE8) — confirmed via TDB reflection cameraParam: 0xB8 (RE2) vs 0xC8 (RE8) pitch/yaw: 0x108/0x10C vs 0x118/0x11C Added CAMCTRL() dispatch macro and sdk::re2::RopewayPlayerCameraController_RE2 struct in CameraSystemDispatch.hpp. Replaced 18 field accesses in FirstPerson.cpp. RE2 RETransform has REJointArray at 0xD0 (vs 0xD8 in RE8). The get_joint() and get_all_children() functions read transform.joints.data at the RE8 offset, causing joint lookups to fail on RE2 — head bone never found, never zeroed. Added get_joint_array_data() dispatcher in RETransform.hpp and rewrote get_joint()/get_all_children() to use it for REFRAMEWORK_UNIVERSAL builds.
RE3's RopewayMainCameraController has extra cameraDampingCameraPosition field at 0x90, shifting all subsequent fields +0x10 vs RE2/RE8: cameraRotation: 0x90 (RE8) vs 0xA0 (RE3) mainCamera: 0xD0 (RE8) vs 0xE0 (RE3) switchInterpolationTime: 0xB0 (RE8) vs 0xC0 (RE3) Added MAINCAM() dispatch macro and RopewayMainCameraController_RE3 struct in CameraSystemDispatch.hpp. Replaced 8 field accesses in FirstPerson.cpp.
PRAGMATA_SKETCHBOOK.exe uses TDB 83 (confirmed from runtime TDB header). GameIdentity hardcoded 84 (matching the unreleased full game), causing dispatch macros to hit the tdb84 default path instead of case 83. TODO: Read TDB version from binary at runtime and override the hardcoded value, making the universal build resilient to demo/trial TDB mismatches. asdf
105 static_asserts across RETypeDB.hpp proving: - REMethodImpl: all 5 field offsets match tdb84 in tdb69-tdb83 (35) - REPropertyImpl: all 3 field offsets match tdb84 in tdb69-tdb83 (21) - REFieldImpl: attributes_id offset stable across tdb69-tdb83 (7) - REParameterDef: attributes_id + init_data_index stable (14) - RETypeImpl: name_offset + namespace_offset match tdb82 in tdb69-tdb81 (10) - RETypeImpl: field_size offset stable across tdb69-tdb83 (7) - REMethodDefinition: sizeof stable tdb71-tdb83 vs tdb84 (6) - REField: sizeof stable tdb71-tdb83 vs tdb84 (6) - REProperty: sizeof stable tdb69-tdb83 vs tdb84 (7) - REModule: types_start/count/name offsets match tdb74 vs tdb81 (4) Every macro that casts to a single TDB version without runtime dispatch now has compiler-verified proof that the assumption holds. Also fixes incorrect comment on RFIELDIMPL_FIELD: init_data_lo is NOT stable across versions (14 bits tdb69 vs 6 bits tdb84).
Static proof for all layout assumptionsCommits Every macro that casts to a single TDB version without runtime dispatch now has compiler-verified proof that the assumption holds. If a future TDB version moves a field or changes a struct size, the build fails with the exact type and field name. 105 static_asserts in RETypeDB.hppoffsetof — field position proof (non-bitfield members):
sizeof — struct size proof (bounds bitfield repacking):
Total: 140 static_asserts (35 impl sizes from prior commit + 105 new offsetof/sizeof). Also in this batch
|
Private fields on all three types. Compiler rejects direct ->field access.
RETransform (shared/sdk/types/RETransform.hpp):
- Stable-offset accessors: get_position(), get_angles(), get_scale(),
get_world_transform(), get_child(), get_next(), get_parent_transform()
- get_joints() retains UNIVERSAL runtime dispatch (0xD0 vs 0xD8)
- REJointArray also extracted
REObjectInfo (shared/sdk/types/REObjectInfo.hpp):
- get_class_info() — classInfo at offset 0x00, stable across all versions
- get_type_fn() — dispatches TDB67 (0x10) vs TDB69+ (0x18)
- REObjectInfo.cpp has UNIVERSAL implementation
REClassInfo (shared/sdk/types/REClassInfo.hpp):
- get_type() — dispatches TDB67 (0x68) / TDB69-80 (0x40) / TDB81+ (0x38)
- get_parent_info() — dispatches TDB67 (0x70) / TDB69-80 (0x48) / TDB81+ (0x40)
- get_object_type(), get_object_flags(), get_size(), etc.
- REClassInfo.cpp has UNIVERSAL implementations
CI: dev-release.yml split into REFramework.zip (DLL only) + VR.zip
(openvr_api.dll + openxr_loader.dll). Nightly produces 3 artifacts.
Consumer migration: 30+ direct field accesses replaced across
REManagedObject.cpp, Renderer.cpp, REContext.cpp, RETransform.cpp,
FirstPerson.cpp, FreeCam.cpp, VR.cpp, IntegrityCheckBypass.cpp,
ObjectExplorer.cpp.
Verified: builds clean, clang audit 0 violations, DMC5 (TDB 67)
smoke test passes with full assembly generation.
REClassInfo was the old name for RETypeDefinition before the TDB was fully researched. They are the same runtime struct at the same address. Under REFRAMEWORK_UNIVERSAL, REClassInfo is now an empty opaque struct. All consumer code casts to sdk::RETypeDefinition* and uses its methods: - class_info->get_type() → ((RETypeDefinition*)class_info)->get_type() - class_info->parentInfo → ((RETypeDefinition*)class_info)->get_managed_vt() - class_info->objectFlags → get_type_definition(obj)->get_vm_obj_type() Deleted REClassInfo.cpp (dispatch code no longer needed). Removed classinfo_accessor namespace (redundant with RETypeDefinition). Guarded TypeListArray with #ifndef REFRAMEWORK_UNIVERSAL (dead ReClass artifact). Verified: DMC5 (TDB 67) smoke test passes — full assembly generation.
Type header extraction + REClassInfo elimination + nightly split + full 20-game smoke testCommits RETransform, REObjectInfo, REClassInfo extracted to type headersAll three types extracted from RETransform — private fields, stable-offset accessors ( REObjectInfo — private fields. REClassInfo — eliminated. It's the same runtime struct as // Before:
class_info->get_parent_info() // custom dispatch code
class_info->get_type() // custom dispatch code
class_info->objectFlags >> 5 // raw field access
// After:
((sdk::RETypeDefinition*)class_info)->get_managed_vt() // already dispatched
((sdk::RETypeDefinition*)class_info)->get_type() // already dispatched
get_type_definition(object)->get_vm_obj_type() // already dispatchedDeleted CI nightly split
Full 20-game smoke test
20/20 boot and initialize. 18/20 full assembly generation. GGR and Onimusha2 have Consumer migration tally30+ direct field accesses replaced across 9 files: |
154 conditional blocks stripped across 28 files. Only the REFRAMEWORK_UNIVERSAL code paths remain. TDB49 (RE7) reference paths preserved for future support. Removed: - All #else/#elif TDB_VER branches under #ifdef REFRAMEWORK_UNIVERSAL - All #if TDB_VER conditions that are always true/false for TDB_VER=84 - All #ifndef REFRAMEWORK_UNIVERSAL dead blocks - Non-universal macro pass-throughs in RETypeDefDispatch.hpp - Legacy per-game TDB_VER/TYPE_INDEX_BITS definitions in TDBVer.hpp Kept (TDB49 reference): - TDBVer.hpp legacy block (contains RE7_TDB49 paths) - REManagedObject.cpp TDB49 paths (info->size, different validation) - RETypeDB.cpp TDB > 49 guards on init_data/byte pool access - RETypeDefinition.cpp TDB <= 49 special cases Verified: builds clean, DMC5 boots and resolves all singletons.
worldPos2ScreenPos method not found on RE9 (different signature?). Add null check before calling. Pre-existing bug, not a regression.
Fixed strip script: TDB_VER > 49 is NOT a TDB49 reference (it means 'everything except old RE7'). Added orphaned #elif handler for chains left behind by first pass. Removed orphaned #elif TDB_VER chains in REManagedObject.cpp, RETypeDB.cpp, RETypeDefinition.cpp, Renderer.cpp/hpp, MotionFsm2Layer.hpp. Remaining #ifdef REFRAMEWORK_UNIVERSAL blocks all contain TDB49 references (RE7 support) or are structural (RETypeDB.hpp versioned struct definitions, TDBVer.hpp legacy builds, ReClass.hpp includes). Total dead code removed across both passes: ~2169 lines.
Dead code removal — 2169 lines of non-universal preprocessor paths strippedCommits What was removedEvery
What remainsAll remaining
One known gap: RE7 TDB49 invoke wrapper code ( Also in this batchGameObjectsDisplay null deref fix ( Verification
|
The behavior tree headers (regenny/mhrise_tdb71/) only work for TDB >= 69. DMC5 (TDB 67) has different struct layouts (TreeNode 0xC8 vs 0xD0, no parent_condition field, name at different offset). Runtime dispatch using regenny/re3/ headers under a separate namespace is needed to support behavior tree editing on DMC5. Added TODO.
TreeNode, TreeNodeData, TreeObject, TreeObjectData no longer inherit from regenny structs. They are opaque classes with offset-dispatching accessors that branch on needs_legacy_bhvt() (tdb_ver < 69). Key layout differences dispatched: TreeNode: name/status1/status2 shifted +8 (parent_condition inserted) TreeNodeData: tags/name shifted +0x10 TreeObjectData: action_methods/static_action_methods shifted +0x30 TreeObject: selectors shifted +4, root_node 0xA0 vs 0xC0 Stride-aware iteration for node arrays (0xC8 vs 0xD0 per TreeNode). Lua bindings updated to use sol::property with getter methods. Direct field access compiler-rejected on all 4 types. Verified: builds clean.
Behavior tree runtime dispatch — DMC5 TDB67 support restoredCommit The behavior tree subsystem was compiled against TDB69+ struct layouts (mhrise_tdb71 regenny headers). In v1 per-game builds, DMC5's DLL compiled with TDB67 headers so this was never a problem — each game got its own correct layout. In the v2 monolithic build, DMC5 runs with the TDB69+ compiled layout, reading wrong offsets for node names, statuses, and other fields. This commit adds runtime dispatch so the correct offsets are used for each game. What changedTreeNode, TreeNodeData, TreeObject, TreeObjectData no longer inherit from regenny structs. They are opaque classes with offset-dispatching accessors that branch on
Stride-aware iteration for node arrays (0xC8 vs 0xD0 per TreeNode). Lua bindings updated to use BehaviorTree, CoreHandle, Core, MotionFsm2Layer are identical across versions — kept regenny inheritance. Verified
|
Chain::CollisionData is at 0x58 (TDB < 71) vs 0x60 (TDB >= 71). ChainViewer was hardcoded to re2_tdb70 layout (0x58), reading wrong offset on MHRise/SF6/DD2/RE4 and all TDB71+ games. Added get_chain_collision_data() dispatcher. All chain->CollisionData accesses now go through it.
ChainViewer runtime dispatch — full offset dispatch for all chain structsCommit The ChainViewer was hardcoded to
The crash on DMC5 was: array indexing FixZero direct regenny struct field access. All chain data goes through dispatch accessors:
Verified
|
176 call sites migrated. get_field<T> renamed to get_reflection_property<T> to avoid confusion with the plugin API's get_field (which stays unchanged). Free functions → member methods: get_type_definition(obj) → obj->get_type_definition() is_managed_object(addr) → REManagedObject::is_managed_object(addr) is_a(obj, name) → obj->is_a(name) add_ref(obj) → obj->add_ref() release(obj) → obj->release() get_type(obj) → obj->get_type() get_size(obj) → obj->get_size() get_vm_type(obj) → obj->get_vm_type() get_field<T>(obj, f) → obj->get_reflection_property<T>(f) etc. namespace utility::re_managed_object deleted entirely. Plugin API (include/reframework/API.h, API.hpp) untouched. Verified: builds clean.
ik_leg->call_method("set_CenterAdjust", value) instead of
REManagedObject::call_method(ik_leg, "set_CenterAdjust", value).
4 call sites updated.
|
| Game | TDB | Types |
|---|---|---|
| DMC5 | 67 | 20,349 |
| RE8 | 69 | 23,978 |
| RE2 | 70 | 13,432 |
| RE3 | 70 | 15,045 |
| RE7 | 70 | 15,404 |
| RE4 | 71 | Full gen |
| MHRise | 71 | Compiling |
| SF6 | 71 | ✅ |
| DD2 | 73 | Compiling |
| DRDR | 73 | Compiling |
| Kunitsu | 73 | 6,992 |
| Onimusha2 | 74 | 6,606 |
| Starforce | 78 | Compiling |
| MHWilds | 81 | Compiling |
| RE9 | 83 | Compiling |
| Pragmata Sketchbook | 83 | 18,364 |
| Pragmata | 83 | 18,480 |
All 21 game installs boot, initialize, and generate assemblies. Zero crashes.
14 call sites: obj->get_name() instead of utility::re_game_object::get_name(obj). namespace utility::re_game_object deleted.
|
56 call sites migrated: find<T>(comp, name) → comp->find<T>(name) find<T>(comp, type) → comp->find<T>(type) get_game_object(comp) → comp->get_game_object() get_delta_time(comp) → comp->get_delta_time() find_replaceable<T>(comp, t) → comp->find_replaceable<T>(t) Also added: get_valid(), get_chain(), get_delta_time() as reflection property helpers. namespace utility::re_component deleted.
|
# Conflicts: # src/mods/IntegrityCheckBypass.cpp
RE3 TDB70 uses the same Window/SceneView layout as RE2. The case fallthrough was wrong — RE3 fell through to DMC5's TDB<69 path. Fixed all 6 dispatch points. Renamed W::re3 / SV::re3 to W::re3_tdb67 / SV::re3_tdb67 to clarify the alias is for the old TDB<69 layout (DMC5), not current RE3 TDB70. VR.cpp: fixed screen squish on RE2/RE3 in VR mode.
Copied imgui_impl_dx11/dx12/win32 from dependencies/imgui/backends/. Added ImGui_ImplWin32_WndProcHandler forward declaration in Plugin.cpp (required by newer imgui which wraps the declaration in #if 0).
Final fixes — merge readyRE3 ViaDispatch fix + VR screen squish (
|
Experimental branch to convert REFramework into one monolithic DLL covering all the games, getting rid of the need for multiple builds via runtime dispatch. Should be easier to maintain, takes up less space for nightlies and is less straining on CI.
20 games on one
dinput8.dll..NET assembly generation verified across all games (commit
99a5f49a— plugin ABI TDB count fields were bypassing the version-aware dispatcher, producing empty 2KB_mscorlib.dll/viacore.dll/application.dllon every game with TDB < 81; fixed by routing eight lambdas inPluginLoader.cppthroughget_num_types()/get_num_methods()/ etc.).All layout-variant types enforced — 18 struct types have private fields or opaque empty structs preventing direct
->fieldaccess. Dispatch macros (TDEF_FIELD,TMETH_FIELD,TFIELD_FIELD,RFIELDIMPL_FIELD,TIMPL_DISPATCH, etc.) centralize per-version casts. CI runs libclang-based audit on every PR.Old (non-modern) builds of RE2, RE3, and RE7 are not tested and will need additional work.
Full VR functionality (motion controls) is not yet tested on RE2, RE3, RE7, RE8.