Skip to content

Changelog

All notable changes to LuaModLoader. The newest release is at the top.


v1.3.1

22 September 2026

Download

Overlay: fonts for menus

A menu mod can finally draw its title big and its rows small, in the typeface of its choice, and measure a string to right-align or center it. A script written for v1.3.0 draws exactly as before. Details in the API reference.

  • Draw.Text takes a size and a font family as fifth and sixth arguments: Draw.Text(x, y, "PRO TRAINER", color, 36, "Impact"). Without them it is the usual system font, pixel for pixel.
  • Draw.TextSize(text, [size], [font]) returns the width and height of the text as it will be drawn. No more guessing seven pixels per character to right-align a value.
  • Draw.LoadFont(path) loads a .ttf or .otf shipped in the mod folder, for this process only: nothing is installed on the machine. The family is then named by its internal name ("Pricedown").
  • Draw.ScreenSize() returns the size of the game's backbuffer, for a menu that wants the same proportions at 1080p and 1440p.

v1.3.0

22 September 2026

Download

The proxy is now dinput8.dll, and nothing gets renamed any more

On Complete Edition, Rockstar's integrity wrapper (MTLX.dll) restores the files shipped with the game about fifteen seconds after launch, and binkw32.dll is one of them. A binkw32.dll proxy therefore worked for exactly one session after each copy, which is why it looked intermittent. The proxy now ships as dinput8.dll, the slot Ultimate ASI Loader uses: a file foreign to the install, which nothing rewrites. You drop it next to GTAIV.exe, and that is the whole install.

Upgrading from v1.2.0: delete the old binkw32.dll proxy and give binkw32_orig.dll its original name back. See Upgrading.

Streaming: drop a folder, the game loads it

A mod can now ship models, textures and data lines, and the player still installs it by copying one folder. Nothing is edited in the game's own files, and nothing is written into the game folder: everything the loader produces goes to its cache and is served to the engine through the file redirection. Details in Mod structure.

  • mods/<name>/stream/: every file placed there (.wdr, .wtd, .wft, .wbn...) is packed into an IMG archive at launch and mounted for the engine. The archive is rebuilt only when a file changed.
  • mods/<name>/gamedata/<file>: a fragment of vehicles.ide, handling.dat, carcols.dat... holding only your lines, under the section header of that format. Fragments are merged into the game's file, on top of what another mod or FusionFix already serves, so two mods that each add a car add two lines instead of erasing each other.
  • Rockstar's encrypted archives are readable. The AES key is measured in the game's own executable at launch, so the loader can open vehicles.img and friends. That is what the episode bridge below stands on.
  • A hand-placed update/update.img is absorbed, not bypassed. Its entries are read and carried into the loader's archive, and the game still gets them. A mod file wins over an absorbed entry of the same name.
  • ASI plugins are also loaded from plugins/ and scripts/, and the loader announces itself as Ultimate ASI Loader, so plugins written for it (FusionFix among them) initialise the way they expect instead of failing with error 1114.
  • The log goes where it can be written. The game folder when it is writable, otherwise %LOCALAPPDATA%\LuaModLoader\. Witness files are looked up next to the log.

Overlay and input

  • Alt-tab gives the keyboard back. GTA IV reads the keyboard through APIs that ignore window focus, so typing in Discord or a browser made the character jump and shoot. Key and mouse reads now stop as soon as the foreground window leaves the game's process.
  • The overlay disappears under the pause menu and the fades. It used to stay drawn over the pause menu and during session changes, because the game freezes its script loop and the rendering thread kept redrawing the last frame's queue. The overlay now hides one frame before the freeze and drops a tick older than 200 ms.
  • Millisecond timestamps in LuaModLoader.log. A frozen thread and an event that never happened used to produce the same file.

Editor

  • A Settings page, behind the gear icon right of the tabs. It holds the Always on top switch (the editor stays above the game and other applications after an alt-tab, remembered in LuaModLoader.ini next to LuaModLoader.log) and the credits, with the Discord and documentation links.
  • No more Discord window at first launch. The loader used to fetch an invitation from Discord and open it in your browser the first time the game started. That is gone: the loader makes no network request at all any more, and the invitation is a button on the Settings page. The first-launch popup was also what made antivirus engines flag the loader.
  • One click on + / - folds or unfolds a mod in the list. Selecting a folder no longer unfolds it by accident, and the dotted focus rectangle is gone.
  • The editor opens at 1000 x 650, centered on the game window and kept inside the work area, so a game window against the screen edge cannot push it off screen.
  • The binaries carry version information (right-click, Properties, Details), so you can tell which build you have without reading the log.

The episode bridge

