-
Notifications
You must be signed in to change notification settings - Fork 6
en Override System
Documentation moved: This page is archived. See the up-to-date guide at innovault.wiki.
- Override System (full index)
- ItemOverride
- NPCOverride
- PlayerOverride
- ProjOverride
- ItemUseAnimation
- MenuOverride
- TileOverride
- SceneOverride
- GlobalDustOverride
Three Override base classes (Item / Player / NPC): singleton behavior overrides by
TargetIDwithout editing vanilla code.
Override is built on VaultType<T> and binds via TargetID. Compared to tModLoader GlobalItem / GlobalNPC:
-
Precise ID matching: Bind to specific items/NPCs via
TargetID -
Universal override:
TargetID = -1applies to all objects -
Dual-layer hooks: Standard hooks plus
On_prefix hooks; the latter can interrupt the rest of the chain -
Query system:
TryFetchByID/GetOverride<T>()for quick instance retrieval
| Component | Base Class | Purpose |
|---|---|---|
ItemOverride |
VaultType<ItemOverride> |
Override item behavior (SetDefaults, Shoot, ModifyTooltips…) |
PlayerOverride |
VaultType<PlayerOverride> |
Override player behavior (damage modification, hit, death…) |
NPCOverride |
VaultType<NPCOverride> |
Override NPC behavior (AI, draw, death, loot…) |
using InnoVault.GameSystem;
using Terraria;
using Terraria.ID;
public class WoodenSwordOverride : ItemOverride
{
// Bind to Wooden Sword
public override int TargetID => ItemID.WoodenSword;
// Modify item default properties
public override void SetDefaults(Item item) {
item.damage = 50;
item.useTime = 10;
}
// Modify item tooltips
public override void ModifyTooltips(Item item, List<TooltipLine> tooltips) {
tooltips.Add(new TooltipLine(Mod, "CustomLine", "Modified by Override!"));
}
}
TargetID Value |
Behavior |
|---|---|
> 0 |
Only applies to that item ID, registered to the ByID dictionary |
= -1 |
Applies to all items, registered to UniversalInstances
|
= 0 (ItemID.None) |
Not registered, no effect |
The following static dictionaries can be modified in SetStaticDefaults to control prefixes:
// Allow/disallow all prefixes
ItemOverride.ItemAllowPrefixDic[ItemID.WoodenSword] = true;
// Allow/disallow melee prefixes
ItemOverride.ItemMeleePrefixDic[ItemID.WoodenSword] = false;
// Allow/disallow ranged prefixes
ItemOverride.ItemRangedPrefixDic[ItemID.WoodenSword] = null; // null = default logicMost ItemOverride hooks provide two versions simultaneously:
| Standard Hook | On_ Hook | Difference |
|---|---|---|
ModifyHitNPC(...) |
On_ModifyHitNPC(...) |
On_ version can return bool? to control execution chain |
ModifyTooltips(...) |
On_ModifyTooltips(...) |
On_ version can return bool? to control execution chain |
Shoot(...) |
On_Shoot(...) |
On_ version can return bool? to control execution chain |
CanUseItem(...) |
On_CanUseItem(...) |
On_ version can return bool? to control execution chain |
On_ hook return value rules:
-
null— Continue executing all subsequent methods (original ModItem + GlobalItem) -
true— Only execute the original ModItem method, block GlobalItem's additional logic -
false— Block all subsequent logic
| Hook | Description |
|---|---|
SetDefaults(Item) |
Set properties when item is created |
ModifyName(Item, ref string) |
Modify item logical name (affects search) |
ModifyAffixName(Item, ref string) |
Modify item display name (affects UI) |
CanUseItem(Item, Player) |
Control whether item can be used |
Shoot(Item, Player, source, pos, vel, type, dmg, kb) |
Shoot hook |
ModifyShootStats(Item, Player, ref pos, ref vel, ref type, ref dmg, ref kb) |
Modify shoot parameters |
ModifyHitNPC(Item, Player, NPC, ref modifiers) |
Modify hit damage |
OnHitNPC(Item, Player, NPC, hit, damageDone) |
Post-hit callback |
ModifyTooltips(Item, List<TooltipLine>) |
Modify item tooltips |
ModifyWeaponDamage(Item, Player, ref StatModifier) |
Modify weapon damage |
ModifyWeaponCrit(Item, Player, ref float) |
Modify weapon crit |
UpdateAccessory(Item, Player, bool) |
Accessory equip update |
UpdateEquip(Item, Player) |
Equipment effect update |
UpdateArmorByHead(Player, Item body, Item legs) |
Set bonus effects |
PreDrawInInventory(...) / PostDrawInInventory(...)
|
Draw in inventory |
PreShimmering(Item) / PostShimmering(Item)
|
Before/after shimmer transform |
SaveData(Item, TagCompound) / LoadData(Item, TagCompound)
|
Item data persistence |
HoldItem(Item, Player) |
Held behavior |
RightClick(Item, Player) |
Right-click event |
AddRecipe(Item) / ModifyRecipe(...)
|
Recipe system |
// Find all overrides by ID
if (ItemOverride.TryFetchByID(ItemID.WoodenSword, out var overrides)) {
foreach (var ov in overrides.Values) { /* ... */ }
}
// Find single override by ID
if (ItemOverride.TryFetchByID(ItemID.WoodenSword, out ItemOverride singleOv)) {
// Use singleOv
}
// Generic retrieval
var myOverride = ItemOverride.GetOverride<WoodenSwordOverride>();using InnoVault.GameSystem;
using Terraria;
public class MyPlayerOverride : PlayerOverride
{
// Set default properties
public override void SetDefaults() {
// Initialize
}
// Per-frame update
public override void PostUpdate() {
Player.statDefense += 10;
}
// Reset effects
public override void ResetEffects() {
// Reset per-frame data
}
}-
Per-player instances: Each player has an independent
PlayerOverridecloned instance -
Playerproperty automatically points to the owning player -
TargetItemID: If set to non-ItemID.None, related item hooks only apply to that item
| Hook | Description |
|---|---|
SetDefaults() |
Initialize on load |
ResetEffects() |
Reset per frame |
PostUpdate() |
Per-frame update (runs last) |
On_ModifyHitNPCWithItem(Item, NPC, ref modifiers) |
Item hit modification |
On_ModifyHitNPCWithProj(Proj, NPC, ref modifiers) |
Projectile hit modification |
On_OnHitNPC(NPC, hit, damageDone) |
Post-hit callback |
On_Hurt(ref HurtState) |
Hurt processing |
On_PreKill(damage, hitDir, pvp, ...) |
Pre-death intercept, return false to prevent death |
CanSwitchWeapon() |
Whether weapon switching is allowed |
CanUseItem(Item) |
Whether item can be used |
ItemShoot(Item, source, pos, vel, type, dmg, kb) |
Item shoot override |
On_CanBeHitByProjectile(Projectile) |
Whether hit by projectile |
On_PreEmitUseVisuals(Item, ref Rectangle) |
Before item use visual effects |
PreDrawPlayers(ref Camera, ref players) |
Before player draw |
PreIsSceneEffectActive(ModSceneEffect) |
Scene effect override |
// Get from player
if (PlayerOverride.TryFetchByPlayer(player, out var overrides)) {
foreach (var ov in overrides.Values) { /* ... */ }
}
// Generic retrieval (prototype instance, not per-player)
var prototype = PlayerOverride.GetOverride<MyPlayerOverride>();
// Get specific player's instance
var myOv = player.GetOverride<MyPlayerOverride>();using InnoVault.GameSystem;
using Terraria;
using Terraria.ID;
public class ZombieOverride : NPCOverride
{
public override int TargetID => NPCID.Zombie;
// Initialize instance data
public override void SetProperty() {
ai[0] = 100f; // Custom AI data
}
// Override AI
public override bool AI() {
// Custom behavior...
ai[0] -= 1;
if (ai[0] <= 0) {
npc.life = 0;
}
return false; // Block vanilla AI
}
// Post-AI processing
public override void PostAI() {
// Processing after AI runs
}
}- Per-NPC instances: Each NPC has an independent cloned instance
- Built-in 12-slot
ai[]andlocalAI[]arrays -
OverrideID: Globally unique number for network sync identification -
npcproperty automatically points to the associated NPC
| Hook | Return | Description |
|---|---|---|
SetProperty() |
void |
Initialize when NPC is created |
AI() |
bool |
false blocks subsequent AI |
PostAI() |
void |
After AI runs |
On_PreKill() |
bool? |
Non-null blocks death logic |
CheckDead() |
bool? |
Non-null blocks death check |
SpecialOnKill() |
bool? |
Non-null blocks kill event |
CheckActive() |
bool |
Active check |
| Hook | Description |
|---|---|
On_ModifyIncomingHit(NPC, ref modifiers) |
Override hit damage formula |
On_OnHitByProjectile(NPC, Projectile, hit, dmg) |
Hit by projectile |
On_OnHitByItem(Player, Item, hit, dmg) |
Hit by item |
ModifyHitByItem(Player, Item, ref modifiers) |
Modify item hit damage |
ModifyHitByProjectile(Projectile, ref modifiers) |
Modify projectile hit damage |
CanBeHitByItem/NPC/Projectile(...) |
Whether can be hit |
| Hook | Description |
|---|---|
Draw(SpriteBatch, screenPos, drawColor) |
Override draw |
PostDraw(SpriteBatch, screenPos, drawColor) |
Post-draw |
FindFrame(frameHeight) |
Frame animation update |
BossHeadSlot(ref index) |
Map boss icon |
DrawHealthBar(hbPos, ref scale, ref pos) |
Health bar draw |
ModifyDrawNPCHeadBoss(...) |
Boss head portrait data |
| Hook | Description |
|---|---|
GetChat(ref string) |
Modify chat content |
SetChatButtons(ref btn1, ref btn2) |
Chat button names |
PreChatButtonClicked(firstButton) |
Pre-button click intercept |
OnChatButtonClicked(firstButton) |
Button click callback |
ModifyActiveShop(shopName, items) |
Modify shop inventory |
ModifyNPCLoot(NPC, NPCLoot) |
Modify loot table |
public override bool NeedSaving() => true; // Enable saving
public override void SaveData(TagCompound tag) {
tag["customHP"] = ai[0];
}
public override void LoadData(TagCompound tag) {
ai[0] = tag.GetFloat("customHP");
}NPCOverride provides multiple network sync mechanisms:
// 1. ai[] auto-sync: set npc.netUpdate = true
npc.netUpdate = true;
// 2. Additional data sync: set NetOtherWorkSend (server-side only)
NetOtherWorkSend = true;
// 3. Override custom network data
public override void OtherNetWorkSend(ModPacket netMessage) {
netMessage.Write(localAI[0]);
}
public override void OtherNetWorkReceive(BinaryReader reader) {
localAI[0] = reader.ReadSingle();
}
// 4. Client-initiated send (bidirectional sync)
SendNetworkData();ai[] uses bitmask optimization, only sending non-zero slots to reduce bandwidth.
All Override types support the CanOverride() method for dynamically enabling/disabling overrides at runtime:
public override bool CanOverride() {
// Only takes effect under certain conditions
return SomeCondition;
}TryFetchByID automatically filters out instances where CanOverride() returns false.
| Previous | Home | Next |
|---|---|---|
| SaveContent Save System | Home | SyncVar Network Sync |