Dieses Guide enthält Informationen rund um die Möglichkeiten mit der main.lua.
Mein dank geht an Basil Weber (Urban Games) und Gwinda, die mir die nötigen Erklärungen zu den neuen Möglichkeiten und die Erlaubnis zur Veröffentlichung der Informationen gegeben haben.
Urban Games wird demnächst auch noch weitere Informationen Rund um das Thema Modding veröffentlichen.
Dieses Guide enthält nur Informationen rund um die main.lua.
Für Informationen zu der info.lua und dem neuen Modding System empfehle ich den folgenden Lexikon Eintrag: [url='http://www.train-fever.net/lexikon/index.php/Entry/92-Making-mods-work-with-the-in-game-mod-manager/']Making mods work with the in-game mod manager[/url].
1 Allgemeines
Die main.lua befindet sich zusammen mit der info.lua und strings.lua im Hauptverzeichnis einer Modifikation oder DLCs. Über die main.lua können Script Eingriffe in das Spiel gemacht werden, ohne das elementare Dateien dafür geändert oder überschrieben werden müssen. Dadurch werden die Modding Möglichkeiten sehr dynamisch und auch kompatibler zu einander.
2 Die main.lua
In diesem Abschnitt werde ich nun auf die verschiedenen Möglichkeiten mit der main.lua eingehen.
[hl=2]game.config.[x][/hl]
Mit der Methode [tt]game.config.[x][/tt] kann man auf diverse LUA-Confog Dateien zugreifen, erweitern und nutzen. Diese liegen im Verzeichnis [tt]Train Fever\res\config[/tt]. Um ein Verständis und die Möglichkeiten mit der Methode zu verdeutlichen werde ich genauer auf [tt]game.config.costs[/tt] und [tt]game.config.cargotypes[/tt] eingehen.
[hl=3]game.config.costs [Parameter editieren][/hl]
In meiner Sandbox Mod benutze ich die Methode game.config.costs um die kosten für Terrain-Bearbeitung, Gleis-, Straßen-, Tunnel- und Brückenbau auf Null zu setzen.
Dafür habe ich die Methode [tt]game.config.costs[/tt] auf [tt]costs[/tt] verkürzt um eine bessere Übersicht zu behalten. Mittels [tt]costs[/tt] kann ich ich nun auf die Parameter von[tt] game.config.costs[/tt] zugreifen. Die Parameter finden sich in der Datei [tt]Train Fever\res\config\costs.lua[/tt] wieder. Also setzen wir in der [tt]main.lua[/tt] nun die Parameter auf Null.
Der Quellcode sieht nun wie folgt aus:
[code]local costs = game.config.costs
costs.terrainRaise = 0
costs.terrainLower = 0
costs.railroadTrack = 0
costs.railroadHighSpeedTrack = 0
costs.railroadCatenary = 0
costs.railroadSwitch = 0
costs.railroadBridge = 0
costs.railroadBridgeVol = 0
costs.railroadTunnel = 0
costs.railroadTunnelLen = 0
costs.roadBusLane = 0
costs.roadTramLane = 0[/code]
So könnt ihr also sehr einfach bestimmte [tt]game.config[/tt] Parameter direkt setzen, ohne das ihr die [tt]costs.lua[/tt] direkt editieren müsst.
[hl=3]game.config.cargotypes [Parameter hinzufügen][/hl]
Mit der Methode [tt]game.config.cargotypes[/tt] können wir auch direkt neue CargoTypen hinzufügen ohne das wir die [tt]cargotypes.lua[/tt] bearbeiten müssen. Dadurch werden neue CargoTypen dynamisch zum Spiel hinzugefügt und es sollte möglich sein, mehrere CargoMods gleichzeitig zu nutzen (nicht getestet, rein theoretische Annahme meinerseits).
Damit wir nun neue CargoTypes hinzufügen können müssen wir als erstes ein Script am Anfang der [tt]main.lua[/tt] einbinden.
Das Script [tt]tableutil[/tt] laden wir mit dem Command [tt]require[/tt].
Unsere [tt]main.lua [/tt]sieht also bisher wie folgt aus:
[code]require "tableutil"[/code]
Für die Methode [tt]game.config.cargotypes[/tt] erstelle ich wieder ein Variable [tt]cargoType[/tt] als Verkürzung.
[code]require "tableutil"
local cargoType = game.config.cargotypes[/code]
Um nun einen neuen CargoTyp hinzu zufügen benötigen wir das Command[tt] table.insert([param1], [param2])[/tt]. Diesen befüllen wir nun mit dem nötigen Inhalt.
An der Stelle von [tt][param1][/tt] fügen wir die gewählte[tt] game.config[/tt] aus, in unseren Fall also die Variable [tt]cargoType[/tt].
An der Stelle von [tt][param2][/tt] fügen wir als nächstes den Array mit Informationen für den neuen CargoTyp ein. Dieser Array sieht wie folgt aus:
[code]{ id = "[id]", name = _("[id]" ) }[/code]
An der Stelle von ID geben wir nun eine Eindeutige ID für die spätere Identifizierung und Verwendung ein, in meinen Beispiel also „PIG_IRON“ und anschließend noch einen geeigneten Namen „Roheisen“. Das Array fügen wir nun an der Stelle von [param2] ein und sollten nun folgende Zeile vorfinden:
[code]table.insert(cargoType, { id = "PIG_IRON", name = _("Roheisen" ) })[/code]
Unsere [tt]main.lua[/tt] sollte nun wie folgt aussehen:
[code]require "tableutil"
local cargoType = game.config.cargotypes
table.insert(cargoType, { id = "PIG_IRON", name = _("Roheisen" ) })[/code]
Natürlich können wir mit dem [tt]table.insert()[/tt] Command so beliebig weitere CargoTypen definieren.
Wie die CargoTypes dann im Spiel genutzt werden können (Lieferketten etc.) muss dementsprechend dann in den .mdl Dateien festgelegt werden, der jeweiligen CargoTypen.
2.1 getConfig und setConfig
Mit Hilfe von getConfig und setConfig können wir beispielsweise eine neue Konfiguration für die Auswahl von Landschaften und Umgebungen definieren. Dies ermöglicht uns widerum eine dynamische Auswahl beim Spielstart, ohne das wir Dateien verändern müssen oder Mods aktivieren/ deaktivieren müssen für unser Spiel.
Um zu verstehen wie die nachfolgenden Parameter funktionieren und eine vollständige Liste der möglichen Parameter zu erhalten, lohnt sich ein Blick in die Train Fever\res\config base_config.lua.
Im folgenden Beispiel werden wir eine neue Auswahl für Landschaft und Umgebung erstellen.
Als ersten benötigen wir wieder das Script [tt]tableutil[/tt] und binden dies mit [tt]require[/tt] ein.
Anschließend kopieren uns mit dem Befehl [tt]table.copy(getConfig("terrain", "/default"))[/tt] die Konfiguration der Standard Landschaft (Europa) und speichern diese in der Variable [tt]newTer[/tt].
[code]require "tableutil"
local newTer = table.copy(getConfig("terrain", "/default"))[/code]
Im nächsten Schritt legen wir nun einen Namen für unsere Landschaft fest. Dieser Name erscheint später in der Auswahlliste der Option Landschaft.
[code]newTer.name = _("main.lua - Guide")[/code]
In den nächsten Schritte legen wir nun die Texturen im Texture-Array für forestFloor (1) über die Parameter fest.
[code]newTer.shader.textures[1].detailTex.fileName = "terrain/mod_name/grass_detail.tga"
newTer.shader.textures[1].detailNrmlTex.fileName = "terrain/mod_name/grass_detail_nrml.tga"
newTer.shader.textures[1].colorTex.fileName = "terrain/mod_name/grass_colors.tga"
[/code]
Anschließend setzen wir die Konfiguration mit [tt]setConfig([option], [mod_name], [arg])[/tt] aktiv.
[code]setConfig("terrain", "mod_name", newTer)[/code]
Unsere [tt]main.lua[/tt] sieht nun wie folgt aus:
[code]require "tableutil"
local newTer = table.copy(getConfig("terrain", "/default"))
newTer.name = _("main.lua – Guide")
newTer.shader.textures[1].detailTex.fileName = "terrain/mod_name/grass_detail.tga"
newTer.shader.textures[1].detailNrmlTex.fileName = "terrain/mod_name/grass_detail_nrml.tga"
newTer.shader.textures[1].colorTex.fileName = "terrain/mod_name/grass_colors.tga"
setConfig("terrain", "mod_name", newTer)[/code]
Wenn wir unsere Mod komplett fertig haben, und diese im Ingame Modmenu aktiv setzen, können wir nun auch bei Landschaft unsere Mod als Landschaft auswählen.
[img]http://img4host.net/upload/0707481854fa9f32b9d3a.png[/img]
2.2 Scripting mit „addModifer“
Mit der Funktion [tt]addModifier[/tt] können sämtliche Inhalte bei Spielerstellung dynamisch modifiziert werden, ohne das jede Datei dafür geändert werden muss. Bei der timeless und costmod war es früher notwendig, jede einzelne Datei mit einem Variable und einer Scripteinbindung auszustatten. Bei neu hinzugefügten Mods musste also jedesmal auch die cost/timeless mod erneut installiert werden oder per Hand die entsprechende Datei der Mod geändert werden. Dies ist dank addModifier nicht mehr nötig und ich erkläre nun wie dies in der Sandbox Mod funktioniert.
Wer mehr über die Möglichkeiten und weiteren Funktionen erfahren möchte, sollte sich das Script [tt]mod.lua[/tt] in[tt] Train Fever\res\scripts[/tt] genauer anschauen.
Zu aller erst fügen wir eine Funktion [tt]metadataHandler[/tt] hinzu, die die übergebene Datei auf vordefinierte Werte überprüft und dementsprechend für diesen Spielstand ändert.
[code]local function metadataHandler(fileName, data)
if data.metadata.cost and data.metadata.cost.price then
data.metadata.cost.price = 0
end
return data
end[/code]
Mittels Data können wir auf die übergebene Datei (fileName) zugreifen und auf die dortigen Parameter. Welche Parameter genau vorliegen kann man einfach Überprüfen in dem eine .mdl eines Modells öffnet uns sich dort den Quelltext näher betrachtet.
Im Grunde erstellt man nun für jeden möglichen Fall eine Überprüfung und setzt dann den Parameter auf den gewünschten Wert. Die gesetzten Parameter werden dann per [tt]return Data[/tt] zurückgegeben und später dem [tt]addModifier[/tt] übergeben.
Für eine bessere Strukturierung und Übersicht empfiehlt es sich mehrere Funktionen anzulegen, da die Strukturen nicht gleich sind in jeder .mdl Datei.
Zum Schluss fügt man noch den entsprechenden [tt]addModifier[/tt] hinzu und verknüpf diesen mit der erstellten Funktion.
[tt]addModifier( "loadModel", metadataHandler )[/tt]
Folgende [tt]addModifier[/tt] sind möglich:[list][*]loadModel
[*] loadBridge
[*] loadBuilding
[*] loadBuildingMaterial
[*] loadMultipleUnit
[*] loadRailroadCrossing
[*] loadSoundSet
[*] loadStreet
[*] loadTrainStation
[*] loadTunnel[/list]
Wer sich noch näher mit der Vorgehensweise beschäftigen möchte, sollte sich den timeless mod, cost mod oder meine sandbox mod genauer anschauen.
Ich hoffe mit diesem kleinen Guide konnte ich euch mehr Licht ins Dunkeln bringen, gerne könnt ihr auch Fragen oder Anregungen, Kritik posten.
Sollten neue Informationen bekannt/veröffentlicht werden, werde ich diese auch gerne hier hinzufügen und erläutern.
Mit freundlichen Gruß
Revyn112