Reference: Positioning Placeable Items

This is a reference on how the different coordinate systems affect various origin positions and regions for placeable items in the game. I’m going to assume the modelling tool being used to create models is Qubicle: Stonehearth Edition. It is the only modelling program for Stonehearth that I’m familiar with.

All of my examples use a scale of 0.1 for scaling between the Qubicle model and the world as this is the default for the game and very easy to work with. If you choose to use a different scale, some values will change (mostly in the region_collision_shape).

World coordinates
The game world has its own set of coordinates based on a right-handed system. Assuming “north” is into the screen and up is above the ground, then when you first start a new game +Y is up, +Z is south and +X is east.

In all the pictures to follow, the color of the axis tells you which it is. I’ve labelled some for convenience, but X is always red, Y is always green and Z is always blue by convention.

In general, models have an origin at the centre of the face to which they are attached. For furniture, they are generally attached to the ground, so the origin is at the centre of the bottom. Some decorations are attached to walls, so their origin is the centre of the tile that attaches to the wall. Other items like weapons and armor have special rules for their origins and so aren’t discussed here.

If you have debug keys enabled, you can press F11 to see the axis of an given object. Here’s a barrel icon and you can see the origin comes from the middle of the bottom.

A Note on object coordinates
The coordinate system of objects in Qubicle is not the same as the world coordinate system in Stonehearth. Qubicle uses a left-hand coordinate system and Stonehearth uses a right-handed coordinate system. This has an impact on the offsets you use later.

The exact difference is the direction of the Z-Axis. In Qubicle, the positive Z-Axis points towards the back of an object (or the “north”). In Stonehearth, the positive Z-Axis points to the front of an object (or the “south”).

Here is the barrel in Qubicle. Note that the Z axis faces away from the front of the barrel.

Object Orientation
Objects can be reoriented to face in one of 4 directions in Stonehearth. One of the easiest ways to see a mistake in your numbers is to try rotating the orientation of the object in the world. If your model_origin is incorrect, the object will not spin around its own centre. If your region_origin is incorrect, the collision region will not match the position of the model as it rotates.

If you have debug keys enabled, you can use F11 to reveal the collision region, axis and destination regions for the object.

Origins and which file to put them in
The origin information for your object should go in the ghost.json file when it is available. The regular json file mixes information in from the ghost.json file, so you won’t need to repeat it. If your object can’t be placed in the world by the player (like weapons and armor), then it won’t have a ghost.json file and only then do you put your origin information in the regular json file. Failure to do so leads to situations where the ghost object and regular object do not have the same origins and the position of the object jumps when an item is placed.

model_origin
This offset is defined in terms of the world axis coordinate system. It works based on the origin of the model itself (which is defined in Qubicle).

This is an offset for the model so that it aligns well with the world. Some models have X and Z dimensions that are not exactly divisible by 2. When this happens, you set that dimension to 0.05 so that it corrects the alignment in the world. The value should always be 0 or + or - 0.05. If the model needs to be positioned by larger amounts, then you can and should do that in Qubicle itself.

For instance, if you create an object in Qubicle that is 9x9 blocks in the X and Z directions, you’ll need to set model_origin to something like

"model_origin" : { "x": -0.05, "y": 0, "z": 0.05 }

Whether you use -0.05 for X or Z depends on how you orient the object itself around the origin in Qubicle. With this example, the central block is placed in the positive direction of both X and Z. X set to -0.05 because that is the difference between the origin point (0,0,0) and the actual centre of the object (0.05, 0, 0.05) in Qubicle.

But why is Z +0.05 when X is -0.05? As discussed before, the coordinate system of Qubicle is different to the coordinate system of Stonehearth. The exact difference is the direction of the Z-Axis. In Qubicle, the positive Z-Axis points towards the back of an object (or the “north”). In Stonehearth, the positive Z-Axis points to the front of an object (or the “south”). So you actually want to use the opposite adjustment in the Z-Axis compared to the model position in Qubicle.

