User:Toketsupuurin/AutoTileTutorial

From wiki
< User:Toketsupuurin
Revision as of 23:08, 7 January 2020 by Toketsupuurin (Talk | contribs) (Project 1: Wall Mushrooms That Auto-Sense Surfaces)

Jump to: navigation, search

AutoTile Tutorial by Toketsupuurin

AutoTile is a fairly powerful system that allows a tile to change appearance based on the local context. What blocks surround a tile can affect how it looks and rotates.

That said, getting the most out of autoTile will require wrapping your brain around the way autoTile sees the world.

The simplest implementations of autoTile should be pretty painless for even a new modder. This sequence of tutorials will cover tiers of difficulty, new concepts in bite-sized chunks, and will introduce practical ways to utilize autoTile for different effects. Later sections of the tutorial will make use of the Tutorial Mod. In theory it's an optional, but it contains all of the exercises referenced in the tutorial for you to examine in detail and the .QB files could be useful to troubleshoot your own autoTile logic. When the front and back of a fence look identical, it's really hard to diagnose what's going on. It's not a code mod and won't hurt your game at all, even if you uninstall it.

TLDR: Make my Poster Stick to a Wall!

Checking your orientation in Qubicle.

The first thing to know about autoTile: Don't reinvent the wheel.

The game has a number of pre-written autoTile instructions that probably do 90% of the things you want. If there's an object in the game that behaves the way you want your item to behave: Great! Go pull those instructions out of the game file, and change the Codes to the ones for your object. Make sure that your object is rotated in the same direction in the .QB as the orientation of the object in the original .QB and you're golden.

Prewritten AutoTile Instructions

You'll find autoTile instructions in one of two places, generally, a *.config file or a *.tile file. This is a list of all the files in the vanilla game that have autoTile instructions:

staxel/tileObject/vines.config, walllight.config, wallObject.config 
Makes the object stick to a wall. At a brief glance they all look the same. 
staxel/tileObject/airship/RopeFenceStraight.tile 
A fence with a straight, corner, T section and cross. 
staxel/tileObject/museum/paintings/paintingBase.config 
Makes the object stick to a wall.  (At a brief glance looks the same as vines.config.)
staxel\tileObject\mushroomIsland\mazeWalls 
basically a fence with a straight, corner, T section and cross.  (See the Rope Fence to compare, I'm not sure if they're identical.)
staxel/tileObject/quest/Morel/ToughMushrooms.tile and SmallMushroom.tile 
These are something special. They will destroy certain kinds of blocks they are placed on. These are the only objects that do this. BE EXTREMELY CAUTIOUS when using this because it will indiscriminately destroy blocks and they don't go through a proper spawn on break. The tile just gets deleted and replaced. I'll cover this stuff in an advanced section.
staxel/tileObject/roofing/black/Black_Straight.tile 
All the roofs use this logic, I'm only listing one color here. It's generalized to look for categories instead of specific blocks and is only specific when it comes to the block you place.
staxel/tileObject/serverVillage/FenceStraight.tile 
A three piece single sided fence with inner and outer corner tiles. 
staxel/tileObject/serverVillage/exterior/WoodenDeckingRailing.tile, HedgeStraight.tile, RoughWoodenFenceStraight.tile, and BlackFenceStraight.tile 
a two piece fence with a corner piece. (The hedge fence also has a Single tile which is not part of the autoTile logic and is a separate block.)
staxel/tileObject/serverVillage/exterior/WoodenPoleFenceStraight.tile 
a five piece fence, the most complicated one in vanilla staxel. Has a "middle" piece with no post. 
staxel/tileObject/serverVillage/exterior/SmallHedgeEnd.tile 
A three piece fence with a straight, corner and end piece.
staxel/tileObject/serverVillage/exterior/SmallWoodenPoleFenceMiddle.tile 
a four piece fence like the rope fence.

There are other autoTiles out there in modding land. My Furniture mod makes extensive use of autoTile in the fences (6 pieces with 2+ variations for each and improved logic) and in additional decorative roof pieces like the ridge tiles. Any custom autoTile I've written for a mod can be used without asking. (But poke me on the Discord if you use it; I'd love to see what you did with it!)

Definitions

The Object Block Tile model.

There are three terms I'll use in this guide. They're all related but different concepts. I'll try to specifically use the correct term, but under certain situations some of them are synonymous with the others.

Tile 
A tile is an instance of a thing that has been placed in the world of Staxel and is permanently attached to the grid of the world until you or an NPC changes that. A tile is also any item in the game that has a .TILE file, usually it also has a unique .QB file to go along with it.
Block 
I may refer to an item placed into the world grid as a block. In this use it is synonymous with the first definition of "Tile". More importantly, a block is any item that takes up a single space in your inventory. Most blocks have one .TILE file associated with them. AutoTile allows for a sort of substitution where one .TILE can be represented in the game by a different .TILE you then use autoTile logic to access each different tile. The vanilla game uses as many as 6 .TILE files in 1 block. You can use more.
Object 
Everything that uses autoTile is a tileObject. Materials (like dirt or grass) do something that can be compared to autoTile, but is handled in a completely different manner. Materials are not covered in this tutorial at all. When I refer to "the object" I'm usually speaking about the thing you're working with in an abstract sense. A vanilla roof object has 3 blocks, 1 of which is made up of 6 tiles. The hedge fence referenced above is one conceptual object, with two blocks, one of which has two tiles.
Code/Instructions/Script/Logic 
Pedants will complain that autoTile isn't programming, so it's not really "code" nor is it really a "script". Fair enough. Colloquially, it counts, but I'll generally try to avoid the term "code" as Staxel uses that term for something else. I prefer the terms "instructions" or "logic," and I'll endeavor to avoid the others, but I may not always succeed. 
autoTile 
I call it autoTile instead of Auto-Tile, Auto-Tiling or anything else because when you're writing the instructions you'll write it as "autoTileInfo" and I'm trying to reinforce that in your head. Computers are picky about capitalization and spelling when it comes to Jsons or any kind of coding or scripting, really. The reason for the weird capitalization pattern is entirely due to a programming convention.

The autoTile Rotation Model

I'm sure you'd love to skip all my nattering and get onto the practical stuff. Unfortunately, to go much of anywhere with autoTile you will have to grok how autoTile functions, the model it views the world by, and its inherent limitations. So, Let's talk about rotation and points of view. There are three possible types of rotation we're dealing with when we think about rotation in Staxel:

  1. The rotation of an already placed tile, like a bed. This is Cardinal rotation and can be thought of as equivalent to North, South, East, and West. This rotation never changes in regards to the orientation relative to the world. Once you place a block, you can consider it under cardinal rotation.
  2. The rotation of the player. This has no bearing on autoTile results at all. Where you are standing and the direction you are facing in relation to the block you are placing has no impact on the autoTile code at all. What it does do is make it harder for you to keep track of rotation directions because it adds added complexity that can be distracting, depending on how your brain deals with spatial reasoning. For the purposes of autoTile, you can think this as Nautical rotaton, likening the player avatar to a boat and use terms like port, starboard, fore and aft. We won't use this much.
  3. The rotation of the tile you are holding in your hand. This is the model that autoTile operates under. This is a relative direction scheme using right and left, front and back. This is Ego-centric or Relative rotation.

The key thing to remember is that autoTile is block-centric (Relative), NOT player-centric (Nautical). The block you are placing doesn't care where you are standing or what you can see. It doesn't care about north south east or west. All it cares about is where something is relative to it. When you write up autoTile instructions what you're really saying to the block is "look in front of you," or "look left."

This leads into some pretty serious limitations and benefits of the system.

The major benefit to operating this way is that you only have to write one quarter of the logic you'd have to write in a cardinal setup. "Look north and if that has a fence piece, place a straight tile. Look east and see..." versus "look in front of you and if there's a fence there place a straight tile. 

The major downside is that any given block will only ever have 4 possible placement options for a designated location. You can't say "do one thing if it faces north, and another thing if it's east," because it doesn't understand what east or north are.

Optional Exercise: Getting Comfortable With Rotation

You can search for "tutorial" to bring up any of the blocks in the mod.

You don't have to do this, but if you're having any issues really internalizing how rotation behavior works in Staxel, I encourage you to download the autoTile mod and follow the exercises below. If you're comfortable with it, go ahead and skip to the next section, but I really suggest you at least give it a skim.

Take the tutorial block. Notice that it has a series of letters and numbers on it. These are cheats to tell you what side of the block you're looking at. The upper left corner marks the direction of the side. (Front, back, left, right, up down)  the upper right corner shows the rotation number (0-3), the bottom half shows the face's axis name (xp, xn, yp, yn, zp, zn.)  These are also color coded. Every object in the mod is, so you can always tell exactly what face you're looking at. You can use this to troubleshoot autoTile instructions, or any other modding you might be doing.

