MountPoints
Features
Mount points are areas on a block's boundingbox where other blocks can be placed.
Each side of a block can have any number of rectangles which cannot be rotated because they're created from 2 points.
The rectangles can safely overlap if it helps make a complex shape out of less rectangles.
When the game checks if a block can attach to another block, it checks the sides that connect if any mount point overlaps a mount point on the other block. It does not have any minimum surface area requirements to allow attaching, each mountpoint however does have optional rules for what kind of mountpoints it can attach to, defined by masks or coupling.
Airtightness
Mount points also define which faces are airtight (how airtightness works), but only if <IsAirTight> is not defined, otherwise if it's set to true or false, it will make all the block's sides airtight, therefore mountpoints would be ignored for airtightness.
A mount point has to fully cover a cell face in order to begin to affect it for airtightness, then the PressurizedWhenOpen and PressurizedWhenClosed attributes can configure.
Usage
They're declared using the <MountPoints> element in any block definition. A quick recap on the syntax and available attributes:
<MountPoints>
<MountPoint Side="Right" StartX="0.0" StartY="0.0" EndX="0.0" EndY="0.0" Default="false" Enabled="true" PressurizedWhenOpen="true" PressurizedWhenClosed="true" PropertiesMask="0" ExclusionMask="0" CouplingTag="" AllowCouplingWithItself="false" />
<!-- ... -->
</MountPoints>
Basics
Side(required) which side of the block is this on. Values:Front,Back,Left,Right,Bottom,Top.
StartXandStartY(required) the 2D coordinates where to start a rectangle from.EndXandEndY(required) the 2D coordinates where to end the rectangle.
Note: It's a lot easier to design these in Blender using SEUT, for details see its SEUT Mountpoints guide.
Coordinates start from 0.0 and end up to the amount of grid cells that side has. For example, a 1x1x3 block's front/back sides only go to 1.0, but the other sides go to 3.0.
You can see in-game where the coordinates start by pressing F11 in an offline world to open the Debug Menu and enable Debug Draw and Mount Points. Then equip a block and aim it at a grid. The BuildInfo mod will also show mountpoints and airtight faces for blocks.
Default(default false) if true, uses thisSideto auto-rotate the block when placing it.
Enabled(default true) if false, disallows mounting only. Useful to define airtight areas that blocks cannot be built on (glass window for example).
PressurizedWhenOpen and PressurizedWhenClosed
These affect the airtightness of the cell faces fully covered by this mountpoint. Any partial cover will not affect that cell face.
For door blocks that can be opened/closed:
PressurizedWhenOpen(default true) if true, covered cell faces are airtight regardless of door state.PressurizedWhenClosed(default true) ifPressurizedWhenOpenis false and this is true, covered cell faces are airtight when the door is fully closed.- If both are false, the door type decides which sides are airtight when closed, see the "Toggled Airtightness" sections: Door | AdvancedDoor | AirtightSlideDoor | AirtightHangarDoor
For non-door blocks, PressurizedWhenOpen being false will make the mountpoint no longer airtight and PressurizedWhenClosed's value doesn't matter.
The door definitions also have a new <PressurizeCube> element that impacts if they get filled with air.
PropertiesMask and ExclusionMask
PropertiesMaskmountpoint's flags.ExclusionMaskwhat flags to disallow mounting with.
Both default to 0 which means no properties and no exclusion.
The values for either mask tags can be one or all of these (by adding the numbers):
1= Extruding[1] (classic door's side bits go outside of its boundingbox and use this, same for interior lights)2= Thin/small[1] (catwalks, lights, etc)4,8,16,32,64,128= Not used by Keen (last checked: SE v207), therefore they can be whatever modders decide.
The way these work: when BlockA is checking overlap of mountpoints with BlockB, they're also checking BlockA's PropertiesMask vs BlockB's ExclusionMask and BlockA's ExclusionMask vs BlockB's PropertiesMask, if either of these checks match then it does not allow the block to mount.[1]
Also if BlockA and BlockB have the same <Id> then these masks are ignored.
Here's a practical example from game's usage of it:
- Interior light has its only mountpoint as
ExclusionMask="3"(1+2) which means it can't be placed on extruding nor thin mountpoints. - It also has
PropertiesMask="3"(1+2) which means itself is both thin and extruding. - Then classic door has
PropertiesMask="1"on the sides because they poke outside the block quite significantly. - This means you cannot place interior light on the sides of classic door because 1, because interior lights exclude 1+2 and classic door has 1.
- But classic door's side can mount to another classic door's side because they're the same block
<Id>which ignores these masks.
CouplingTag and AllowCouplingWithItself
CouplingTagmakes the mountpoint only mountable to other mountpoints that contain this text in theirCouplingTagor vice-versa.
If empty ("") or undeclared it will disable this feature.
Example, BlockA has CouplingTag="Water Ice Fire" and:
- BlockB has
CouplingTag="Fire"then they can mount, because B's tag is contained in A's tag. - BlockB has
CouplingTag="Fire Ice"then they cannot mount, because it does not process the string in any way. - BlockB has
CouplingTag=""(same as undeclared) then they also cannot mount.
AllowCouplingWithItselfallows mounting the same block<Id>to itself with this mount, false does not allow that.
Only works if the CouplingTag is defined and not empty.
Note: Conveyor and upgrade ports don't care about mountpoints. Having any regular mountpoint elsewhere and a coupling one on a conveyor port will not prevent that port from being connected to regular conveyors when the block is inevitably forced to be placed on the same grid next to it using the regular mountpoint.
Other
Disable all mountpoints
To disable all mountpoints (for suspension's wheels for example) you cannot do it like Keen does with an empty list (who knows why).
As a workaround, you can declare a single disabled mountpoint:
<MountPoints>
<MountPoint Side="Back" StartX="0" StartY="0" EndX="0" EndY="0" Enabled="false" />
</MountPoints>
Build-stage mountpoints
This feature is from Medieval Engineers where they prevent the top part of a block from being mountable until the block is more constructed or even fully built.
It seems to work in SE but as with all features not directly used by Keen in SE, they tend to be buggy(er) or could break in the future.
To use it, in the <BuildProgressModels> first you have to first open up the <Model ... /> element by changing /> to > and then add a regular closing tag:
<Model BuildPercentUpperBound="0.33" File="Models\Whatever.mwm" />
to
<Model BuildPercentUpperBound="0.33" File="Models\Whatever.mwm">
</Model>
Then inside that Model element you can add <MountPointOverrides> which has the same exact layout as <MountPoints>.
However it works quite differently:
- It starts off with a clone of the regular mountpoints.
- Declaring a
<Side>in<MountPointOverrides>will first remove all mountpoints for that side then it adds yours. - Any following build progress models that have
<MountPointOverrides>will inherit the previous one's changes.
Some changes to Refinery block as an example, with comments on the per-stage result:
<!-- non-modified regular mountpoints just for reference -->
<MountPoints>
<MountPoint Side="Back" StartX="0" StartY="0" EndX="2" EndY="4" />
<MountPoint Side="Bottom" StartX="0" StartY="1" EndX="2" EndY="2" Default="true" />
<MountPoint Side="Top" StartX="0" StartY="0" EndX="2" EndY="1" />
<MountPoint Side="Left" StartX="1" StartY="0" EndX="2" EndY="4" />
<MountPoint Side="Right" StartX="0" StartY="0" EndX="1" EndY="4" />
</MountPoints>
<BuildProgressModels>
<Model BuildPercentUpperBound="0.16" File="Models\Cubes\Large\RefineryConstruction_1.mwm">
<MountPointOverrides>
<MountPoint Side="Back" Enabled="false" />
<MountPoint Side="Top" Enabled="false" />
<MountPoint Side="Left" Enabled="false" />
<MountPoint Side="Right" Enabled="false" />
<!-- results in only bottom side remaining -->
</MountPointOverrides>
</Model>
<Model BuildPercentUpperBound="0.33" File="Models\Cubes\Large\RefineryConstruction_2.mwm">
<MountPointOverrides>
<!-- results in identical mountpoints as previous build stage -->
</MountPointOverrides>
</Model>
<Model BuildPercentUpperBound="0.50" File="Models\Cubes\Large\RefineryConstruction_3.mwm">
<MountPointOverrides>
<MountPoint Side="Back" StartX="0" StartY="0" EndX="2" EndY="4" />
<!-- results in bottom + back side -->
</MountPointOverrides>
</Model>
<Model BuildPercentUpperBound="0.83" File="Models\Cubes\Large\RefineryConstruction_4.mwm">
<MountPointOverrides>
<!-- results in identical mountpoints as previous build stage -->
</MountPointOverrides>
</Model>
<!-- this one has no override so it just uses the regular full mountpoints -->
<Model BuildPercentUpperBound="1.00" File="Models\Cubes\Large\RefineryConstruction_5.mwm" />
</BuildProgressModels>
The above mountpoints visualized using the BuildInfo mod to show construction stages and mountpoint overlays shown in yellow:
- ↑ 1.0 1.1 1.2 KSH github
