Buildings
2.1 : The building group
The building group will hold variants of your building, such as the flipped version. A basic building group needs the title, description and icon. Here is a basic example from my nand gate mod :
IBuildingGroupBuilder bldingGroup = BuildingGroup.Create(new("nandgroup"))
.WithTitle("building-variant.nand-gate.title".T())
.WithDescription("building-variant.nand-gate.description".T())
.WithIcon(FileTextureLoader.LoadTextureAsSprite(res.SubPath("icon.png"), out _))// res is the mod resource locator. If you used my project generator, it should already be there
.AsNonTransportableBuilding()// if the building transports items/fluids, use AsTransportableBuilding()
.WithPreferredPlacement(DefaultPreferredPlacementMode.Single)
.AutoConnected();
2.2 : The building connector data
The connector data is the layout of the connectors on your building. Multi-tile buildings are not currently supported. Basic wire example :
IBuildingConnectorData connectorData = BuildingConnectors.SingleTile()
.AddWireInput(WireConnectorConfig.CustomInput(TileDirection.North))// top
.AddWireInput(WireConnectorConfig.CustomInput(TileDirection.South))// bottom
.AddWireOutput(WireConnectorConfig.CustomOutput(TileDirection.East))// right
.Build();
Using fluids or shapes is similar. Simply use Add(Fluid/Shape)(Input/Output) along with (Shape/Fluid)ConnectorConfig
2.3 : The simulation
The simulation is what processes the inputs and outputs of the building. It needs to extend the Game.Core.Simulation.Simulation class. There are already pre-made simulation classes that are easier to use. The following examples are all in the Game.Content dll. I omitted some simulations, because they were not relevant. You can see the full list by decompiling the Game.Content dll.
- BeltFilterSimulation
- BeltReaderSimulation
- ButtonSimulation
- ConstantSignalSimulation
- ConveyorSimulation
- DisplaySimulation
- FullCutterSimulation
- HalfCutterSimulation
- HalvesSwapperSimulation
- ItemProducerSimulation
- LabelSimulation
- LogicGate2In1OutSimulation // What i use for my nand gate
- LogicGateIfSimulation
- LogicGateNotSimulation
- MergerSimulation
- MixerSimulation
- PainterSimulation
- PipeGateSimulation
- StackerSimulation
- VirtualHalfCutterSimulation
Example NAND gate with LogicGate2In1OutSimulation
public class NAndGateSimulation(LogicGate2In1OutSimulationState state) : LogicGate2In1OutSimulation(state)
{
protected override ISignal ComputeOutputSignal(ISignal a, ISignal b)
{
return IntegerSignal.Get(!(a.IsTruthy() && b.IsTruthy()));
}
}
Example bottom painter with PainterSimulation
public class BottomPainterSimulation(PainterSimulationState state) : PainterSimulation(state)
{
protected override IBeltItem PaintItem(ShapeDefinition shape, IShapeColor color)
{
for (var i = 0; i < shape.Layers[0].Parts.Length; i++)
{
shape.Layers[0].Parts[i].Color = color;
}
return new ShapeItem(shape);
}
}
2.4 : Draw data
Draw data is the look of your building (what will be drawn to the screen).
First, make a class that extends IBuildingCustomDrawData. In that class, make a method that returns a BuildingDrawData object. Basic example :
public static BuildingDrawData CreateDrawData()
{
string baseMeshPath = Main.Res.SubPath("nand.fbx");
Mesh baseMesh = FileMeshLoader.LoadSingleMeshFromFile(baseMeshPath);
LOD6Mesh lodMesh = MeshLod.Create().AddLod0Mesh(baseMesh).BuildLod6Mesh();
return new BuildingDrawData(
renderVoidBelow: false,
mainMeshPerLayer: [lodMesh, lodMesh, lodMesh],
isolatedBlueprintMesh: lodMesh,
combinedBlueprintMesh: lodMesh,
previewMesh: lodMesh.LODClose,
glassMesh: new LODEmptyMesh(),
colliders: BoundingBoxHelper.CreateBasicCollider(baseMesh),
customDrawData: new NAndGateDrawData(),
hasCustomOverviewMesh: false,
customOverviewMesh: null,
simulationRendererDrawsMainMesh: false);
}
For more advanced things, check out the rendering page.
2.5 : The simulation renderer
There is two types of simulation renderer. Stateless and stateful. Stateless ones are always the same, and stateful ones depend on the state of the simulation.
Stateless
public class NAndGateSimulationRenderer(IMapModel map)
: StatelessBuildingSimulationRenderer<NAndGateSimulation, IBuildingCustomDrawData>(map);
Stateful
TODO
2.6 : The actual building
This process is very similar to making the building group. Simply call Building.Create() and fill all the fields. Basic example :
IBuildingBuilder blding = Building.Create(new("nand"))
.WithConnectorData(connectorData)
.DynamicallyRendering<NAndGateSimulationRenderer, NAndGateSimulation, IBuildingCustomDrawData>(new NAndGateDrawData())
.WithStaticDrawData(NAndGateDrawData.CreateDrawData())
.WithoutPrediction()
.WithoutSound()
.WithoutSimulationConfiguration()
.WithoutEfficiencyData();
2.7 : Registering the building
To register the building, use the AtomicBuildingExtender :
AtomicBuildings.Extend()
.AllScenarios()
.WithBuilding(blding, bldingGroup)
.UnlockedAtMilestone(new ByIndexMilestoneSelector(2))
.WithDefaultPlacement()
.InToolbar(ToolbarElementLocator.Root().ChildAt(2).ChildAt(6).ChildAt(^1).InsertAfter())
.WithSimulation(new NAndGateFactoryBuilder())
.WithCustomModules(new NAndGateModuleDataProvider())
.Build();