region_origin
This offset is defined in terms of its own coordinate system. X and Y are the same as the world coordinate system, but +Z is north instead of south. It works based on the model_origin.

This is an offset for the origin of the region_collision_shape so that it aligns well with the world. The region_collision_shape aligns with the edges of tiles in the world. The origin of a model aligns with the centre of a tile. So usually you’ll want to set your region_origin to something like

"region_origin" : { "x": 0.5, "y": 0, "z": 0.5 }

This puts the origin of the region_collision_shape at the corner of the tile to the north-east of the model origin. You could use another value, but consistency helps. If your region_origin does not align with a block corner, there is a good chance your region_collision_shape will not align correctly in the world when the object is rotated for placement.

region_collision_shape
This offset is defined in terms of its own coordinate system. +Y and +Z are the same as the world coordinate system, but +X is west. It is defined this way so that most values are positive (objects larger than 2 tiles in the X or Z direction may not have all values positive).

This is the collision area of an object that can be placed in the world. It is used to make entire blocks of the world unavailable for movement by hearthlings and placement of new items. The following is an example taken from the stone_chair object:

"region_collision_shape" : {
   "region": [
     {
       "min" : { "x" : 0, "y" : 0, "z" : 0 },
       "max" : { "x" : 1, "y" : 2, "z" : 1 }
    }
  ]
}

In this example we can see that the object is 1 tile wide in the X and Z directions and 2 tiles high in the Y direction, starting from the region_origin which we previously defined. Z direction is to the south and X direction is to the west as previously defined.

Larger objects
When creating objects that are larger than a single tile on the ground, we come into an additional issue. Where is a good place to put the origin, especially if the centre of the object would not naturally coincide with the centre of a tile?

For example, if we have an object that is 2 blocks wide and long, then the true centre of the object is where 4 blocks join and not at the centre of one. My suggestion is to go for a slightly more southerly tile and a slightly more easterly tile for the model origin. In this example, we’ll pick the south-east tile.

In this case, model_origin and region_origin will be

"model_origin" : { "x": 0.5, "y": 0, "z": 0.5 },
"region_origin" : { "x": 0.5, "y": 0, "z": 0.5 }

If you’ve been following to this point, you’ll note that the model_origin has moved to the south-easterly tile, but the region_origin, moves back to the centre of the object because the model_origin and region_origin X and Z axis are in opposite directions.

When the true centre of the object is the same as the corner of 4 blocks, then we should always set the region origin to that point. If the true centre is in the centre of a tile, then we should set the region_origin to the north-east corner of that tile.

If we assume that the object is 2 blocks high as well, then the collision region will be

"region_collision_shape" : {
   "region" : [
      {
         "min" : { "x" : -1, "y" : 0, "z" : -1 },
         "max" : { "x" : 1, "y" : 2, "z" : 1 }
      }
   ]
}

X and Z go from -1 to +1 because the region_origin is at the exact centre of the base of the object (and is therefore symmetrical around the origin). If the object was instead 3 in the X axis, then the region_origin should be biased towards the east and you’d have X from -1 to +2 instead.

Here’s a picture of one of my large barrels that is 2x2x2 in size and has an origin in the SE corner in the default orientation (along with the iconic barrel it comes from).

14 Likes

It’s really confusing sometimes that the positive and negative axis are different depending on the region type that you’re defining.

Thanks for putting up this tutorial, it’s really useful :smiley: :thumbsup:
I always found myself making little sketches on paint about where the +/- axis pointed to.

2 Likes

MS paint to the rescue!

Oh, also, I forgot to mention. You shouldn’t need the debug tools in order to use F11. You might have to enable the debug keys instead. :smile:

1 Like

indeed you are correct, you just need debug keys not debug tools.

Thanks again, Tuhalu. I just got my issues fixed with the item I was working on that prompted my questions about these coordinate systems.

1 Like

Ah right. Thanks for the correction.