Plugin Authoring
InteractV can load custom actions from your own .dll files, without touching the mod's own code. This lets you add a brand new NPC action and use it from scenario XML, exactly like a built-in one.
What a plugin does
A plugin adds a new action name usable in a scenario step, e.g. <Actor action="MY_ACTION" />. When that action fires, InteractV calls your plugin to create the object that actually runs it. Plugins are loaded at startup, so restart the game (or reload scripts) after adding one.
A plugin can also reuse the name of a built-in action. If it does, your plugin takes over that action instead of the built-in behavior.
Built-in action names
Before writing a plugin, check whether what you want already exists. These are the main action names the mod currently recognizes. If an action is unknown, the mod logs a warning and falls back to IDLE.
- Brain:
AUTO_REACT(aliasDYNAMIC_AI) - Movement / social:
LOOK,APPROACH,PURSUE,FOLLOW,POSITION_SIDEWALK,IDLE,WANDER,HOLD,STARE,ARGUE(aliasVERBAL),SHOVE,THREATEN,BACK_DOWN,STAGGER,OUTRO,PLAY_ANIM,PLAY_SCENARIO(aliasSCENARIO),SURRENDER,HANDSHAKE,HIGHFIVE,HUG,INSULT_GESTURE,HEADBUTT,MENACE,CONFRONT,INTERROGATE,STANDOFF,TAKE_HOSTAGE - Combat:
AIM,COMBAT,MELEE_COMBAT,RELOAD,FLEE,FLEE_VEHICLE,COWER,WARNING_SHOT,THROW_PROJECTILE,EXECUTION_SHOT,TAKEDOWN - Vehicle:
DRIVE_BY,PARK_VEHICLE,FOLLOW_VEHICLE,CARJACK,EXIT_VEHICLE,ENTER_VEHICLE,RETURN_VEHICLE,OPEN_TRUNK,CLOSE_TRUNK,BLOCK_VEHICLE - Gang:
GANG_SURRENDER,SUICIDE_BOMB,DEAL_SUICIDE_BOMB,ROBBERY_GIVE_MONEY,TORCH_VEHICLE - Police / arrest:
COP_APPROACH,COP_DRIVE_APPROACH,COP_IDLE,COP_SCENARIO,COP_RADIO,COP_CALL_BACKUP,COP_TACTICAL,COP_TASER,COP_NATIVE_ARREST,COP_FOOT_CHASE,COP_FOOT_CHASE_DUO,COP_CUFF,COP_CUFF_SIMPLE,COP_UNCUFF,COP_DIVE_TACKLE,COP_BATON,COP_PURSUIT,COP_SEARCH,COP_SEARCH_VEHICLE,COP_ESCORT_SUSPECT,PATDOWN,ARREST_ON_FLOOR,SUSPECT_ALERTED,SUSPECT_KNEEL,SUSPECT_KNEEL_LOOP,SUSPECT_PRONE,SUSPECT_STANDUP,SUSPECT_HANDS_UP,SUSPECT_WALK_TO_CAR,SUSPECT_ENTER_CAR,SUSPECT_DROP_FLOOR,SUSPECT_GETUP_STATE,SUSPECT_EXIT_VEHICLE_ON_COMMAND,DEPARTURE,COP_RETURN_VEHICLE - Ambulance / rescue:
REVIVE_TARGET,MEDIC_TREAT,MEDIC_CPR,MEDIC_ESCORT,RESCUE_VICTIM,PATIENT_BOARD
This list reflects the currently shipped catalog; if you think an action from a scene should exist and isn't here, it has probably been renamed or moved between releases. Check the mod log (unknown actions warn and fall back to IDLE) and keep your scene content in sync with the build you run.
How to write a plugin
- Create a .NET Framework 4.8 Class Library.
- Add a reference to the
InteractV.Pluginassembly (orInteractV.dllbuilt in development mode; it carriesICustomStateand the types your plugin needs:StateBase,ActorAction,StepDefinition,SceneContext,Config), plusScriptHookVDotNet3.dllforGTA.Ped. - Implement
ICustomState:
public interface ICustomState
{
string ActionName { get; } // the XML action name, e.g. "MY_ACTION"
StateBase Create(
GTA.Ped actor,
GTA.Ped target,
ActorAction action,
StepDefinition step,
SceneContext context,
Config config);
}
StateBaseis the base class every ped state builds on. ImplementProcess()(called every frame while your state is active) and setIsDone = truewhen it's finished. OverrideDisplayNameto identify your state in the logs.OnEnter()/OnExit()are optional hooks for setup/cleanup.- Build your DLL and drop it in
scripts/InteractV/plugins/; the mod creates that folder on first launch if it doesn't exist. - Reference your action from a scenario XML:
<Actor id="A" action="MY_ACTION" target="B" />
Example skeleton
using InteractV.Plugin;
using InteractV.Runtime;
using InteractV.Models;
using InteractV.Configuration;
public class MyActionFactory : ICustomState
{
public string ActionName => "MY_ACTION";
public StateBase Create(GTA.Ped actor, GTA.Ped target,
ActorAction action, StepDefinition step,
SceneContext context, Config config)
{
return new MyActionState(actor, target);
}
}
public class MyActionState : StateBase
{
private readonly GTA.Ped _actor;
private readonly GTA.Ped _target;
public MyActionState(GTA.Ped actor, GTA.Ped target)
{
_actor = actor;
_target = target;
}
public override string DisplayName => "MY_ACTION";
public override void Process()
{
// your logic here, called every frame while the step is active
IsDone = true; // set when the state is complete
}
}
Notes
- The public API surface that plugins build against (the
ICustomStatecontract and its types) is kept stable across releases; a plugin built against one release keeps working after an update, as long as that contract hasn't changed. - Document your own plugin's actions yourself. The built-in list above only covers what ships with InteractV.