Projectile Class Documentation - tModLoader/tModLoader GitHub Wiki


This Guide has been updated to 1.4. If you need to view the old 1.3 version of this wiki page, click here


Projectile Class Documentation

This page lists methods and fields pertaining to the Projectile class. This page is useful for understanding what to use in ModProjectile.SetDefaults and ModProjectile.AI. Only common fields and methods are listed. More documentation for methods and fields not listed here is built into tModLoader when using your IDE properly. Feel free to add to this list if you find an important field that is missing.

Index
Fields
Methods

Fields and Properties

You can assign these fields to give your ModProjectile various values. Typically you'll want to refer to this page when writing code for ModProjectile.SetDefaults. Be sure to visit Vanilla Projectile Field Values to see what values vanilla projectiles use for these fields. All fields listed are public unless otherwise noted.

Vanilla

Field Type Default Value Description
type int 0 This is the ProjectileID, automatically set.
aiStyle int 0 Selects which vanilla code to use for the AI method. Modders can use vanilla aiStyle to mimic AI code already in the game. See ModProjectile.AIType and ExampleCloneProjectile to see how to use vanilla ai. If you are using custom AI code, you can omit this line.
width int 0 The width of the projectile's hitbox in pixels.
height int 0 The height of the projectile's hitbox in pixels.
friendly bool false If True, this projectile will hurt enemies (!npc.friendly)
hostile bool false If True, this projectile will hurt players and friendly npcs (npc.friendly)
maxPenetrate int 1 How many npc can it hit before dying. (Or tile bounces) Set at the end of SetDefaults automatically to the current value of penetrate.
penetrate int 1 Current penetrate value.
alpha int 0 How transparent to draw this projectile. 0 to 255. 255 is completely transparent. ExampleBullet sets this to 255, and the projectile aiStyle of 1 automatically decreases alpha each tick, letting the projectile fade in quickly after being spawned. Useful for projectiles that look odd when initially spawned on the weapon because of texture overlap.
timeLeft int 3600 Each update timeLeft is decreased by 1. Once timeLeft hits 0, the Projectile will naturally despawn. The default value, 3600, is measured in ticks, which are usually 60 per seconds, so the default despawn time is about 60 seconds. Adjust this if you want the projectile to fizzle early rather than travel infinitely. Note that extraUpdates will cause it to decrease faster than normal time because Update is being called more often.
tileCollide bool true The projectile will collide with tiles, usually bouncing or killing the tile depending on ModProjectile.OnTileCollide. ExampleBullet shows how to bounce.
ignoreWater bool false The projectile will not be affected by water.
extraUpdates int 0 Additional update steps per tick. Useful for really fast projectiles such as Shadowbeam Staff.
scale float 1f Scales the projectile drawing, but not the hitbox, making this not suitable for affecting hitbox.
frame int 0 The frame # in the spritesheet that this projectile will be drawn with. Example: projectile has 4 frames, then frame can have values between 0 and 3
frameCounter int 0 Used as a timer to decide when to change frame
rotation float 0f Rotation of the projectile. Radians not Degrees. Use MathHelper if you want to convert degrees to radians. 0 is facing right, pi/2 is facing down, and so on.
oldPos Vector2[] Holds the value of Projectile.position from previous updates. Use for drawing trails. Must be used with ProjectileID.Sets.TrailCacheLength and ProjectileID.Sets.TrailingMode to be used. See ExampleBullet
oldRot float[] Holds the value of Projectile.rotation from previous updates. See above.
oldSpriteDirection int[] Holds the value of Projectile.spriteDirection from previous updates. See above.
ai float[] 0, 0 An array used for any sort of data storage, which is occasionally synced to the server. Call netUpdate to manually sync.
localAI float[] 0, 0 Acts like ai, but does not sync to the server.
noDropItem bool false Set to true if you don't want this item to have a chance to recover the ammo item that shot this. For example, if you shoot the wooden arrow projectile, it will sometimes drop the wooded arrow item. If your weapon shoots multiple arrows for 1 ammo, you might want to consider setting this field to prevent infinite ammo glitches.
minion bool false Indicates that this projectile is a minion
minionSlots float 0f Set to 1f on a minion to count it towards the minion limit of the summoning player (Optic Staff summons two minions at once with 0.5f each)
spriteDirection int
hide bool Projectile is not drawn normally. See (TODO) ExampleBehindTilesProjectile
lavaWet bool false Indicates that this projectile is currently in lava
wetCount
wet bool false Indicates that this projectile is currently in water
netImportant bool false Indicates that this projectile will be synced to a joining player (by default, any projectiles active before the player joins (besides pets) are not synced over). Example: glowsticks
netUpdate bool false Set manually to true in ModProjectile.AI once to make it sync its current ai[] array to the server and other clients (depending on what the Main.netMode is where this is set to true in)
netUpdate2 bool false Used internally to check for projectiles that spam netUpdate. Don't use it yourself manually
numUpdates
identity int The projectile's universal unique identifier, which is the same on all clients and the server. Usually used to find the same projectile on multiple clients and/or the server, e.g. Projectile match = Main.projectile.FirstOrDefault(x => x.identity == identity);
light float 0f Set to a value above 0f to make this projectile emit a white light (higher number: more intensive light. 1f being stronger than a torch))
position Vector2
velocity Vector2 Vector2.Zero The amount of coordinates this projectile will move per tick
active bool True if this Projectile actually exists. Main.projectile will hold a lot of junk data in it. If you are iterating over Main.projectile, be sure to check active to make sure the projectile is still alive. For example, old projectiles that die aren't removed from the array, they simply have active set to false.
owner The index of the player who owns this projectile. In Multiplayer, Clients "own" projectiles that they shoot, while the Server "owns" projectiles spawned by NPCs and the World. It is very important to check if (projectile.owner == Main.myPlayer) for things like dropping items or spawning projectiles in ModProjectile.AI and some other methods because AI runs simultaneously on all Clients and the Server. This check gates some of the code that should only run on the owners computer. ExamplePaperAirplaneProjectile checks owner for spawning the recovered item. If you don't do this, you will run into desync bugs in your mod.
damage int 0 This will always be set in Projectile.NewProjectile based on the weapons damage. Don't assume that setting it to something in SetDefaults does anything.
originalDamage int 0 Set manually on projectile spawn in vanilla for minions and sentries, aswell as automatically by tML when ContinuouslyUpdateDamage is true. Causes the projectile to update its damage every tick (contrary to the usual design of "snapshotting" damage)
knockBack float 0f
trap bool false If true, this projectile was spawned by a trap tile.
npcProj bool false If true, this projectile was spawned by a friendly Town NPC.
projUUID

