Skip to content

About

Limit adjuster for GTA San Andreas: The Definitive Edition (x64 ASI port of Open Limit Adjuster)

Resources

Stars

1 star

Watchers

0 watching

Forks

Latest commit

 

History

4 Commits

Folders and files

Repository files navigation

DE_LimitAdjuster

x64 ASI port of GTAmodding/III.VC.SA.LimitAdjuster (SA part) for GTA San Andreas – The Definitive Edition. Current build: 0.2.0-debug. It is a debug build: /Od, PDB, and a usage monitor that logs what the game actually uses.

Is it needed?

Not for the unmodded game. DE already raised most pools. Only content mods (extra IPL/IDE entries, add-on vehicles/peds, heavy scripts) get close to the limits. Each classic SA limit was checked against the DE binary (current Steam/RGL SanAndreas.exe, SHA-256 ed7545eb…ac1f0):

Classic limit SA → DE Verdict
Pools: PtrNodeSingle, PtrNodeDouble, EntryInfoNode, Peds, Vehicles, Buildings, Objects, Dummys, ColModel, Task, Event, PointRoute, PatrolRoute, NodeRoute, TaskAllocator, PedIntelligence, PedAttractors see DE_LimitAdjuster.ini (e.g. Peds 140→1000, Buildings 13000→14000) Adjustable ([Pools])
VehicleStructs pool 50 → 50 Adjustable ([Pools])
AtomicModels / DamageAtomicModels / TimeModels / ClumpModels / WeaponModels / VehicleModels / PedModels 14000→14020, 70, 169, 92, 51, 212, 278 Needed by mods that add IDE entries; DE has no bounds check. Vanilla SA fills VehicleModels 212/212. Monitored only
EntityIpl 40 → 40 Needed by mods that add IPLs; an overflow corrupts the following globals. Monitored only
EntitiesPerIpl 4096 → 4096 (now a stack array in LoadScene) Mods only. Not ported
MatrixList 900 → 1800 Needed by map mods: every tilted IPL instance keeps a matrix for good; when none is left DE crashes in GetMatrix. Adjustable ([Pools] MatrixList)
SCM main/mission size 200000/69000 → 270000/69000 DE already raised main. Not ported
StreamingObjectInstancesList, VisibleEntityPtrs, VisibleLodPtrs, AlphaEntityList list removed in DE Not needed: UE4 renders
ExtraObjectsDir 550, allocated but never filled Not needed
MemoryAvailable no byte budget; DE flushes by model count Not needed
OutsideWorldWaterBlocks 70 → 4096 Not needed
Coronas, StaticShadows, ScriptSearchLights 64 / 48 / 8, bookkeeping only (the RW render paths are stubbed) Not needed: nothing draws more

How it works

  • The ASI hooks CPools::Initialise (0x14116FCA0) and the VehicleStructs pool constructor (0x14113C680). After DE builds a pool, the arrays of every pool set above DE's size are replaced with bigger ones from the game's GMalloc. The pools are still empty at that point, and every pool user reads the size from the pool header.
  • MatrixList is not a pool: sub_141147F90 builds the CMatrixLink array (104 bytes each) from three immediates right after CPools::Initialise. At load the ASI checks their bytes and rewrites them (size, count, free-list bytes).
  • Everything is found by byte signature (src/sigscan.h), not fixed address: each pattern must match exactly once in .text, with RIP/call displacements wildcarded. If any signature misses, nothing is installed and the log names it (a MatrixList miss only disables MatrixList). Supported builds so far: SanAndreas.exe SHA-256 ed7545eb…ac1f0 and cf677214…5ba17 (same version, recompiled: code shifted +0x1490). Scanning takes ~2 s at startup in this debug build.
  • A monitor thread samples every pool (used slots) and every store counter every SampleMs. It logs WARN at WarnPercent, FULL at capacity, and OVERFLOW when a store has gone past its array. Every LogInterval seconds it logs a usage: line with all values and peaks.

Install

  1. Install an ASI loader for DE (e.g. Ultimate ASI Loader as dxgi.dll/version.dll in Gameface\Binaries\Win64). The ASI must load before the game initialises its pools. If it loads too late, the log says pools already exist, and only the monitor runs.
  2. Copy bin\DE_LimitAdjuster.asi and bin\DE_LimitAdjuster.ini into <Game>\Gameface\Binaries\Win64\.
  3. Play, then read DE_LimitAdjuster.log next to the ASI.

Build and check

  • build.bat (VS 2022 x64 build tools) produces bin\DE_LimitAdjuster.asi and its .pdb.

  • test\run_check.bat <SanAndreas.exe> maps the real exe and installs the adjuster with test\DE_LimitAdjuster.ini. It then runs DE's own CPools::Initialise and VehicleStructs constructor through the hooks, using a recording GMalloc. It checks:

    • every pool's DE size and element size against the allocations the game code made;
    • the grown pools;
    • the counter addresses against IDA;
    • the monitor's WARN/FULL/OVERFLOW paths.

    Run it once per build: test\run_check.bat <SanAndreas.exe> test\check_result_<hash>.txt. Checked builds: check_result_ed7545eb.txt, check_result_cf677214.txt; a second run gives identical files. On the IDB build the counters are also compared to IDA addresses.

Source

File Contents
src/main.cpp Layout tables, pool growing, hooks, monitor, log, ini, DllMain
src/limits.h Shared declarations (used by the offline check)
src/sigscan.h Byte-signature lookup (unique match in .text)
test/offline_check.cpp Real-binary E2E check
minhook/ MinHook (BSD-2)

Credits

  • ThirteenAG and LINK/2012, and the contributors of Open Limit Adjuster (III.VC.SA.LimitAdjuster): the original adjuster this ports; the pool list and the PedIntelligence-follows-Peds rule come from it. MIT, see LICENSE.
  • Tsuda Kageyu: MinHook (BSD-2, license in minhook/MinHook.h).
  • DE port and reverse engineering: RAZORRZR0.

Grand Theft Auto and GTA San Andreas are trademarks of Take-Two Interactive / Rockstar Games. This project contains no game files.

License

MIT (LICENSE), same as the original adjuster.

About

Limit adjuster for GTA San Andreas: The Definitive Edition (x64 ASI port of Open Limit Adjuster)

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages