Zum Hauptinhalt springen

1. Bulk Silo – XML Setup

Übersicht

Diese Seite erklärt wie du ein eigenes Gebäude mit dem extendedSilo System einrichtest. Das System besteht aus zwei Teilen: der modDesc.xml deines Content-Mods und der Placeable-XML des Gebäudes.

Wichtig

Der PlaceableType FS25_SiloExtension.extendedSilo ersetzt nicht den Vanilla-Silo. Er erweitert ihn. Du behältst alle Vanilla-Features (UnloadingStation, LoadingStation, Storage) und bekommst zusätzlich das Box-System.


1. Dependency in modDesc.xml

Damit dein Mod das Framework nutzen kann, muss FS25_SiloExtension als Abhängigkeit deklariert werden:

<modDesc>
<!-- ... -->
<modDependencies>
<modDependency modName="FS25_SiloExtension"/>
</modDependencies>
<!-- ... -->
</modDesc>

Das Spiel stellt dann sicher, dass das Framework vor deinem Mod initialisiert ist.

info

storeItems, l10n und deine i3d/XML-Dateien bleiben vollständig in deinem Content-Mod. Das Framework stellt nur die Lua-Logik bereit.


2. Placeable-Typ verwenden

In deiner Placeable-XML (z. B. MySilo.xml):

<placeable type="FS25_SiloExtension.extendedSilo"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="../../../../../shared/xml/schema/placeable.xsd">
Wichtig

Der Typ muss immer mit dem Mod-Präfix angegeben werden: FS25_SiloExtension.extendedSilo


3. Vanilla Silo Grundstruktur

Das System baut auf der Vanilla silo-Specialization auf. Du brauchst mindestens:

  • Storages – eine pro Box (werden von der Vanilla-Silo-Logik für Savegame-Persistenz genutzt)
  • UnloadingStation mit einem UnloadTrigger pro Box
  • LoadingStation für das Auslagern
<silo>
<!-- Ein Storage pro Box -->
<storages>
<storage node="storage1" fillTypes="WHEAT" capacity="200000" supportsMultipleFillTypes="false" isExtension="false"/>
<storage node="storage2" fillTypes="BARLEY" capacity="200000" supportsMultipleFillTypes="false" isExtension="false"/>
</storages>

<!-- Auslagern -->
<loadingStation node="loadingStation" fillTypeCategories="BULK">
<loadTrigger triggerNode="loadingTrigger" fillLitersPerSecond="2000" fillTypeCategories="BULK" autoStart="true"/>
</loadingStation>

<!-- Einlagern – ein Trigger pro Box, storageIndex entspricht dem Index in <boxes> -->
<unloadingStation>
<unloadTrigger fillTypes="WHEAT" exactFillRootNode="unloadTrigger1" storageIndex="1"/>
<unloadTrigger fillTypes="BARLEY" exactFillRootNode="unloadTrigger2" storageIndex="2"/>

<effectNodes>
<effectNode effectNode="pipeEffect1" materialType="pipe" effectClass="PipeEffect"/>
<effectNode effectNode="pipeEffect2" materialType="pipe" effectClass="PipeEffect"/>
</effectNodes>
</unloadingStation>

<!-- Box-System -->
<boxSystem>
<playerTrigger node="boxPlayerTrigger"/>
<boxes>
<box storageIndex="1" name="Box 1" effectNode="pipeEffect1"/>
<box storageIndex="2" name="Box 2" effectNode="pipeEffect2"/>
</boxes>
</boxSystem>
</silo>

Parameter <boxSystem>

ParameterTypBeschreibung
playerTrigger#nodeNodeTrigger-Node für Spieler/Fahrzeug-Erkennung (Einlagern-Dialog)

Parameter <box>

ParameterTypBeschreibung
storageIndexIntIndex des zugehörigen Vanilla-Storage (1-basiert)
nameStringAnzeigename im Box-Dialog
effectNodeNodei3d-Node des PipeEffects für diese Box (→ PipeEffects)
Reihenfolge

Der storageIndex in <box> und in <unloadTrigger> muss übereinstimmen! Box 1 → storageIndex="1", der erste <unloadTrigger> ebenfalls mit storageIndex="1".


4. i3dMappings

Alle Nodes müssen in den <i3dMappings> eingetragen sein:

<i3dMappings>
<!-- Storages (Vanilla-Silo) -->
<i3dMapping id="storage1" node="0>5|0|0"/>
<i3dMapping id="storage2" node="0>5|1|0"/>

<!-- Unload Trigger (Einlagern) -->
<i3dMapping id="unloadTrigger1" node="0>3|0"/>
<i3dMapping id="unloadTrigger2" node="0>3|1"/>

<!-- Loading Station (Auslagern) -->
<i3dMapping id="loadingStation" node="0>4"/>
<i3dMapping id="loadingTrigger" node="0>4|0"/>

<!-- Box Player Trigger -->
<i3dMapping id="boxPlayerTrigger" node="0>6"/>

<!-- PipeEffects -->
<i3dMapping id="pipeEffect1" node="0>5|0|1"/>
<i3dMapping id="pipeEffect2" node="0>5|1|1"/>

<!-- FillPlane (optional) -->
<i3dMapping id="fillPlane1" node="0>7|0"/>

<!-- Info Trigger -->
<i3dMapping id="infoTrigger" node="0>8"/>
</i3dMappings>
warnung

Die Node-Pfade (0>5|0|0 etc.) sind Beispiele – du musst sie an deine i3d-Struktur anpassen!


5. Vollständiges Beispiel

<?xml version="1.0" encoding="utf-8" standalone="no"?>
<placeable type="FS25_SiloExtension.extendedSilo"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="../../../../../shared/xml/schema/placeable.xsd">

<storeData>
<name>$l10n_Silo</name>
<functions>
<function>$l10n_function_Silo</function>
</functions>
<image>store/storeSilo.png</image>
<price>50000</price>
<lifetime>1000</lifetime>
<species>placeable</species>
<category>productionPoints</category>
<canBeSold>true</canBeSold>
<showInStore>true</showInStore>
</storeData>

<base>
<filename>MySilo.i3d</filename>
<canBeRenamed>true</canBeRenamed>
<canBeDeleted>true</canbeDeleted>
</base>

<infoTrigger triggerNode="infoTrigger"/>

<silo>
<storages>
<storage node="storage1" fillTypes="WHEAT" capacity="200000" supportsMultipleFillTypes="false" isExtension="false"/>
<storage node="storage2" fillTypes="BARLEY" capacity="200000" supportsMultipleFillTypes="false" isExtension="false"/>
<storage node="storage3" fillTypes="CANOLA" capacity="200000" supportsMultipleFillTypes="false" isExtension="false"/>
</storages>

<loadingStation node="loadingStation" fillTypeCategories="BULK">
<loadTrigger triggerNode="loadingTrigger" fillLitersPerSecond="2000" fillTypeCategories="BULK" autoStart="true"/>
</loadingStation>

<unloadingStation>
<unloadTrigger fillTypes="WHEAT" exactFillRootNode="unloadTrigger1" storageIndex="1"/>
<unloadTrigger fillTypes="BARLEY" exactFillRootNode="unloadTrigger2" storageIndex="2"/>
<unloadTrigger fillTypes="CANOLA" exactFillRootNode="unloadTrigger3" storageIndex="3"/>
<effectNodes>
<effectNode effectNode="pipeEffect1" materialType="pipe" effectClass="PipeEffect"/>
<effectNode effectNode="pipeEffect2" materialType="pipe" effectClass="PipeEffect"/>
<effectNode effectNode="pipeEffect3" materialType="pipe" effectClass="PipeEffect"/>
</effectNodes>
</unloadingStation>

