Hallo
Für die Weiterführung der Diskussion in Gameplay-Patch angekündigt
Hier also mal meine Ideen & Anregungen zur Modding Schnittstelle
Die einzelnen Punkte werde ich dann noch mit Inhalt füllen,sobald mir die Zeit es zulässt.
Zusammenfassung:
- Dokumentation zu Parametern
- Fehlerbehandlung
- bessere API für das Laden von neuen Ressourcen (Gleise, Straßen, Tunnel)
- Kontrolle über das Konstruktionsfenster per LUA. Ich möchte alle Internen UI Elemente (Knöpfe usw.) selber festlegen
Daraus erstellt meine LUA Funktion eine Parameter Liste die in der Entity Konstruktion abgelegt werden kann. - Möglichkeit im Virtuellen Res Ordner nach Dateien zu suchen.
- Pfad Auslesen/Speichern von Mod spezifischen Einstellungen.
- Snappoints für Konstruktionen
- Bessere Kontrolle über die Bodentätigkeiten eines Gleis. (Und auch keine Änderung Textur bei alignTerrain = false)
- Abschalten von Tunnelwänden (Ich will nicht jedes Modgleis duplizieren um die Wände zu ändern)
Dokumentation zu Parametern
Damit wir beim erstellen von Mods keine bösen Überraschungen erleben wäre eine Übersicht der Grenzen von Parametern hilfreich:
Beispiele: Max Min werte von slopeLow, slopeHigh
Wie kurz darf ein Straßenstück sein das Snappoints hat? (wenn man ein größere Strasse anbaut, und die Verengung nicht mehr passt crasht das Spiel.)
Fehlerbehandlung
Die LUA Stack Traces sollten wenn möglich die Dateiname mit kompletten Pfadnamen des Modordners zeigen.
Allgemein wäre es gut nicht nur den Mod ID sondern auch die Bezeichnung aus der mod.lua im stdout zu zeigen (Gerade für SteamWorkshop Mods)
API für bessere Ressourcenmanagement
Zurzeit hat TPF keine Möglichkeit die Mod Gleise, Strassen usw. Zentral per Code abzufragen.
Daher Schlage ich eine API Schnittstelle vor, die internen Repositories für Gleise, Strassen, Brücken und so weiter zur Verfügung stellt.
Leisten soll Sie: Die Anzahl der Typen auszugeben, die Daten per ID bzw. Namen zu erhalten, zwischen ID und Namen zu konvertieren.
Als Beispiel:
game.repositories.tracks / roads / bridges
getCount()
getById()
getByName()
convertIdtoName()
convertNameToId()
Damit wäre es Möglich die Gleisauswahl der parameterutils komplett dynamisch zu erstellen.
Auch sind Fragen wie die Gleis oder Straßenbreite so zu erhalten. Ein Depot bauen mit Schmalspurgleis, dafür bräuchte man nur noch ein Depot.
Objekte (Gleise, Strassen, Brücken) erhalten darüber hinaus noch einen shortUIName, und hideInUI Flag.
(Keine Hacks mehr per Erscheinungsjahr um etwas zu verbergen)
Die Filterung hierbei übernimmt ein LUA Script, damit kann dann auch nach anderen Kriterien gefiltert werden.
Die starre paramsutil.makeTrackTypeParam Funktion wird durch eine neue ergänzt. shortUIName wird als Namen der (Gleis)typen genutzt
Probleme / Änderungen am Spiel:
Hierfür muss das Laden von Mods geändert werden, Gleise oder ähnliches müssen früher als Konstruktionen geladen werden oder das Konstruktionsfenster muss man updaten können.
Die UI kann zurzeit nur komplette Parameter per Zeit ausblenden.
Konstruktionen UI
Neue API für UI Konstruktionen, da es eine Zweideutigkeit gibt zwischen param und param der updateFn, hier eine Unterscheidung:
uilist = eine Liste mit der UI Beschreibung (params der Konstruktionsbeschreibung)
settings = eine Liste der gewählten Einstellungen des Users, bzw. die vorhandenen oder neuen Einstellungen der Konstruktion. (also der UI Parameter Teil von updateFn, { param1 = 1, param2 = 2, ... })
Es gibt keine Änderungen in den Namen der vorhanden Daten bzw. in der Funktion.
Neue UI Elemente für die Uilist
Es gibt einen neuen UI Type für jedes Element, sollte dieser nicht vorhanden sein wird type = "VALUELIST" angenommen (zwingend)
Es muss immer auch eine values = {} angeben werden, dies soll verhindern das "alte" Mods zu viele Probleme bekommen, ist aber nicht zwingend.
Hierbei ist zu beachten, damit nicht alles intern verändert werden muss das UI Elemente weiterhin auf uint32 begrenzt sind.
Desweiteren gibt es die Möglichkeit mit hidden = true ein Element auszublenden,
für kompaktere Layouts kann die Überschrift weggelassen werden. name = ""
Einzelne Werte in values Listen sollten auch die Möglichkeiten habe per yearFrom yearTo Zeitabhängig ausgeblendet werden.
Um auch hier die Kompatibilität zu erreichen, schlage ich eine Liste yearFromValues und yearToValues vor, die Liste hat für jeden Eintrag in values einen Wert.
Die verschiedenen Typen:
Wertebuttons:
type = "VALUELIST"
Die jetzigen UI Elemente
Überschriften:
type = "HEADER"
Verstecktes Element:
type = "HIDDEN"
value = <uint>
Dient dazu weitere Daten für eine Konstruktion zu speichern
BUTTON:
type = "BUTTON"
values = { "<nicht gedrückte Beschreibung>", "gedrückte Beschreibung" }
CHECKBOX:
type = "CHECKBOX"
values = { "Wert1 ", "Wert2 " }
Jeder Wert in values Wert kann an/aus geschaltet werden, (Benötigt ggf. bit32 wegen der Lua Version)
Design:
[x] Wert 1
[x] Wert 2
BITSETTING:
type = "BITSETTING"
values = { "Wert1", "Wert2", "Wert3", "Wert4" }
Jeder Wert in values Wert kann an/aus geschaltet werden, (Benötigt ggf. bit32 wegen der Lua Version)
Design:
[Wert 1] {Wert 2] [Wert 3] {Wert 4]
SPINNER:
type = "SPINBOX"
minValue =<uint>
maxValue = <uint>
step = <uint>
values = {}
formatString = "<formatstring>"
Wenn Values gefüllt ist, können diese Werte ausgewählt werden, anstatt einen Wert zwischen minValue, maxValue inklusive
Für größere Wertelisten wäre eine Schnellwahl schön, vielleicht kann man da die Linienauswahl Fenster wiederverwenden.
updateUIFn(uilist, settings)
Erstellt eine neue UI für diese Konstruktion und ersetzt die uilist Definition,
gibt als Rückgabewerte eine Tabelle wieder, analog der updateFn.
Mögliche Rückgabewerte sind eine veränderte uilist und/oder eine neue settings Liste
return {
uilist = uilist,
settings = settings
}
updateUIFn wird aufgerufen bevor eine Konstruktionsfenster erstellt wird, nachdem ein UI Element bedient wurde und nachdem die updateFn ausgeführt wurde.
Die updateFn kann per result.uisettings die Einstellungen der UI ändern!:
Weitere Punkte folgen...
Ihr seit eingeladen eure Kritik / Fehler / API Wünsche zu äußern. Vielleicht hab ich ja noch irgendwo einen Denkfehler oder es gäbe eine bessere Alternative.