Validité des entités
Le bug le plus fréquent dans le modding GTA V consiste à manipuler une entité qui a déjà disparu du monde. En C# pur, tester if (monPed != null) suffit à savoir si un objet est alloué en mémoire. Dans le moteur de GTA V, ce test est dangereusement incomplet.
Le piège du handle périmé (stale handle)
Quand tu crées une entité, SHVDN enveloppe le handle du moteur à l'intérieur d'un objet C# :
private Ped _gardeDuCorps;
private void CreerGarde()
{
_gardeDuCorps = World.CreatePed(model, positionSpawn);
}
Imagine maintenant ce qui se passe trois minutes plus tard :
- Le garde du corps prend une balle et meurt.
- Une ambulance ou le nettoyeur ambiant du jeu supprime le cadavre.
- Le moteur libère le handle dans sa table interne.
En C#, _gardeDuCorps n'est toujours pas null ! Ta variable référence toujours l'instance GTA.Ped qui encapsule l'ancien numéro de handle. Mais dans le jeu, ce handle est mort. Si tu écris maintenant _gardeDuCorps.Position, SHVDN interroge le moteur sur une entité inexistante, et ton script plante.
Le double contrôle : null et Exists()
Chaque fois que tu touches une entité conservée d'une image à l'autre, tu dois tester à la fois la référence C# et l'existence réelle dans le moteur :
if (_gardeDuCorps != null && _gardeDuCorps.Exists())
{
// L'entité est bien présente et vivante dans la mémoire du jeu
Vector3 positionGarde = _gardeDuCorps.Position;
}
Exists() appelle la native DOES_ENTITY_EXIST sous le capot. Elle vérifie si le handle est actif dans la table du moteur.
Mort contre invalide
Ne confonds pas une entité invalide et une entité morte :
- Morte (
ped.IsDead) : La santé du ped est tombée à zéro. Son corps physique (ragdoll ou cadavre) repose toujours sur le trottoir. Son handle est encore valide. Tu peux lire sa position, examiner ses blessures ou le réanimer. - Invalide (
!ped.Exists()) : L'entité a totalement quitté le monde du jeu. Elle a été nettoyée, supprimée, ou n'a jamais pu être créée. Tout appel de méthode sur cette entité échouera.
Voici le modèle défensif standard utilisé dans les mods de production :
private void OnTick(object sender, EventArgs e)
{
// 1. Garde contre une entité inexistante
if (_gardeDuCorps == null || !_gardeDuCorps.Exists())
{
return;
}
// 2. Garde contre une entité morte
if (_gardeDuCorps.IsDead)
{
GTA.UI.Notification.PostTicker("Ton garde du corps est tombé au combat.", false);
_gardeDuCorps = null;
return;
}
// 3. Traitement sécurisé sur l'entité vivante
_gardeDuCorps.Task.FollowToOffsetFromEntity(Game.Player.Character, new Vector3(0f, -2f, 0f));
}
Dans la leçon suivante, nous étudions les modèles 3D : comment les charger en mémoire graphique, vérifier leur disponibilité et les libérer proprement.