<boxSystem>
<playerTrigger node="boxPlayerTrigger"/>
<boxes>
<box storageIndex="1" name="Box Weizen" effectNode="pipeEffect1">
<fillPlane node="fillPlane1" minY="0.0" maxY="3.5" changeVisibility="true"/>
</box>
<box storageIndex="2" name="Box Gerste" effectNode="pipeEffect2">
<fillPlane node="fillPlane2" minY="0.0" maxY="3.5" changeVisibility="true"/>
</box>
<box storageIndex="3" name="Box Raps" effectNode="pipeEffect3"/>
</boxes>
</boxSystem>
</silo>

<i3dMappings>
<i3dMapping id="storage1" node="0>5|0|2"/>
<i3dMapping id="storage2" node="0>5|1|2"/>
<i3dMapping id="storage3" node="0>5|2|2"/>

<i3dMapping id="unloadTrigger1" node="0>3|0"/>
<i3dMapping id="unloadTrigger2" node="0>3|1"/>
<i3dMapping id="unloadTrigger3" node="0>3|2"/>

<i3dMapping id="loadingStation" node="0>4"/>
<i3dMapping id="loadingTrigger" node="0>4|0"/>

<i3dMapping id="boxPlayerTrigger" node="0>6"/>

<i3dMapping id="pipeEffect1" node="0>5|0|1"/>
<i3dMapping id="pipeEffect2" node="0>5|1|1"/>
<i3dMapping id="pipeEffect3" node="0>5|2|1"/>

<i3dMapping id="fillPlane1" node="0>7|0"/>
<i3dMapping id="fillPlane2" node="0>7|1"/>

<i3dMapping id="infoTrigger" node="0>8"/>
</i3dMappings>

</placeable>

6. i3d Anforderungen

boxPlayerTrigger

Der boxPlayerTrigger-Node muss im Giants Editor als Trigger konfiguriert sein:

  • Collision Group: TRIGGER (Bit 29)
  • Collision Mask: PLAYER (Bit 20)
info

Die Kollisionsmaske für VEHICLE und FILLABLE wird automatisch zur Laufzeit vom Framework ergänzt – du musst nur PLAYER im Giants Editor setzen.

unloadTrigger Nodes

Die exactFillRootNode-Nodes der UnloadTrigger müssen:

  • Collision Group: FILLABLE (Bit 30) gesetzt haben

Vanilla-Anforderung – ohne dieses Flag gibt Giants eine Warnung aus und der Trigger wird nicht geladen.


Häufige Fehler

❌ "Unknown type 'extendedSilo'"

Ursache: Der PlaceableType wurde ohne Mod-Präfix angegeben.

Lösung:

<!-- FALSCH -->
<placeable type="extendedSilo">

<!-- RICHTIG -->
<placeable type="FS25_SiloExtension.extendedSilo">

❌ "Missing collision group FILLABLE"

Ursache: Der exactFillRootNode des UnloadTriggers hat kein FILLABLE-Flag.

Lösung: Im Giants Editor den Node auswählen → Collision Group → Bit 30 (FILLABLE) aktivieren.


❌ Box-Dialog öffnet sich nicht

Ursache: boxPlayerTrigger-Node hat falsche Collision-Maske oder Node-Pfad stimmt nicht.

Lösung:

  1. i3dMapping für boxPlayerTrigger prüfen
  2. Im Giants Editor Collision Group = TRIGGER (Bit 29), Collision Mask = PLAYER (Bit 20) setzen
  3. Sicherstellen dass der Node als Trigger konfiguriert ist (nicht als statisches Objekt)

Nächste Schritte

  1. ✅ Content-Mod mit modDependencies auf FS25_SiloExtension einrichten
  2. ✅ Placeable-XML mit boxSystem konfigurieren
  3. ✅ i3dMappings eintragen
  4. Im Giants Editor Trigger-Nodes korrekt konfigurieren
  5. Optional: FillPlane für Füllstand-Visualisierung einrichten
  6. Optional: SiloDisplay für 3D-Textanzeige einrichten