Posts by red51

A small new update is available now!

    Am I correct to believe that it's always going to be better to use the StringBuilder class over String?

    The Java compiler already turns a + concatenation either into a StringBuilder, or uses internal String magic (since Java 9) to combine them (which is even faster than a StringBuilder) ^^ So it's totally fine to use the + operator in most cases.

    But there are situations where the compiler typically can't optimize it, e.g. in loops or if the concatenation happens over multiple methods - so it's much better and faster to use a StringBuilder there ;)

    Oha, danke für den Hinweis, tatsächlich ist das Enum noch aus der Java Version und hat da gar nichts mehr zu suchen :saint: Mit dem kommenden Hotfix werden wir das entfernen (das WeatherChangeEvent und die Server-Methoden auch entsprechend abändern) und stattdessen können dann die WeatherDefs verwendet werden (die die Wetter-Definitionen enthalten). Der Einfachheit halber wird es die bestehenden Wettereffekte darin dann vordefiniert als statische Variablen geben (zB WeatherDefs.Rain) ;)


    Das Enum würde ich also vermeiden. Nach dem Hotfix (höchstwahrscheinlich morgen) wird aus Server.setWeather(Weather.Overcast, true); dann ein Server.setWeather(WeatherDefs.Overcast, true);

    This is indeed C# code (although a few other languages support that feature as well) :D It's called String interpolation. Java doesn't have such a feature directly... instead you either have to use regular concatenation, or the String.format() method. In newer Java versions there is also a new "formatted" method (e.g. "%s bar".formatted("foo");, which is the same as String.format("%s bar", "foo");).


    Strictly speaking, String concatenation is usually a lot faster than String.format(), but only the latter provides proper formatting options. But we're typically talking about nanoseconds here (so you wouldn't really notice a difference unless doing thousands or hundreds of thousands of calls) ^^


    So if you want formatted Strings, use "String.format()" (or the new ".formatted()" method), and if you just want to combine some Strings, use concatenation - unless you're in a loop, then it's much better to use a StringBuilder object directly:

    Java: Bad code
    String text = "Numbers: ";
    for(int i = 0; i < 100; i++){
    text += " " + i;
    }


    Java: Good code
    StringBuilder sb = new StringBuilder(300);
    sb.append("Numbers: ");
    for(int i = 0; i < 100; i++){
    sb.append(' ').append(i);
    }
    String text = sb.toString();

    Gibt es denn schon eine grobe Vorhersage, wann wir Items und Worlditems erstellen können?

    Du meinst eigene, neue Items, also Custom Items? Leider haben wir momentan noch keinen Zeitplan dafür :/ Das zieht leider einen relativ langen Rattenschwanz hinter sich her...


    Geladene Prefabs werden bei Neustart nicht wiederhergestellt. Muss ich das in der Plugin selber machen, oder fehlt hier noch etwas in der API?

    Das Speichern und Laden von "GameObjects" (genau wie UI Elemente) muss im Plugin selbst implementiert werden. Hier könnte der StaticModelLoader der Java Version als Referenz dienen (die API ist in der neuen Version zwar etwas anders, aber die Logik bleibt die gleiche), dort ist sowas zB implementiert ;)


    Man kann bspw. eine eigene SQLite Datenbank im Pluginordner anlegen und dort die Daten drin speichern. Leider ist Seitens der API noch kein SQLite oder MySQL inkludiert, das ändert sich aber mit dem Hotfix, der in Kürze erscheint^^


    Ein paar Beispielscripte wären sicherlich für alle sehr hilfreich.

    Aus Zeitmangel haben wir leider noch keine Beispielplugins bereitstellen können :/ Die Beispielplugins der Java Version können aber als grobe Vorlage verwendet werden.


    Ansonsten enthält dieser Thread noch ein paar Informationen über "GameObjects" (das ist die Grundklasse, die selbstgeladene Elemente in der Spielwelt repräsentiert - in der Java Version hießen die noch "WorldElement"): New Plugin Game Objects

    1. Fließgewässer für Fluss- und Bachbetten. Damit meine ich den optischen Eindruck, nicht den physikalischen.

    Das war ursprünglich für das Wasser geplant (als visueller Effekt wenn Wasser fließt, hätte man aber über statisches Wasser auch platzieren können), hat es aber leider nicht ins damalige Welt-Update geschafft (und ist dadurch auf die lange Bank gerutscht) :/ Das Thema ist aber noch nicht vom Tisch :D


    2. Stehende Gewässer, von dunklerer Eigenschaft, ohne großartigen Wellengang und Dauergeplätscher, zur Darstellung von Mooren oder Tümpeln

    Weitere Wassersorten sind geplant, ggf. kommt schon etwas zusammen mit dem Biomupdate, ansonsten aber vmtl. erst etwas später...


    3 Wasserfälle. Wahrscheinlich am schwierigsten zu bewerkstelligen, aber ich als alter Landschaftsbauliebhaber, gebe die Hoffnung eben nicht auf.

    Wir möchten durchaus ein paar Wasserfälle als "technische Objekte" einbauen - die man also fest platzieren kann. Das werden dann überwiegend Partikeleffekte sein. Ist leider nicht dasselbe, wie richtige Wasserfälle, aber damit sollte sich schon einiges anstellen lassen ^^

    Yes, subsurface scattering is unfortunately indeed disabled right now (because it it's not used by the game yet)... but it's definitely our intention to add it for vegetation and certain other materials in the future ;)

    Das klassische bzw. natürliche Wasser wird sich leider nicht an solche Formen anpassen können - das ist technisch mit heutiger Hardware nicht möglich, da das Wasser dafür eine deutlich kleinere Tröpfchengröße benötigt. Gleichzeitig muss Wasser aber auch persistent sein, d.h. der Zustand bzw. die Position in der Welt gespeichert werden. Ebenso muss es im Multiplayer synchronisiert werden. Ansätze, wie man in einigen Grafikdemos sieht (GPU Wasser, meist auch nur im kleinen Maßstab) funktionieren daher nicht.


    Derzeit besteht ein komplett mit Wasser gefüllter Chunk (32x64x32 Blöcke) aus 65.536 "Wassertropfen" (in Blockgröße). Für präziseres Wasser müsste so ein Tropfen eher die Größe von 0.1 oder gar 0.05 Blöcken haben (vmtl. wäre auch das für kleine Behälter noch zu grob). Bei einer Größe von 0.05 bestünde ein einzelner Chunk bereits aus 524 Millionen Wassertropfen. Das ist einerseits viel zu viel zum Berechnen, andererseits zu viel zum Speichern oder im MP zu snychronisieren...


    Als Lösung wird es aber später die Möglichkeit geben, eine Wassertextur auf Bauteile zu legen. Damit wird man beliebige Formen oder Behälter mit Wasser ausfüllen können ;)


    Eine andere Sache ist das Terrain anzupassen. Ich spreche nicht vom der allgemeinen Möglichkeiten mit dem Tool, sondern, die Höhen von Gebäuden mit der Umgebung in Einstimmung zu bringen.

    Mein Beispiel ist mein alter Friedhof. Wie man unschwer erkennen kann, ist die Hälfte der Grabsteine im Boden verschwunden. Höhenanpassung des Terrains funktioniert nicht, die einzige Möglichkeit ist abreißen und neu hinsetzen, aber dann stimmt die restliche Umgebung nicht mehr. Man versucht ja sein Bestes, aber einen Friedhof mit Platten zu verkleiden oder zukünftige Terrainplatten zu verwenden, ist auch nicht schön. Das Terrain hat im Gegensatz zur gebauten Umgebung immer einen Höhenunterschied. Ich frage mich zwar seit Jahren, warum das so sein muss?

    Blöcke mit einer Größe von 1x1x1 ragen, wenn sie im Raster (größte Stufe) auf flachen Terrain platziert wurden, standardmäßig ein kleines Stückchen heraus. Der Grund liegt darin, dass dadurch das Bauen von Fundamenten usw. in vielen Situationen vereinfacht wird. Das können wir nicht mehr ändern ohne alte Welten zu zerschießen.


    Statt das Terrain zu verschieben bzw. zu ändern, können aber Blöcke natürlich verkleinert oder frei platziert werden, damit sie zB direkt auf dem Terrain aufliegen.


    Langfristig wäre es sonst ggf. noch denkbar, dass optional das Raster der Blöcke verschoben werden könnte :thinking:

    Oh, sorry, I misunderstood your previous message :saint: Actually TextureAsset.loadFromFile(plugin.getPath() + "\\res\\test.jpg"); should already work (if there is a "res" folder in your plugin dir) :wat: If the image doesn't show up, there is likely another reason for that (e.g. maybe another style setting causing the image to be transparent or something like that) :thinking: Could you maybe post your style code here (or send it via PM to me)?^^

    Your code is correct, and the file can be loaded from a plugin .jar indeed, it's just that the data isn't properly synced with the client apparently (due to a bug). This will be definitely fixed soon ;)

    Sure, that could be added with the upcoming hotfix :) However, we have been thinking about adding a more generic event like PlayerChangeStateEvent instead - it would be called every time the player changes his state, e.g. sitting on a chair, lying in a bed, playing a piano etc. So this old code:

    Java
    @EventMethod
    public void onPlayerSleep(PlayerSleepEvent evt){
    Player player = evt.getPlayer();
    //Player is sleeping
    if(evt.isSleeping()) System.out.println("Player " + player.getName() + " is now sleeping");
    //Player is no longer sleeping
    else System.out.println("Player " + player.getName() + " is no longer sleeping...");
    }


    Would look like this in the new API:

    Java
    @EventMethod
    public void onPlayerChangeState(PlayerChangeStateEvent evt){
    Player player = evt.getPlayer();
    //If new state is "sleeping", player went to bed
    if(evt.getNewState() == Player.State.Sleeping) System.out.println("Player " + player.getName() + " is now sleeping");
    //If old state was sleeping, player is now definitely no longer sleeping
    //(otherwise there wouldn't have been a state change)
    else if(evt.getOldState() == Player.State.Sleeping) System.out.println("Player " + player.getName() + " is no longer sleeping...");
    }


    The new event requires a bit more code, but in return, it provides access to other state changes as well (e.g. sitting on a chair, swimming, climbing ladders etc). Do you think that would work in your case?

    Loading from plugin resources is broken atm unfortunately :/ But we try to get it fixed with the upcoming hotfix ;) However, loading from a file (e.g. from plugins folder), url, asset bundle or raw byte data should still work.

    Allerdings komme ich nicht an der net.jiw.unity.runtime.PluginLoader.loadPlugins(PluginLoader.java:71) vorbei

    Nee, es ist anders herum, der erste Aufruf des Stacks ist die obige Zeile (PluginLoader.loadPlugins()), diese wiederum ruft "onEnable()" im Plugin auf, das dann "update()" in JSONManagerMSB, welches "reload()" aufruft - der Aufruf "getDeclaredConstructor()" wirft dann letztenendes die "NoSuchMethodException", was heißt, dass dieser Konstructor nicht gefunden wurde. Das hängt mit dem Classloader eigentlich nicht direkt zusammen (die Klasse kennt er ja scheinbar, sonst hätte Class.forName() schon eine Exception geworfen). Die Klasse befindet sich im gleichen Plugin, oder?


    Wie paulevs erwähnt, die Signatur des Konstruktors scheint eine andere als angegeben zu sein (der Konstruktor erwartet einen String-Parameter, aber du suchst nach einem Konstruktor mit "ClassSeite"-Parameter. Zeile 5 oben muss also - wie paulevs schon sagt - so aussehen: Constructor<?> cons = clazz.getDeclaredConstructor(String.class); ;)

    Oh, I'm so sorry to hear about the data loss! :/ Steam cloud save is unfortunately only active for the Java version... we can't activate it for both versions because they would interfere with each other :( And we can't disable it for the Java version yet (because it's still the "main game" that's advertised on the store page)... it's a tricky situation...


    If wiping the storage wasn't too long ago, you could try to use a data recovery tool (there may be a small chance that some blueprints and world files [it's sufficient if you manage to get at least the Chunks.db file] could be recovered)...


    You've also shared some blueprints in our forums in the past, so at least these blueprints are safe: https://www.rising-world.net/search-result/14167/

    I think that I found an answer - if the style is created on plugin startup and applied to several elements it will change only the first element. Looks like style argument will be mutated, and if it will be applied to the next element it will not have effect.

    Yes, in fact each Style field has a "dirty" flag which is set whenever a property is changed. When applying the Style, the game only serializes the dirty properties (and removes the dirty flag at the same time). So when reusing the Style object, it no longer has any dirty flags.

    For regular, built-in UI elements this usually makes sense (because you can't assign Style objects anyway), but when overriding game UI elements (through the Internals method), it's probably better if the fields remain "dirty" after serialization. We will change that with the upcoming hotfix, so Style objects will be reusable when overriding UI elements ^^ Until then, the workaround is indeed to create a new Style object everytime you override an element (which is a bit cumbersome unfortunately)^^

    I see, yes we could add the player.showLocationTicker() method with the upcoming hotfix :) There is no max character count for the location ticker (it even supports line breaks) :D


    But please bear in mind that entering an area with a name, for example, or entering any other location that triggers the location ticker overwrites the text again... to overcome this, we could maybe add an event for that (so you could cancel that event if required). But alternatively you could also use the player.showStatusMessage() method to show a text on screen (it's not as fancy as the location ticker though)^^

    Dummerweise hatte ich als Leinwand eine Steintextur genommen, die ich mal eben mit F8 auf Putz ändern wollte ... hat auch geklappt; aber die Farbe war komplett weg 8|

    Hängen Textur und Farbe denn dermaßen voneinander ab?

    Ja, wenn eine andere Textur mit dem F8 Tool gewählt wird, wird leider auch die Farbe geändert (denn das Tool kann ja Farben überschreiben, da ist in der Ecke des kleinen Texturfensters ja dieser Pinöpel mit dem eine neue Farbe gewählt wird) ^^

    Aber wir werden das mit dem nächsten Hotfix insofern ändern, dass bestehende Farben erhalten bleiben außer der Spieler wählt explizit eine neue Farbe im Texturfenster aus ;)


    und könnte man bezüglich der Deckkraft nicht einfach einen Sättigungsgrad bei der Farbauswahl hinzufügen, so dass man dort experimentieren könnte zwischen durchschimmern der Textur und Deckkraft, anstatt sich zwischen der einen oder anderen Möglichkeit entscheiden zu müssen?

    Das Problem ist leider, dass wir derzeit keine weiteren Farbdaten oder -informationen mehr an die Grafikkarte senden können (ohne ein paar größere Änderungen vorzunehmen)... aktuell senden wir 4 Farbinfos an den Shader - die RGB Farbwerte sowie den Alpha-Wert. Grundsätzlich wäre der Alpha-Wert die Deckkraft, wir verwenden das allerdings dafür, um diesen groben Anmal-Effekt zu erzielen, der zB bei halb angemalten Objekten oder Bauteilen sichtbar wird (was wie abgenutzte Farbe aussieht). D.h. die Deckkraft beträgt immer 100%, man kann lediglich bestimmen, wieviel der Textur angemalt wird (abhängig von der Textur selber).


    Wenn wir darauf verzichten würden, dann könnten wir diesen Wert stattdessen für die Farbintensität bzw. Deckkraft verwenden (dann würde allerdings dieser "Abgenutzte-Farben-Effekt" bei halb angemalten Bauteilen verlorengehen). Beides hat seine Vor- und Nachteile :/


    Mal sehen, ob sich in Zukunft ggf. noch andere Optionen ergeben :thinking:

    Grundsätzlich können wir in absehbarer Zeit zumindest die UI Elemente anbieten, die wir auch im Spiel verwenden ;) Also prinzipiell Dinge, die man zB im Einstellungsmenü findet etc. Keine klassischen Comboboxen, sondern unsere eigene Implementation davon. Verkleiner- bzw. vergrößerbare Fenster haben wir in unserer UI bislang leider nicht, daher wird sowas wahrscheinlich nicht so schnell kommen...


    Was Buttons angeht: Grundsätzlich kann das mit einem normalen UI Element umgesetzt werden (einfach setClickable() setzen und ggf. noch einen eigenen hoverStyle festlegen) ^^


    Auch der File Browser wird wieder kommen. Der ist noch nicht 100% fertig, muss er aber noch für das nächste Update (Poster) werden. Wahrscheinlich wird zeitgleich (oder kurze Zeit später) dann auch ein Gegenstück in der API vorhanden sein^^