Journal des versions¶
Tous les changements notables de LuaModLoader. La version la plus récente est en haut.
v1.3.1¶
22 septembre 2026
Overlay : des polices pour les menus¶
Un mod menu peut enfin dessiner son titre en grand et ses lignes en petit, avec la police de son choix, et mesurer un texte pour le caler à droite ou le centrer. Un script écrit pour la v1.3.0 dessine exactement comme avant. Détails dans la référence de l'API.
Draw.Textprend une taille et une famille de police en cinquième et sixième arguments :Draw.Text(x, y, "PRO TRAINER", couleur, 36, "Impact"). Sans eux, c'est la police système de toujours, au pixel près.Draw.TextSize(texte, [taille], [police])rend la largeur et la hauteur du texte tel qu'il sera dessiné. Fini la largeur estimée à sept pixels par caractère pour caler une valeur à droite.Draw.LoadFont(chemin)charge un.ttfou.otflivré dans le dossier du mod, pour ce process seulement : rien n'est installé sur la machine. La famille se nomme ensuite par son nom interne ("Pricedown").Draw.ScreenSize()rend la taille du backbuffer du jeu, pour un menu qui veut les mêmes proportions en 1080p et en 1440p.
v1.3.0¶
22 septembre 2026
Le proxy s'appelle désormais dinput8.dll, et plus rien n'est à renommer
Sur Complete Edition, le wrapper d'intégrité de Rockstar (MTLX.dll)
restaure les fichiers livrés avec le jeu une quinzaine de secondes après le
lancement, et binkw32.dll en fait partie. Un proxy binkw32.dll ne
tenait donc qu'une seule session après chaque copie, d'où son air
intermittent. Le proxy est maintenant livré sous le nom dinput8.dll,
le créneau qu'occupe Ultimate ASI Loader : un fichier étranger à
l'installation, que rien ne vient réécrire. Vous le posez à côté de
GTAIV.exe, et c'est toute l'installation.
Mise à jour depuis la v1.2.0 : supprimez l'ancien proxy binkw32.dll et
rendez à binkw32_orig.dll son nom d'origine. Voir
Mettre à jour.
Streaming : le moddeur dépose un dossier, le jeu le charge¶
Un mod peut désormais livrer des modèles, des textures et des lignes de données, et le joueur l'installe toujours en copiant un seul dossier. Aucun fichier du jeu n'est édité, et rien n'est écrit dans le dossier du jeu : tout ce que le loader produit va dans son cache et est servi au moteur par la redirection de fichiers. Détails dans Structure d'un mod.
mods/<nom>/stream/: chaque fichier posé là (.wdr,.wtd,.wft,.wbn…) est empaqueté au lancement dans une archive IMG et monté pour le moteur. L'archive n'est reconstruite que si un fichier a changé.mods/<nom>/gamedata/<fichier>: un fragment devehicles.ide,handling.dat,carcols.dat… qui ne contient que vos lignes, sous l'en-tête de section du format. Les fragments sont fusionnés dans le fichier du jeu, par-dessus ce qu'un autre mod ou FusionFix sert déjà : deux mods qui ajoutent chacun une voiture ajoutent deux lignes au lieu de s'effacer l'un l'autre.- Les archives chiffrées de Rockstar se lisent. La clé AES est mesurée
dans l'exécutable du jeu au lancement, ce qui permet au loader d'ouvrir
vehicles.imget les autres. C'est là-dessus que repose le pont d'épisode ci-dessous. - Un
update/update.imgposé à la main est absorbé, pas contourné. Ses entrées sont lues et reprises dans l'archive du loader, et le jeu les reçoit toujours. Un fichier de mod passe devant une entrée absorbée du même nom. - Les plugins ASI sont aussi chargés depuis
plugins/etscripts/, et le loader se présente comme Ultimate ASI Loader, pour que les plugins écrits pour lui (FusionFix entre autres) s'initialisent comme ils l'attendent au lieu d'échouer avec l'erreur 1114. - Le journal va là où il peut être écrit. Le dossier du jeu s'il est
inscriptible, sinon
%LOCALAPPDATA%\LuaModLoader\. Les fichiers témoins sont cherchés à côté du journal.
Overlay et entrées¶
- L'alt-tab rend le clavier. GTA IV lit le clavier par des API qui ignorent le focus de la fenêtre, donc taper dans Discord ou un navigateur faisait sauter et tirer le personnage. La lecture des touches et de la souris s'arrête dès que le premier plan sort du processus du jeu.
- L'overlay disparaît sous le menu pause et les fondus. Il restait dessiné par-dessus le menu pause et pendant les changements de session, parce que le jeu gèle sa boucle de script et que le thread de rendu continuait de redessiner la file de la dernière image. L'overlay se masque maintenant une image avant le gel et laisse tomber un tick de plus de 200 ms.
- Horodatage à la milliseconde dans
LuaModLoader.log. Un thread gelé et un événement qui n'a jamais eu lieu produisaient le même fichier.
Éditeur¶
- Une page Settings, derrière l'engrenage à droite des onglets. On y
trouve l'interrupteur Always on top (l'éditeur reste au-dessus du jeu et
des autres applications après un alt-tab, mémorisé dans
LuaModLoader.inià côté deLuaModLoader.log) et les crédits, avec les liens Discord et documentation. - Plus de fenêtre Discord au premier lancement. Le loader allait chercher une invitation chez Discord et l'ouvrait dans le navigateur au premier démarrage du jeu. C'est terminé : le loader ne fait plus aucune requête réseau, et l'invitation est un bouton de la page Settings. Cette fenêtre du premier lancement était aussi ce qui faisait signaler le loader par les antivirus.
- Un clic sur
+/-plie ou déplie un mod dans la liste. Sélectionner un dossier ne le déplie plus par accident, et le rectangle de focus en pointillés a disparu. - L'éditeur s'ouvre en 1000 x 650, centré sur la fenêtre du jeu et borné à la zone de travail : une fenêtre de jeu collée au bord de l'écran ne peut plus le pousser hors cadre.
- Les binaires portent leurs informations de version (clic droit, Propriétés, Détails) : on sait quel build on a sans ouvrir le journal.
Le pont d'épisode¶
Le contenu de TLAD et de TBoGT, utilisable dans GTA IV, sans un seul fichier à poser dans le dossier du jeu. Sur Complete Edition les assets des épisodes sont déjà sur le disque ; le loader sait maintenant lire les archives chiffrées de Rockstar et sert ce qui manque à IV directement depuis elles.
- 58 véhicules et 20 armes d'épisode, avec leur handling, leurs couleurs,
leurs animations, leurs icônes, leurs explosions et leurs sons. Ids d'armes :
WEAPON_EPISODIC_nvaut20 + n(voir les constantes du jeu). - Le parachute de TBoGT. Le loader extrait
parachute_player.sco, le réécrit pour IV (signature, globales relocalisées en statiques) et fait tourner son propre lanceur : le parachute s'enfile dès que l'arme 41 entre dans l'inventaire, une chute de plus de 6 m lance la descente, Shift ou Espace ouvre la voile. - L'audio d'épisode par le chargeur de Rockstar (
setup2.xml), plus deux correctifs moteur : l'objet sonore que IV rend muet en 3D (DSR-1, lance-grenades, fusil scié) et l'unique slot de banque statique d'où TBoGT évinçait TLAD. - La table de handling passe de 160 à 512 entrées ; il en faut 166.
- Des fichiers témoins pour couper une moitié à la fois :
LuaModLoader.noepisodes,.noepisodemodels,.noepisodedata,.noepisodeweapons,.noepisodeweaponimg,.noparachute,.noaudiopatch,.noepisodeslot. asi_loader_crash.log: chaque violation d'accès est écrite avec son module et son décalage avant que le jeu ne meure.
Limites connues¶
- Les véhicules d'épisode ne circulent pas dans le trafic (
cargrp.datest positionnel, pas encore fusionné) et n'ont pas de nom affiché (GXT). EPISODIC_1etEPISODIC_5sont réclamés par les deux épisodes ; TLAD les garde.- L'atterrissage en parachute a planté deux fois dans le code des variations de ped du moteur ; pas reproduit depuis.
v1.2.0¶
29 août 2026
Rupture : toute l'API Lua a été renommée
Les scripts écrits pour la v1.1.x ne tournent plus tant qu'ils ne sont pas
mis à jour. Les anciennes globales nues valent nil volontairement :
un script périmé lève tout de suite attempt to call a nil value au lieu de
dérailler en silence. Le tableau de correspondance complet est en bas de la
référence de l'API.
Changements en rupture¶
- Les natifs sont des globales en PascalCase. Les 3 158 natifs sont
maintenant des globales sous leur nom PascalCase, comme
SetCharHealthouGetPlayerId. Ce sont les noms qu'utilisent les scripts ScriptHookDotNet et les trainers classiques, donc du code porté n'a rien à renommer. La formeALL_CAPSn'est plus une globale, mais elle reste joignable par la tablenativeset parNative.Call("SET_CHAR_HEALTH", …). - L'API du loader passe en namespaces. Tout ce que LuaModLoader fournit vit
sous
Thread,Console,Log,Draw,Color,Input,Gamepad,Native,Memory,VehicleetScript. Plus aucune globale du loader ne peut entrer en collision avec un nom de natif. - Les anciennes globales échouent franchement.
print,log,msgbox,is_key_down,draw_text,call_native,CreateThread,Waitet les autres valent toutesnil. -
onTick()disparaît. Le loader n'appelle plus de fonction globaleonTick(). Un thread est le seul point d'entrée par image, donc le code par image se déplace dansThread.Create(function() while true do ... Thread.Wait(0) end end). Un mod qui définit encoreonTickdémarre normalement, mais la fonction ne tourne jamais et rien ne le signale. Vérifiez vos mods au moment de mettre à jour.Ce retrait ferme aussi un piège. Une erreur dans
onTickposait un drapeau testé avant l'ordonnanceur, si bien qu'une seule mauvaise image tuait en silence tous les threads du mod jusqu'au rechargement. Maintenant, un thread qui casse n'emporte que lui-même. -
Les mods se déclarent dans
manifest.lua. Le manifeste est maintenant un petit fichier Lua dans l'esprit dufxmanifest.luade FiveM, avecname,author,description,version,episode,autostartetclient_scripts. Une clé que le loader ne connaît pas est gardée comme métadonnée du mod au lieu d'être une erreur, un mod peut donc déclarer ce qu'il veut.Deux conséquences à connaître. Un dossier sans aucun manifeste n'est plus un mod, le loader passe devant sans s'arrêter. Et
autostart trueest une erreur de syntaxe en Lua, les booléens s'écrivent doncautostart = true.Rien n'a besoin d'être converti.
manifest.xmletmeta.xmlrestent lus, etScript.DeclareModFilecontinue d'écrire dans le format que le mod utilise déjà. -
L'overlay multijoueur est retiré. Les aides
Events,Chat,PlayeretGamen'existent plus. Les scripts qui s'en servaient doivent appeler les natifs directement.
Scripting¶
- Ordonnanceur de coroutines.
Thread.Create(fn),Thread.Wait(ms),Thread.Stop(id)etThread.Count()apportent leWait()bloquant auquel les mods ScriptHookDotNet sont écrits, sans que chaque script recopie sa propre boucle de coroutines. Une erreur dans un thread ne tue que ce thread, les autres continuent. Les délais comptent du temps réel, donc une partie en pause ne réveille rien. - Vos propres natifs.
Native.Register(nom, fonction)ajoute une fonction Lua à la table des natifs du jeu. Tout ce qui résout un natif par hash peut alors l'appeler, quel que soit le langage : un plugin ScriptHookDotNet ou HappinessMP atteint votre code sans partager ni DLL ni header.Native.CustomHash(nom)calcule le hash etNative.CallHash(hash, …)appelle le natif. Recharger un mod réutilise son emplacement au lieu d'en prendre un nouveau. - Os de véhicule.
Vehicle.BonePrepare,Vehicle.HasBone,Vehicle.SetBoneVisible,Vehicle.IsBoneVisibleetVehicle.BoneNamescachent ou rétablissent des os précis, avec un cache validé. Le nombre de composants et d'os change selon le modèle de véhicule, donc chaque indice est vérifié contre le modèle courant avant la moindre écriture. - Console en direct. Ce que les mods en cours écrivent avec
Console.Print()arrive dans la console de l'éditeur. - Les erreurs d'exécution y arrivent aussi. Seules les erreurs de chargement
le faisaient. Une erreur levée dans un
Thread.Create, un appel de natif en échec ou une panne de l'ordonnanceur partaient dansLuaModLoader.loget nulle part ailleurs, si bien qu'un mod pouvait casser sous les yeux de son auteur sans une seule ligne visible. Elles apparaissent maintenant dans la console avec le préfixe[erreur], en plus du fichier journal.
Stabilité¶
- Les mods tournent sur la boucle de script du jeu. Le loader accrochait
son tick à un natif détourné, et repassait sur le thread de rendu quand plus
personne n'appelait ce natif. Lua tourne désormais depuis la boucle que le jeu
lui-même exécute une fois par image, donc les mods ne se retrouvent jamais sur
le mauvais thread.
Script.IsTickFallback()existe toujours et rend toujoursfalse. - Les natifs sont détournés par la table du jeu. Rediriger un natif se
résume à écrire une valeur dans la table que le jeu tient déjà, sans patcher
de code ni allouer de mémoire exécutable. Le détour devient aussi retirable :
décharger
LuaModLoader.dllpendant que le jeu tourne rend le natif au jeu au lieu de le laisser sauter dans de la mémoire libérée. - Moins collé à une seule build. Les adresses dont le loader a besoin sont retrouvées en cherchant dans le code du jeu, au lieu d'être écrites en dur pour la 1.2.0.59. L'ancienne adresse en dur reste en dernier recours, et elle est vérifiée avant d'être utilisée.
- Correctif du texte sous DXVK. Les ressources de rendu sont libérées avant une réinitialisation du device, ce qui répare le texte de l'overlay sous les wrappers D3D9 vers Vulkan comme DXVK. Le cache de texte est borné lui aussi : 512 entrées, évincées après 240 images sans usage.
- Journal plus calme.
LuaModLoader.logutilise maintenant des niveaux[info]/[warn]/[error]. Les diagnostics par image sont passés en[debug], qui n'écrit rien par défaut. Ils noyaient les vraies erreurs sous des centaines de kilooctets par session. Posez un fichier videLuaModLoader.debugà côté du journal pour les rallumer. - Interrupteurs pour cerner un blocage. Un fichier vide à côté du journal
désactive un sous-système le temps d'un lancement :
LuaModLoader.noanchor,LuaModLoader.nohooketLuaModLoader.nod3d. Pratique quand on vous demande un journal sur le Discord.
Éditeur¶
- Plusieurs lecteurs de console en même temps. Lire la console ne la vide plus, et chaque lecteur garde sa position : deux lecteurs voient les mêmes lignes au lieu de se les voler.
- New mod écrit un squelette qui marche. Clic droit dans le gestionnaire de
mods puis New mod : vous obtenez un
manifest.luaavec un commentaire sur chaque clé et unmain.luaqui contient déjà la boucle de thread et unonUnload. Avant, il écrivait deux lignes qui appelaientlog(), une fonction qui disparaît dans cette version : un mod tout neuf échouait donc dès sa première ligne. - Always on Top. Un réglage pour garder la fenêtre de l'éditeur au-dessus des autres applications. Il est retenu d'une session à l'autre.
Base de natifs¶
- 2 920 natifs ont désormais une signature connue, sur les 3 158 que le loader connaît. La base de natifs est reconstruite à partir des mêmes données.
v1.1.2¶
Stabilité¶
- « Fatal Error: SMPA60 » corrigé. Les mods pouvaient démarrer pendant
l'écran de chargement, avant que le jeu ne tourne réellement, et finir par
appeler des natifs depuis le thread de rendu. Ces natifs échouaient dans le
moteur et laissaient son allocateur mémoire incohérent, ce qui faisait
s'éteindre GTA IV sur un
Fatal Error: SMPA60plusieurs minutes plus tard, sans lien évident avec la cause réelle. Les mods attendent désormais que le jeu soit vraiment en partie avant leur premier tick. - Écriture mémoire plus sûre.
mem_write_hexvérifie maintenant que la zone visée est valide et accessible en écriture avant d'y toucher, au lieu de la forcer d'abord. Une adresse fausse échoue proprement et renvoiefalse, au lieu d'écraser silencieusement la mémoire du jeu et de planter bien plus tard.
Performances¶
- Menus beaucoup plus rapides. L'overlay de texte construisait une texture toute neuve pour chaque ligne de texte à chaque frame. Cela représentait environ 1 800 allocations de texture par seconde sur un menu de trainer typique, d'où de fortes chutes de framerate dès qu'un menu était ouvert. Le texte rendu est désormais mis en cache et réutilisé d'une frame à l'autre, et les couleurs sont appliquées au moment du dessin : surligner et déplacer le curseur ne coûte plus rien.
v1.1.1¶
Corrections¶
- Éditeur F6 in-game rétabli. En v1.1.0 l'éditeur intégré ne démarrait jamais, et appuyer sur F6 ne faisait rien. L'éditeur est de retour et se bascule à nouveau correctement.
API avancées & reverse engineering¶
- Écriture mémoire. Ajout de
mem_write_hex(addr, hex)pour patcher la mémoire du jeu directement depuis Lua. - Contrôle des composants de véhicule. Ajout de
resolve_vehicle_ptr(handle),hide_vehicle_component(handle, index)etrestore_vehicle_components(handle)pour masquer et réafficher des pièces de fragment d'un véhicule, comme les capots, les attaches et les ailerons. - Appels de fonctions bruts. Ajout de
call_thiscall1(rva, this, arg)etcall_vtable_method0(obj, offset)pour appeler des fonctions du moteur directement, toutes deux protégées contre les plantages par SEH.
v1.1.0¶
21 août 2026
ASI loader & plugins¶
- ASI loader intégré.
binkw32.dlldécouvre et charge automatiquement tous les plugins*.asiau lancement, avec une journalisation détaillée dansasi_loader.log.
Manette & entrées¶
- Support manette natif (XInput). Ajout de
is_pad_button_down(button)pour lire les entrées manette directement dans les scripts Lua. - Filtre de messages d'entrée (WndProc). Absorbe les messages Windows bruts de F4 et des touches de navigation de menu, pour éviter que le téléphone ou la radio du jeu ne se déclenchent pendant qu'un menu de trainer est ouvert.
API mémoire & natifs¶
- API d'inspection et de scan mémoire. Ajout de
mem_find_string,mem_find_dword,mem_read_hex,mem_read_u32,module_infoetnative_address, toutes protégées contre les plantages par SEH. - Correctif de passage par pointeur. Correction du passage de paramètres pour
les natifs
MARK_*_AS_NO_LONGER_NEEDED.
DirectX 9 & système¶
- Hook D3D9 de repli tardif. Ajout d'un hook de device de repli automatique pour un rendu d'overlay fiable.
- Intégration du widget Discord. Connecte les nouveaux joueurs à la communauté Discord au premier lancement.
v1.0.2¶
18 août 2026
- Sous-système d'overlay nettoyé et moteur stabilisé.
- Documentation mise à jour, dont la couverture PascalCase complète dans la doc et l'explorateur de la base de natifs.
v1.0.1¶
7 août 2026
- Mode borderless implémenté et support total de DXVK.
- Correctif du namespace de l'éditeur.
- Correction du scintillement de la souris en F6.
- Résolution d'une race condition sur la vtable D3D9.
v1.0.0¶
6 août 2026
Première version publique : un mod loader Lua 5.4 pour GTA IV Complete Edition (1.2.0.59), avec l'éditeur F6 in-game, l'API d'appel des natifs, le rendu d'overlay D3D9 et les hooks d'entrées clavier.