Sprites


Almost everything in the game is a sprite. Enemies, items, bullets, gibs, liquids, 3D objects like tables or cars or hidden objects that manage game logic.
Floors, walls, ceilings, particles and decals aren't sprites.

  • Sprites are created by adding a .txt script file in the /Script/Sprites folder of a mod.
  • The name of the .txt file will be how this sprite will be referred to in other script files.
  • To replace a base game sprite, you must name the .txt file using the right sprite ID.
  • Using the same name as a previous mod's sprite will overwrite it.
  • Making a sprite can be simple or complicated. It's recommended that you use a similar existing script example to build your own sprite from it.
  • Sprites are composed of a capsule and a flat mesh. The mesh is used to display the sprite and is either static or faces the player's orientation. The capsule is used for collisions all around the mesh.

    Basic script file content example

    // Every script operation must end with a semicolon. Spaces or line returns are ignored.;
    // Base game sprite file names are a number, so only use non-number names to add new sprite. Ex: BlueChicken.txt;
    // Don't put spaces in file names.;
    // This file contains only a small subset of all possible sprite commands. To make your own sprite, take a similar existing one and copy its script file.;

    // This sprite script is for a chicken bullet fired by a new modded gun.;

    // If true, kills the sprite when it stops moving.;
    killWhenStopped = true;

    // If true, the sprite will orient itself towards the player vertically. Makes somewhat-spherical objects look better.;
    facePlayerPitch = true;

    // If true, the sprite will be placed on the ground after being created.;
    placeOnGround = false;

    // Collision bleed time is the minimum time before a collision-related effect is triggered after the last one.;
    // Objects that leave decals or play sounds when bouncing are a good example.;
    collisionBleedTime = 0.25;

    // Init is the main sprite-creation command. It requires some commands to be called before it and others after it.;
    // definition: Init(Sprite scale vector(scale x, scale y, scale z), material, movement type, collision type, destructible type, activation type);
    // It's possible to randomly choose a material by adding multiple ones separated by ':'. Example: 15:BlueChickenMaterial:33:PotatoMaterial;
    // Movement types;
    // 0 : No movement (but can be moved);
    // 1 : Projectile;
    // 2 : Enemy;
    // 3 : Static (cannot be moved at all);
    // 4 : Physics (bouncing);
    // Collision types;
    // 0 : No collisions;
    // 1 : The flat mesh has collisions;
    // 2 : The capsule shape around the sprite has collisions;
    // 3 : Overlap (don't use);
    // Destruction types;
    // 0 : Can't be destroyed;
    // 1 : Disappears on destruction;
    // 2 : Explodes (not used, becomes 1);
    // 3 : Slice (not used, becomes 1);
    // 4 : Falls down like a flat mesh;
    // 5 : Context (depends on how the destruction happened. Mostly for enemies);
    // Activation types;
    // 0 : Can't be activated;
    // 1 : Can only be activated once;
    // 2 : Can be activated infinitely;
    // 3 : This is a switch;
    Init(vector(0.75,0.75,0.75), BlueChickenMaterial, 1, 2, 1, 0);

    // How much damage the sprite can take before being destroyed;
    life = 100;
    // How much damage the sprite does when colliding with another one;
    damage = 20;

    // Set to false means that the mesh won't make shadows even if the material allows it;
    mesh.CastShadow = false;

    // Set the type of collision of this sprite's capsule. This affects how it'll react with other objects it can collide with.;
    // Possible collision types;
    // 0 : Static (walls or static sprites);
    // 1 : Dynamic (most moving sprites);
    // 2 : Pawn (the player);
    // 6 : Usually for projectiles that can pass through most objects;
    // 7 : Most projectiles;
    // 14 : The player in multiplayer;
    capsule.CollisionObjectType = 7;

    // Set what to do when colliding with an object of type 7;
    // Collision responses;
    // 0 : Ignore;
    // 2 : Block;
    capsule.SetCollisionResponseToChannel(7, 0);
    capsule.SetCollisionResponseToChannel(2, 0);
    capsule.SetCollisionResponseToChannel(14, 0);

    // Set the mass of the capsule. This affects how heavy it reacts. 0.0 means it isn't affected by its weight;
    capsule.AllMassScale = 0.0;

    // tmpSound is a temporary sound structure that can be used for many things. First you need to set all its values;
    // tmpSound.m_sound is simply which sound to use;
    tmpSound.m_sound = RubberChickenSound;
    // The minimum possible volume. Random;
    tmpSound.m_volumeMin = 1.0;
    // The maximum possible volume. Random;
    tmpSound.m_volumeMax = 1.0;
    // The minimum possible pitch. Random;
    tmpSound.m_pitchMin = 0.9;
    // The maximum possible pitch. Random;
    tmpSound.m_pitchMax = 1.1;
    // true if this should be played as a UI sound;
    tmpSound.m_UI = false;
    // This adds the sound to collisionSounds, which will play all its sounds when a collision happens;
    collisionSounds.Push(tmpSound);

    // decalStruct is a temporary decal structure that can be used to add decals when getting damaged, dying or even to spawn decals immediately.;
    // If true, doesn't add a decal at this position if another already exists close.;
    decalStruct.m_preventOverlapping = false;
    // If true, the decal will rotate according to the impact velocity of the sprite.;
    decalStruct.m_rotateVelocity = true;
    // decalStruct.m_decal is the actual decal to use.;
    decalStruct.m_decal = BlueChickenDecal;
    // If true, when it detects an overlap with a decal of the same type, it'll instead grow the size of the original decal.;
    decalStruct.m_allowsGrowing = false;
    // The minimum quality setting to spawn the decal at. 0 is low and 3 is Epic in the decorations quality settings of the game.;
    decalStruct.m_minFoliageQuality = 1;
    // This adds the decal to killDecals which will spawn a decal at the collision point upon death of this sprite.;
    killDecals.Push(decalStruct);



    Linked sprite script file content example

    // Every script operation must end with a semicolon. Spaces or line returns are ignored.;
    // Base game sprite file names are a number, so only use non-number names to add new sprite. Ex: BlueChicken.txt;
    // Don't put spaces in file names.;
    // This file contains only a small subset of all possible sprite commands. To make your own sprite, take a similar existing one and copy its script file.;

    // This sprite script is for a 3D cube crate composed of 5 flat sprites. (the bottom face isn't there in order to save performance);
    // Since it's hard to properly scale and position these 5 sprites into a cube in the game, you can change and save this file and spawn a new sprite of this type and it'll load the latest script. Except if it's a pooled sprite like weapon bullets.;

    // This is to signify that this sprite has sub sprites.;
    linkWithChildren = true;

    // Setting this to false makes sure the sprite doesn't face the player like other sprites.;
    facePlayer = false;

    // Set to true to allow damage to be done to this sprite.;
    // Since this sprite is composed of 6 other sprites, the game will sync the life as one.;
    canBeDamaged = true;

    // If true, the sprite will be placed on the ground after being created.;
    placeOnGround = false;

    // If true, fire can be passed to this sprite and damage it over time.;
    flammable = true;

    // Init is the main sprite-creation command. It requires some commands to be called before it and others after it.;
    // definition: Init(Sprite scale vector(scale x, scale y, scale z), material, movement type, collision type, destructible type, activation type);
    // It's possible to randomly choose a material by adding multiple ones separated by ':'. Example: 15:BlueChickenMaterial:33:PotatoMaterial;
    // Movement types;
    // 0 : No movement (but can be moved);
    // 1 : Projectile;
    // 2 : Enemy;
    // 3 : Static (cannot be moved at all);
    // 4 : Physics (bouncing);
    // Collision types;
    // 0 : No collisions;
    // 1 : The flat mesh has collisions;
    // 2 : The capsule shape around the sprite has collisions;
    // 3 : Overlap (don't use);
    // Destruction types;
    // 0 : Can't be destroyed;
    // 1 : Disappears on destruction;
    // 2 : Explodes (not used, becomes 1);
    // 3 : Slice (not used, becomes 1);
    // 4 : Falls down like a flat mesh;
    // 5 : Context (depends on how the destruction happened. Mostly for enemies);
    // Activation types;
    // 0 : Can't be activated;
    // 1 : Can only be activated once;
    // 2 : Can be activated infinitely;
    // 3 : This is a switch;
    Init(vector(1.5,1.5,1.5), 1198, 3, 1, 2, 0);

    // How much damage the sprite can take before being destroyed;
    life = 10;

    // Set the type of collision of this sprite's mesh. This affects how it'll react with other objects it can collide with.;
    // Possible collision types;
    // 0 : Static (walls or static sprites);
    // 1 : Dynamic (most moving sprites);
    // 2 : Pawn (the player);
    // 6 : Usually for projectiles that can pass through most objects;
    // 7 : Most projectiles;
    // 14 : The player in multiplayer;
    mesh.CollisionObjectType = 0;

    // parStruct is a temporary particle structure that can be used to spawnn particles in various ways.;
    // If true, the particle will be attached to this sprite and move with it. It'll also be destroyed if the sprite is destroyed.;
    partStruct.m_managed = false;
    // If true, if the other sprite in the collision bleeds, only play the other sprite's bleed particles instead of our own. Useful to not spawn generic bullet hit spark on fleshy enemies that can bleed isntead.;
    partStruct.m_removeIfTargetBleeds = true;
    // The normal points outward from the impact at the impact angle. You can offset the particle towards that direction, so that big particles don't clip with the sprite.;
    partStruct.m_normalOffset = 5.0;
    // If true, will rotate the particle to face the impact.;
    partStruct.m_rotate = false;
    // The actual type of particle to spawn.;
    partStruct.m_type = 2;
    // If true, overwrite the impact location and use the current's sprite location instead.;
    partStruct.m_useActorCoordinates = false;
    // You can specify a x, y, z offset to the particle if it should not come out of the center of the sprite.;
    partStruct.m_offset = vector(0.0,0.0,0.0);
    // This adds the particle structure to bleedParticles which will spawn these particles every time the sprite takes damage.;
    bleedParticles.Push(partStruct);

    // The children tag tells the script that the master sprite is done and that we're going to define new children sprites linked to it.;
    // All other sprites below will execute the commands we called before this point, and then do more.;
    [children]

    // Take the position the master sprite was spawned at and offset it. You can offset x, y and z. We only do y and z here.;
    // cubeSize is a magic value that represents the length of a wall/floor/ceiling cube in the game. "0.25 * cubeSize" means that this sprite should be offset by 25% of a cube's size.;
    loc.Y += 0.25 * cubeSize;
    loc.Z += 0.25 * cubeSize;

    // SpawnChild calls every command called before [children] and then changes the parameters below.;
    // The first time SpawnChild is called, it actually affects the master sprite and doesn't create a child.;
    // Definition : SpawnChild(sprite type, rotation done to the sprite's mesh(pitch, yaw, roll), sprite scale vector(x, y, z), ;
    // string representing a different mesh collision shape(can be left empty, and usually should), material(can choose randomly by using ':'. -1 means use the master's material);
    SpawnChild(885, rotation(0.0, 0.0, 90.0), vector(1.5,1.5,1.5), , -1);

    // Completely unused.;
    verticalLinkedSprite = true;

    // AI is a subject on its own. Please check the AI section in the modding documentation at https://blazingbitgames.com/mods ;
    // AddDeathNode means that this runs when the sprite is destroyed. Type 374 spawns low quality fast simple sprite of wood chips.;
    ai.AddDeathNode(374, 13, 47.0, 4.0, 500.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -1.0, 2.0, 0.0, 1.0);
    ai.AddDeathNode(374, 13, 1520.0, 1.0, 5000.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -1.0, 2.0, 0.0, 1.0);
    ai.AddDeathNode(374, 13, 1521.0, 1.0, 2500.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -1.0, 2.0, 0.0, 1.0);
    // AddHitNode means that this runs every time the sprite is damaged. Type 56 plays a wood hit sound.;
    ai.AddHitNode(56, 8, 0.0, 0.0, 21.0, 1.0, 1.0, 1.0, 1.2, -1.0);
    ai.AddHitNode(374, 13, 47.0, 2.0, 500.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, -1.0, 2.0, 0.0, 1.0);

    loc.Y -= 0.25 * cubeSize;
    loc.Z += 0.25 * cubeSize;

    SpawnChild(885, rotation(0.0, 180.0, 90.0), vector(1.5,1.5,1.5), , -1);

    verticalLinkedSprite = true;

    ai.AddDeathNode(374, 13, 47.0, 4.0, 500.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -1.0, 2.0, 0.0, 1.0);
    ai.AddDeathNode(374, 13, 1521.0, 1.0, 5000.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -1.0, 2.0, 0.0, 1.0);
    ai.AddDeathNode(374, 13, 1520.0, 1.0, 2500.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -1.0, 2.0, 0.0, 1.0);
    ai.AddHitNode(56, 8, 0.0, 0.0, 21.0, 1.0, 1.0, 1.0, 1.2, -1.0);
    ai.AddHitNode(374, 13, 47.0, 2.0, 500.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, -1.0, 2.0, 0.0, 1.0);

    loc.X += 0.25 * cubeSize;
    loc.Z += 0.25 * cubeSize;

    SpawnChild(885, rotation(0.0, -90.0, 90.0), vector(1.5,1.5,1.5), , -1);

    verticalLinkedSprite = true;

    ai.AddDeathNode(374, 13, 47.0, 4.0, 500.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -1.0, 2.0, 0.0, 1.0);
    ai.AddDeathNode(374, 13, 1520.0, 1.0, 5000.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -1.0, 2.0, 0.0, 1.0);
    ai.AddDeathNode(374, 13, 1521.0, 1.0, 2500.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -1.0, 2.0, 0.0, 1.0);
    ai.AddHitNode(56, 8, 0.0, 0.0, 21.0, 1.0, 1.0, 1.0, 1.2, -1.0);
    ai.AddHitNode(374, 13, 47.0, 2.0, 500.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, -1.0, 2.0, 0.0, 1.0);

    loc.X -= 0.25 * cubeSize;
    loc.Z += 0.25 * cubeSize;

    SpawnChild(885, rotation(0.0, 90.0, 90.0), vector(1.5,1.5,1.5), , -1);

    verticalLinkedSprite = true;

    ai.AddDeathNode(374, 13, 47.0, 4.0, 500.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -1.0, 2.0, 0.0, 1.0);
    ai.AddDeathNode(374, 13, 1521.0, 1.0, 5000.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -1.0, 2.0, 0.0, 1.0);
    ai.AddDeathNode(374, 13, 1520.0, 1.0, 2500.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -1.0, 2.0, 0.0, 1.0);
    ai.AddHitNode(56, 8, 0.0, 0.0, 21.0, 1.0, 1.0, 1.0, 1.2, -1.0);
    ai.AddHitNode(374, 13, 47.0, 2.0, 500.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, -1.0, 2.0, 0.0, 1.0);

    loc.Z += 0.5 * cubeSize;

    SpawnChild(885, rotation(180.0, 0.0, 0.0), vector(1.5,1.5,1.5), , -1);

    // Type 20 spawns crate loot on death.;
    ai.AddDeathNode(20, 0);
    ai.AddDeathNode(56, 8, 0.0, 0.0, 90.0, 1.0, 1.0, 0.85, 0.95, -1.0);
    // Type 63 increases the clutter combo.;
    ai.AddDeathNode(63, 0);
    ai.AddDeathNode(374, 13, 47.0, 4.0, 500.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -1.0, 2.0, 0.0, 1.0);
    ai.AddDeathNode(374, 13, 1520.0, 1.0, 5000.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -1.0, 2.0, 0.0, 1.0);
    ai.AddDeathNode(374, 13, 1521.0, 1.0, 2500.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -1.0, 2.0, 0.0, 1.0);
    ai.AddHitNode(56, 8, 0.0, 0.0, 21.0, 1.0, 1.0, 1.0, 1.2, -1.0);
    ai.AddHitNode(374, 13, 47.0, 2.0, 500.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, -1.0, 2.0, 0.0, 1.0);

    partStruct.m_managed = false;
    partStruct.m_removeIfTargetBleeds = false;
    partStruct.m_normalOffset = 0.0;
    partStruct.m_rotate = false;
    // Type 21 is a smoke particles that only spawns for this last sprite.;
    partStruct.m_type = 21;
    partStruct.m_useActorCoordinates = true;
    partStruct.m_offset = vector(0.0,0.0,-0.25 * cubeSize);
    // This adds the particle structure to killParticles which will spawn these particles when the sprite dies.;
    killParticles.Push(partStruct);