Now, put down four tutorial blocks, one in each cardinal direction, leave out the middle, and make the hole big enough that you can stand in it. (Like a 5x5 plus shape, but missing everything but the tips. DO NOT rotate the blocks. They should all face the same direction.

A cross of tutorial blocks all oriented the same way.

For this exercise, you're going to pretend that you ARE a block being placed. Go stand in the center of the four blocks. Look at the block in front of you. Take a note of the face you can see.

Your initial position.

Now turn 90 degrees and note what face you see this time. Do this a few more times to get a feel for what's going on. Try turning the other direction too.

What you should see after your first 90 degree turn.

Now, remember, each of those cubes was placed to have the same orientation. They are, effectively, all facing north.

And yet, when you spin in place, it looks like they've all been rotated. The only thing that matters to autoTile is how the surrounding blocks APPEAR to be rotated RELATIVE to the block to be placed.

This holds true no matter what direction an autoTile is told to check. (Checking the block in front of you for this example is just easy to see because it's right in your field of view.) To prove this to yourself, go stand on top of one of the tutorial blocks, face a cardinal direction (whatever you think north should be.) Take a note of the color that would be between your toes. 

Standing on a block should look something like this.

Now, turn 90 degrees and look at the color between your toes. It changes relative to you, no matter where you stand.

And this is what you see after a 90 degree turn.

This may seem simplistic, but it's really important to internalize this principle. Make sure you remember you've been pretending to be the block. Pull out the tutorial block and place it in the spot I had you stand originally. Break it out, rotate the one in your hand and place it again. Do this a few times, and pay attention to what the placed block "sees" in relation to thinking that the "F" face is the block's eyes.

How you perceive the block seeing the world.

Now change your position so you're looking at the cross from a different angle and place the block without rotating it from the last time. Move around, placing the block from several different angles without rotating it to prove to yourself that where you stand makes no difference to the rotation of the block you place. 

This is the same layout as the last image. The block's perspective hasn't changed; yours has.

Once you really have a handle on this, you've gotten past a good chunk of the hard parts of autoTile.

Project 1: Wall Mushrooms That Auto-Sense Surfaces

I'm going to assume that you went through the basic modding tutorial so you know what blobs are, and you know how tile files work and all that jazz. I'm also going to assume you're using Qubicle whenever I refer to looking at a .qb file. (If you aren't, that's fine, just bear in mind that you might have to mirror over a certain axis in other voxel editors so if you're trying to figure out right and left you'll have to take that into account. Check the basic modding tutorial for more information on that.) One more thing: use a text editor, not the asset manager. You can't rely on it for this and you really shouldn't rely on it for anything other than as a reference for options you can use. It doesn't save all your decisions properly.

If you've played Staxel you've probably encountered these little fellas:

Glowing Mushrooms!

You can buy these from the catalog or from an airship merchant. We're going to take a look at the pre-written autoTileInfo that the wall mushroom uses and then expand on that to add in the ceiling and floor mushrooms in one object.

Rule #1: Make yourself a working folder somewhere other than the staxel install directory. The staxel install directory can get overwritten by the game and you can lose all your work. It's safest to keep your work elsewhere and make copies of the files to drop into the install folder. Just remember that any file paths we put in our text files need to assume they're living in the install folder and not the working folder.

Your install directory will be somewhere like this:

C:\Program Files (x86)\Steam\steamapps\common\Staxel\content\mods\YOURMODFOLDER\

Your working directory can be anywhere you like, but it should look something more like this:

C:\StaxelMods\YOURMODFOLDER\

It can be in your documents folder or anywhere else, really, but it had better stay far, far away from your install folders of all sorts. If Staxel or the content builder knows how to get to it, you shouldn't be putting your working files there.

Staxel's vanilla data files can be found at:

C:\Program Files (x86)\Steam\steamapps\common\Staxel\content\

with the majority of the art and asset files in:

C:\Program Files (x86)\Steam\steamapps\common\Staxel\content\staxel\

If I tell you to go looking for a file in the vanilla game it will be in that ..\content\ folder and 99.9% of the time will be in ..\content\staxel\, alright? Get used to digging around in those folders if you're going to mod Staxel. You'll spend a lot of time there.

Go to your content folder and copy each of these files to your working directory:

..\staxel\tileObject\fairyVillage\GlowingMushroom1.tile
..\staxel\tileObject\mines\CeilingMushroomBlue1.tile
..\staxel\tileObject\mines\MushroomGreen1.tile
..\staxel\tileObject\walllight.config

Go ahead and rename the four files as follows:

GlowingMushroom1.tile        StickyMushroom1Floor.tile
CeilingMushroomBlue1.tile    StickyMushroom1Ceiling.tile
MushroomGreen1.tile          StickyMushroom1Wall.tile
walllight.config             StickyMushroom1.config

Now open all three tiles up and change their codes right away so you don't forget. Best practice will be something like:

mods.YOURMODFOLDER.StickyMushroom1.Floor
mods.YOURMODFOLDER.StickyMushroom1.Ceiling
mods.YOURMODFOLDER.StickyMushroom1.Wall

Close the Floor and Ceiling files. We won't need them for a bit.

Pull up the wall file and go look at the inherits line:

"__inherits": "staxel/tileObject/walllight.config",

change this to:

"__inherits": "mods/YOURMODFOLDER/StickyMushroom1.config",

and save your work and close any open tile files.

Open up StickyMushroom1.config. Now, take a look for the blob that starts with "autoTileInfo". autoTileInfo will look like this:

 "autoTileInfo": [
   {
     "directionsToLookIn": [
       {
         "direction": "left",
         "tileCategoriesToLookFor": [
           "block"
         ]
       }
     ],
     "results": [
       {
         "rotation": 1
       }
     ]
   },
   {
     "directionsToLookIn": [
       {
         "direction": "back",
         "tileCategoriesToLookFor": [
           "block"
         ]
       }
     ],
     "results": [
       {
         "rotation": 2
       }
     ]
   },
   {
     "directionsToLookIn": [
       {
         "direction": "right",
         "tileCategoriesToLookFor": [
           "block"
         ]
       }
     ],
     "results": [
       {
         "rotation": 3
       }
     ]
   }
 ],

autoTileInfo is a list [] of blobs {}. Each blob in an autoTile list has a specific structure:

   {
     "directionsToLookIn": [],
     "results": []
   },

Note that "directionsToLookIn" and "results" are both lists. We will make use of this fact in a future project. For now, just remember that each of these lists needs at least one blob giving it something to do.

"directionsToLookIn" is a test condition and "results" contains a thing to do if the test is true. Let's look at the contents of the first instance of "directionsToLookIn":

       {
         "direction": "left",
         "tileCategoriesToLookFor": [
           "block"
         ]
       }

These are the bare minimum number of things Staxel needs to do an autoTile check.

  1. "direction" tells Staxel what block to look at relative to the block being placed. That's the block it's going to run its tests on. You must have this; Staxel has to know what tile to test.
  2. "tileCategoriesategoriesToLookFor" (or "tilesToLookFor") you must have one or both of these. AutoTile must have a thing to look for. You can't simply say "anything will do except these things." 

Anything else you might see in a "directionsToLookIn" is optional, and we aren't worried about them at the moment because we just want to stick our mushroom to the wall.

Staxel understands six directions: up, down, left, right, front, and back. It also understands 4 rotations. 0, 1, 2, and 3. Rotation 0 is the direction your mushroom faces in the .qb file.  When you hold a ghost object in Staxel before placing it and you rotate it, Staxel will run through the entire autoTile blob in order. It does this every single time you rotate the object, checking each time to see which result it should use. It will use the last valid "directionsToLookIn" it finds. So if you have your mushroom in a corner and it could stick to either the back or to the right and your logic says "check the back first, then check the right" the game will offer you the chance to place the block on the right wall, not the back wall.

So, we have four directions we will have to check, because the lamp can stick to any of the four walls.  We want our lamp to stick to any wall, even walls we don't know about right now. We could dig through the files and name every single tile that acts as a wall, but that doesn't take other mods into account, and if a player has one mod then they have 100.  It's best to use a category in this case, specifically the "block" category as those are usually walls. Let's write up our directionsToLookIn now. So now that you have tests you need something to happen if a test is true. "results" is how we do that. At a bare minimum you need to give "results" a "tileToPlace". That's the whole point. So put in the code of your wall lamp.  If we stop here and run the mod our wall lamp ghost will spin like a dervish in a dryer. If you don't tell "results" a "rotation" it will pick one at random.  So, one rotation for each direction we tested! That makes sense. What we're basically doing is saying "is there a wall there? Great! Which direction is it? Ok. I need to rotate the lamp this way to stick it to the wall." And now we reach the first sticking point. Staxel isn't smart enough to look at your .qb file and understand which face is supposed to stick to the wall. You have to figure it out yourself and then tell staxel. The easy fix: open up the walllamp.qb that's associated with the tile file you've been looking at and take a note of the direction it's facing. Open the QB of the wall lamp you're modding in and make sure it's facing the same direction as the original staxel lamp. That's the easy way, but you're here to actually learn how to write your own logic. So I'm going to walk you through the thought process and reasoning here so you understand the how AND why of it. Now, wait a minute, there are only three tests in the original file!? What gives?  When staxel runs through the entire autoTile and doesn't find any valid results then it defaults to the "voxels" defined in the .tile file and rotation 0. You don't have to define every test case, just the ones you don't want to be the default tile.  At this point you have a working auto tile blob. Honestly, you could just copy and paste the original autoTile blob and change the codes.  There's no need to reinvent the wheel. Find an object in staxel with the behavior you want and copy its autoTile. You could use that walllamp.config to make a poster or a wreath.  You only need to go deeper into autoTile if you need to make new behaviors. So let's get into that. After this point I'm going to assume you've at least looked at the tutorial on the auto-tile page of the modding wiki and you're looking for some more expansive explanations.