TLAD and TBoGT content, usable inside GTA IV, without a single file to drop in the game folder. On Complete Edition the episode assets are already on disk; the loader now knows how to read Rockstar's encrypted archives and serves what IV lacks straight from them.

  • 58 episode vehicles and 20 episode weapons, with their handling, colours, animations, HUD icons, explosions and sounds. Weapon ids: WEAPON_EPISODIC_n is 20 + n (see game constants).
  • The TBoGT parachute. The loader extracts parachute_player.sco, rewrites it for IV (signature, globals relocated to statics) and runs its own launcher: the parachute goes on as soon as weapon 41 enters the inventory, a fall of more than 6 m starts the descent, Shift or Space opens the canopy.
  • Episode audio through Rockstar's own loader (setup2.xml), plus two engine fixes: the sound object the IV engine mutes in 3D (DSR-1, grenade launcher, sawn-off) and the single static-bank slot TBoGT evicts TLAD from.
  • The handling table grows from 160 to 512 entries; 166 are needed.
  • Witness files to cut one half at a time: LuaModLoader.noepisodes, .noepisodemodels, .noepisodedata, .noepisodeweapons, .noepisodeweaponimg, .noparachute, .noaudiopatch, .noepisodeslot.
  • asi_loader_crash.log: every access violation is written with its module and offset before the game dies.

Known limits

  • Episode vehicles do not appear in ambient traffic (cargrp.dat is positional and not merged yet) and have no displayed name (GXT).
  • EPISODIC_1 and EPISODIC_5 are claimed by both episodes; TLAD keeps them.
  • Landing with the parachute has crashed twice in the engine's ped variation code; not reproduced since.

v1.2.0

29 August 2026

Breaking: the whole Lua API was renamed

Scripts written for v1.1.x will not run until they are updated. The old bare globals are nil on purpose, so an outdated script raises attempt to call a nil value immediately instead of failing in silence. The complete old-to-new mapping is at the bottom of the API reference.

Breaking changes

  • Natives are PascalCase globals. All 3,158 natives are now globals under their PascalCase name, such as SetCharHealth and GetPlayerId. These are the names ScriptHookDotNet scripts and classic trainers use, so ported code needs no renaming. The ALL_CAPS form is no longer a global. It stays reachable through the natives table and Native.Call("SET_CHAR_HEALTH", …).
  • The loader API moved into namespaces. Everything LuaModLoader itself provides now lives under Thread, Console, Log, Draw, Color, Input, Gamepad, Native, Memory, Vehicle and Script. No bare loader global is left to collide with a native name.
  • Old globals now fail loudly. print, log, msgbox, is_key_down, draw_text, call_native, CreateThread, Wait and the rest are all nil.
  • onTick() is gone. The loader does not call a global onTick() any more. A thread is the only per-frame entry point, so per-frame code moves into Thread.Create(function() while true do ... Thread.Wait(0) end end). A mod that still defines onTick starts normally, but the function never runs and nothing warns about it, so check your mods when you update.

    This also closes a trap. An error inside onTick used to set a flag that was tested before the scheduler ran, so one bad frame silently killed every thread in that mod until the next reload. Now a failing thread only takes itself down.

  • Mods are declared in manifest.lua. The manifest is now a small Lua file in the style of a FiveM fxmanifest.lua, with name, author, description, version, episode, autostart and client_scripts. A key the loader does not know is kept as the mod's own metadata instead of being an error, so a mod can declare whatever it needs.

    Two consequences worth knowing. A folder with no manifest at all is no longer a mod: the loader walks past it. And autostart true is a syntax error in Lua, so booleans are written autostart = true.

    Nothing has to be converted. manifest.xml and meta.xml are still read, and Script.DeclareModFile keeps writing back into whichever format the mod already uses.

  • Multiplayer overlay removed. The Events, Chat, Player and Game helpers are gone. Scripts that used them must call the natives directly.

Scripting

  • Coroutine scheduler. Thread.Create(fn), Thread.Wait(ms), Thread.Stop(id) and Thread.Count() bring the blocking Wait() that ScriptHookDotNet mods are written against, without every script rolling its own coroutine loop. An error inside a thread kills only that thread, and the others keep running. Delays count real time, so a paused game wakes nothing.
  • Your own natives. Native.Register(name, fn) adds a Lua function to the game's own native table. Anything that resolves a native by hash can then call it, whatever language it is written in, so a ScriptHookDotNet or HappinessMP plugin can reach your code without sharing a DLL or a header. Use Native.CustomHash(name) to compute the hash and Native.CallHash(hash, …) to call one. Reloading a mod reuses its slot instead of taking a new one.
  • Vehicle bones. Vehicle.BonePrepare, Vehicle.HasBone, Vehicle.SetBoneVisible, Vehicle.IsBoneVisible and Vehicle.BoneNames hide or restore individual bones, backed by a validated cache. Component and bone counts differ per vehicle model, so every index is range-checked against the current model before anything is written.
  • Live console. Console.Print() output from running mods streams to the editor console.
  • Runtime errors reach that console too. Only load errors did before. An error raised inside a Thread.Create, a failed native call or a scheduler failure went to LuaModLoader.log and nowhere else, so a mod could break in front of its author without a single visible line. They now show up in the console with an [erreur] prefix as well as in the log file.

