Wall - tModLoader/tModLoader GitHub Wiki
Walls are fairly straightforward and creating a ModWall
is mostly an exercise in following the existing patterns. Like tiles, walls are comprised of 2 parts, the ModItem
that places the wall, and the ModWall
itself.
An Item
will place a specific Wall
when Item.createWall
is set to the WallType
of the ModWall
. The ModWall
will typically return the ModItem
as well. This process is automatic for walls that are placed by the same item they return, otherwise use RegisterItemDrop(ModContent.ItemType<ItemName>());
in ModWall.SetStaticDefaults
to manually specify the item drop.
ExampleWall
in ExampleMod is a basic example. It has 4 files:
-
ExampleMod/Content/Walls/ExampleWall.cs is the actual
ModWall
class -
ExampleMod/Content/Walls/ExampleWall.png is the texture for the
ModWall
-
ExampleMod/Content/Items/Placeable/ExampleWall.cs is the corresponding
ModItem
class that places theExampleWall
ModWall
.- Note: The code
Item.DefaultToPlacableWall((ushort)ModContent.WallType<Walls.ExampleWall>());
inModWall.SetStaticDefaults
automatically setsItem.createWall
and all other properties common to wall items.
- Note: The code
-
ExampleMod/Content/Items/Placeable/ExampleWall.png is the texture for the
ExampleWall
ModItem
.
ExampleWallUnsafe
in ExampleMod is also a basic example, but only has 2 files, the ModWall
class and corresponding texture. ExampleWallUnsafe
doesn't have an item that places it, so RegisterItemDrop
is used to register the item drop.
See ExampleMod/Content/Walls/ExampleWallAdvanced.cs for an advanced example showcasing animation, custom framing, and lighting.
The texture for a wall has several sections for drawing the wall in different positions depending on which neighbors are the same wall type. Notice how for each orientation, there are 3 options. The sections are referred to as "style" and the options are referred to as "WallFrameNumber". ExampleWall
is based off of Gemspark
walls since it is simple to comprehend. Consult other existing wall textures for more detailed examples.
If Main.wallLargeFrames
is used, a 4th WallFrameNumber
is added to the mix for each style
to add even more variety. That template is shown here:
This template shows how Main.wallLargeFrames
values of 1 ("Phlebas") and 2 ("Lazure") produce a deterministic pattern rather than a random pattern.
If the wall is animated, the pattern is repeated. This is only supported for non-Main.wallLargeFrames
walls.
In ModWall.SetStaticDefaults
, various data can be assigned to affect the behavior of the wall.
If true, the wall is considered a safe wall, used for various things.
If true, the wall is considered a dungeon wall.
If true, light flows in from the background, such as fences and glass.
If 1, the "Phlebas" pattern is used (Plating-type walls). If 2, the "Lazure" pattern is used. These both use the 4th WallFrameNumber
option.
Assign to a known WallID
to blend with similar walls.
As seen above, the texture for animated walls has several copies of the template. The wall will animate in accordance with the timing and pattern provided in the ModWall.AnimateWall
hook.
This example loops 7 frames of animation, switching frames every 10 frames. A cycling or more advanced pattern can be made with some effort.
public override void AnimateWall(ref byte frame, ref byte frameCounter) {
frameCounter++;
if (frameCounter >= 10) {
frameCounter = 0;
frame++;
if (frame >= 7)
frame = 0;
}
// Or, more succinctly:
if (++frameCounter >= 10) {
frameCounter = 0;
frame = (byte)(++frame % 7);
}
}
Many Terraria walls have safe and unsafe variants. The safe wall variant is the wall placed by the item the player receives when mining the unsafe wall. The unsafe wall is placed during world generation and usually can't be placed by the player. The unsafe wall is used in NPC Spawning calculations. This separation lets players mine walls and use them for decoration without risking enabling various enemies from specifically spawning in their creations. As a mod developer, this pattern is good to follow if NPC spawning logic takes wall types into account.
With ModTile.WallFrame
, a modder can implement whatever framing logic they desire. This example from ExampleWallAdvanced shows weighting the 1st option more than the other 2 options:
public override bool WallFrame(int i, int j, bool randomizeFrame, ref int style, ref int frameNumber) {
if (randomizeFrame) {
// Here we make the chance of WallFrameNumber 0 very rare, just for visual variety: https://i.imgur.com/9Irak3p.png
if (frameNumber == 0 && WorldGen.genRand.NextBool(3, 4)) {
frameNumber = WorldGen.genRand.Next(1, 3);
}
}
return base.WallFrame(i, j, randomizeFrame, ref style, ref frameNumber);
}
Here is the comparison between this example and WallID.Cog, which has a similar texture, note how rare the WallFrameNumber 0 is:
Make sure not to use wall framing for game logic, only visuals. Wall framing is not synced and each player sees their own pattern of wall framing.
- Vanilla WallIDs
- ModWall Documentation
-
ModBlockType Documentation - Contains other methods and properties that both
ModTile
andModWall
inherit.