tModLoader

Field Type Default Value Description
ArmorPenetration int 0 The number of defense points that this projectile can ignore on its own. Cannot be set to negative values. On spawn, if this projectile was fired from a weapon, this value has the total armor penetration of the weapon that made the projectile added to itself.
CritChance int 0 The critical strike chance modifier of this projectile. Cannot be set to negative values. On spawn, if this projectile was fired from a weapon, this value has the total critical strike chance of the weapon that made the projectile added to itself.
DamageType DamageClass DamageClass.Default The damage class of the projectile, relates to damage bonuses and crit. Vanilla options can be assigned via the DamageClass fields, and modded through ModContent.GetInstance<CustomDamageClassNameHere>()
ContinuouslyUpdateDamage bool false If set, damage will be recalculated based on originalDamage, DamageType and the owning player, just like minions and sentries.
ModProjectile ModProjectile null The ModProjectile instance that controls the behavior of this projectile. This property is null if this is not a modded projectile.
Globals RefReadOnlyArray<Instanced> Do not touch. Use Projectile.GetGlobalProjectile

Methods

Only the most basic methods are documented here. Other documented methods will show documentation in your IDE when you hover over them.

Vanilla

Remember that static methods are called by writing the classname and non-static methods use the instance name. Projectile.NewProjectile(...) vs someProjectileInstance.Kill(...)

public static int NewProjectile(IEntitySource spawnSource, float X, float Y, float SpeedX, float SpeedY, int Type, int Damage, float KnockBack, int Owner = 255, float ai0 = 0f, float ai1 = 0f)

Spawns a projectile in the world. The owner variable should pretty much always be set to Main.myPlayer. See IEntitySource for info on the spawnSource parameter.

Proper usage with multiplayer in mind:

  • If spawned from a player (via accessory, on hit by, on use, etc.), only the "owner" of this projectile should spawn it:
if (Main.myPlayer == player.whoAmI)
{
    //player.whoAmI could be Projectile.owner instead if this runs from a projectile
    Projectile.NewProjectile(...);
}
  • Otherwise, if no player "owns" the projectile (such as a friendly or hostile NPC shooting it, or the world itself spawns it), spawn it on the server (or singleplayer)
if (Main.netMode != NetmodeID.MultiplayerClient)
{
    Projectile.NewProjectile(...);
}

In both cases, this guarantees that NewProjectile runs only on one instance of the game, such that no duplicate projectiles spawn.

public static int GetByUUID(int owner, int uuid)

Do not use this method to get a projectile on a client based on its Projectile.identity. Instead, loop through the Main.projectile[] on the client you wish to find the projectile on and check if there is a projectile that has the same Projectile.identity as the projectile you want to find.

tModLoader

public T GetGlobalProjectile<T>(bool exactType = true) where T : GlobalProjectile

Gets the GlobalProjectile instance (of the specified Type) associated with this projectile instance.

public void CloneDefaults(int type)

Allows you to copy the defaults of a different type of projectile.

public bool CountsAsClass<T>() where T : DamageClass

Returns true if the projectile counts as the given damage class (of the specified type) towards effects.

public bool CountsAsClass(DamageClass damageClass)

Returns true if the projectile counts as the given damage class towards effects.

⚠️ **GitHub.com Fallback** ⚠️