Stability

  • Mods tick on the game's own script loop. The loader used to hang its tick on a detoured native, and to fall back to the rendering thread when nothing called it. Lua now runs from the loop the game itself drives once per frame, so mods never end up on the wrong thread. Script.IsTickFallback() still exists and always returns false.
  • Natives are hooked through the game's table. Redirecting a native is a single value written into the table the game already keeps, with no patched code and no executable memory of our own. That also makes the hook removable, so unloading LuaModLoader.dll while the game runs hands the native back instead of leaving the game jumping into freed memory.
  • Less tied to one build. The addresses the loader needs are found by scanning the game's code rather than hardcoded for 1.2.0.59, with the old hardcoded value kept as a last resort and checked before use.
  • DXVK text fix. Render resources are released before a device reset, which fixes overlay text under D3D9-to-Vulkan wrappers such as DXVK. The text cache is bounded too: 512 entries, evicted after 240 unused frames.
  • Quieter log. LuaModLoader.log now uses [info] / [warn] / [error] levels. Per-frame diagnostics moved to a [debug] level that writes nothing by default. They used to bury real errors under hundreds of kilobytes per session. Drop an empty LuaModLoader.debug next to the log to turn them back on.
  • Switches for narrowing down a freeze. An empty file next to the log turns a subsystem off for one launch: LuaModLoader.noanchor, LuaModLoader.nohook and LuaModLoader.nod3d. Handy when you are asked for a log on the Discord.

Editor

  • Several consoles can read at once. Reading the console no longer empties it, and each reader keeps its own position, so two readers show the same lines instead of stealing them from each other.
  • New mod writes a working skeleton. Right-click in the mod manager and pick New mod: you get a manifest.lua with a comment on each key and a main.lua that already has the thread loop and an onUnload. It used to write a two-line file calling log(), a function that stopped existing in this release, so a brand new mod failed on its first line.
  • Always on Top. A setting to keep the editor window above other applications. It is remembered between sessions.

Native database

  • 2,920 natives now have a known signature, out of the 3,158 the loader knows about. The Native Database is rebuilt from the same data.

v1.1.2

Stability

  • "Fatal Error: SMPA60" fixed. Mods could start during the loading screen, before the game was actually running, and end up calling natives from the rendering thread. Those natives failed inside the engine and left its memory allocator inconsistent, which made GTA IV shut itself down with Fatal Error: SMPA60 several minutes later, with no obvious link to the real cause. Mods now wait until the game is genuinely in gameplay before their first tick.
  • Safer memory writing. mem_write_hex now checks that the target memory is valid and writable before touching it, instead of forcing it writable first. A wrong address fails cleanly and returns false instead of silently overwriting game memory and crashing much later.

Performance

  • Much faster menus. The text overlay used to build a brand new texture for every line of text on every single frame. That came to roughly 1,800 texture allocations per second on a typical trainer menu, causing heavy frame drops whenever a menu was open. Rendered text is now cached and reused across frames, and colors are applied at draw time, so highlighting and moving the cursor costs nothing.

v1.1.1

Fixes

  • In-game F6 editor restored. In v1.1.0 the built-in editor never started - pressing F6 did nothing. The editor is back and toggles correctly again.

Advanced & reverse-engineering APIs

  • Memory writing. Added mem_write_hex(addr, hex) to patch game memory directly from Lua.
  • Vehicle component control. Added resolve_vehicle_ptr(handle), hide_vehicle_component(handle, index) and restore_vehicle_components(handle) to hide and restore individual vehicle fragment parts such as hoods, hood latches and spoilers.
  • Raw function calls. Added call_thiscall1(rva, this, arg) and call_vtable_method0(obj, offset) to call engine functions directly, both protected against crashes by SEH.

v1.1.0

21 August 2026

ASI loader & plugins

  • Integrated ASI loader. binkw32.dll automatically discovers and loads all *.asi plugins on launch, with detailed logging saved to asi_loader.log.

Gamepad & inputs

  • Native gamepad support (XInput). Added is_pad_button_down(button) to read controller inputs directly in Lua scripts.
  • Input message filter (WndProc). Swallows raw Windows messages for F4 and the menu navigation keys, to stop the in-game phone or radio triggering while a trainer menu is open.

Memory & native API

  • Memory inspection & scanner APIs. Added mem_find_string, mem_find_dword, mem_read_hex, mem_read_u32, module_info and native_address, all with SEH crash protection.
  • Native pointer override fix. Fixed parameter passing for the MARK_*_AS_NO_LONGER_NEEDED natives.

DirectX 9 & system

  • D3D9 late fallback hook. Added automatic fallback device hooking for reliable overlay rendering.
  • Discord widget integration. Connects new players to the Discord community on first run.

v1.0.2

18 August 2026

  • Overlay subsystem cleaned up and the engine stabilised.
  • Documentation updated, including full PascalCase coverage in the docs and the Native Database explorer.

v1.0.1

7 August 2026

  • Borderless mode implemented and full DXVK support.
  • Editor namespace fix.
  • F6 mouse flickering fixed.
  • D3D9 vtable race condition resolved.

v1.0.0

6 August 2026

First public release: a Lua 5.4 mod loader for GTA IV Complete Edition (1.2.0.59), with the in-game F6 editor, the native call API, D3D9 overlay rendering and keyboard input hooks.