Wiggles Multiplayer Mod v0.1
Hallo Wiggles Freunde,
in den letzten Tagen habe ich mich an dem langjährigen Traum eines Wiggles Multiplayer-/ Coop Mods versucht.
Der Mod öffnet bei Spielstart einen TCP Server über den in Wiggles integrierten TCL Interpreter und verbindet sich ebenfalls zum angegebenen TCP Server eines anderen Wiggles Client. (Die Verbindung lässt sich in der setupmpconnection.tcl konfigurieren welche bei Spielstart durch die systeminit.tcl aufgerufen wird)
Sobald dann Ingame Events über die TCL Skripte ausgeführt werden, etwa beim Laufen oder Pilz fällen (z.B data/Scripts/classes/zwerg/z_events.tcl), werden diese über die erstellte Methode "generate_mp_command" an den verbundenen anderen Client gesendet. Dieser prüft alle 200ms auf neue eingegangene TCP Pakete und führt die darin enthaltenen TCL Commands aus (Umgesetzt über eine angepasste tcl83.dll und den hinzugefügten custom TCL Command updateLEG welcher über einen zweiten Thread alle 200ms auf wartende Fileevents prüft).
In diesem Github repository werden alle angepassten Dateien für den MP Mod verwaltet: https://github.com/itsme12345678910/Wig ... ree/master
Einrichtung:
1. Den Inhalt des Repositorys in den Ordner kopieren in welchem die Wiggles.exe liegt.
2. Oben in der setupmpconnection.tcl die IP Adresse des anderen PCs angeben zu welchem sich verbunden werden soll und bei einem Client #sleep 20000 wieder zu sleep 20000 (ohne #) ändern und diesen Client ein paar Sekunden früher starten
3. Auf beiden Clients gleichzeitig denselben Spielstand laden
Alpha v.0.1
Der Mod ist aktuell weit entfernt von Fertig, voll funktionsfähig oder Bugfrei. Ein Spielen ist damit aktuell nicht wirklich möglich und es ist nur ein erster Anfang
Ich würde mich sehr freuen wenn sich ein paar Leute finden die Interesse an dem Projekt haben. Über jede Hilfe bei der Umsetzung bin ich sehr dankbar. Weiterentwicklungen, Bugfixes und Verbesserungsvorschläge sind jederzeit gerne gesehen
Falls euch noch Informationen zu irgendeinem technischen Aspekt des Projekts oder ähnlichem fehlen oder noch Fragen offen sind werde ich mein bestes tun euch dabei weiterzuhelfen.
P.S.: Zur Weiterentwicklung des Multiplayers habe ich mir 2 kleine Java Tools geschrieben (einfach in irgendeiner IDE z.B. Intellij laden & starten), welche das Debugging deutlich vereinfachen und sich somit auch ohne zweiten PC/Client Veränderungen am Mod leicht testen lassen.
1. WigglesTestServer: https://github.com/itsme12345678910/WigglesTestServer
Ein simpler TCP Server, welcher sich anstelle von einem zweiten Client in die setupmpconnection.tcl eintragen lässt (127.0.0.1:5591) und alle Commands welche der Wiggles Client versendet auf der Console ausgibt.
2. WigglesTestClient: https://github.com/itsme12345678910/WigglesTestClient
Ein simpler TCP Client, mit welchem sich beliebige TCL Commands direkt an den laufenden Wiggles Client senden lassen, welche dieser dann ausführt
Wiggles Coop-/Multiplayer Mod
Re: Wiggles Coop-/Multiplayer Mod
Cooles Projekt!
LG Arthur
LG Arthur
Re: Wiggles Coop-/Multiplayer Mod
I've created an account on this forum just to write this. I don't speak German, sorry.
Maan, I would be so happy if you continue working on this.
It's been a holy grail for Wiggles enthusiasts like myself.
Keep up the good work!
Maan, I would be so happy if you continue working on this.
It's been a holy grail for Wiggles enthusiasts like myself.
Keep up the good work!
Re: Wiggles Coop-/Multiplayer Mod
Hi, kannst du genauer beschreiben, wie die TCL83.dll erzeugt bzw. angepasst wurde?
Re: Wiggles Coop-/Multiplayer Mod
Hey pyreq, great to hear that there are still more people than just myself waiting to play Wiggles multiplayer. I hope it can function flawlessly one day. Sadly I have barely any time to continue working on the project but I certainly plan to do so in the future. Hopefully we can play a round together in the future
Hey tilk, um die TCL dll abzuändern habe ich mir den sourcode von TCL 8.3 runtergeladen (welcher zum Glück Open Source ist), dann editiert und mithilfe von den im Download enthaltenen Buildscripten dann wieder neu kompiliert. Leider hat das kompilieren mit einem modernen compiler nicht funktioniert, weshalb ich mir eine alte Visual Studio Version heruntergeladen habe (Visual Studio 5?) womit es dann funktioniert hat.
Angepasst wurde alles was in der C Datei im Repository unter dem "Custom Wiggles Code" Kommentar steht. Prinzipiell aber eigentlich nur das folgende:
Wiggles prüft immer dann wenn die Tcl_EvalEx Methode aufgerufen wird mit, ob im Wiggles Verzeichnis eine neue Datei mit TCL commands abgelegt wurde. Sofern dort eine liegt, führt es die Commands aus und löscht die Datei.
Der gesamte Workflow sieht so aus:
1. In den Wiggles TCL Skripten wurde bei allen Aktionen (wie laufen oder essen usw.) ein Codeblock integriert, welcher den ausgeführten Befehl als TCL Command 1:1 rausschreibt.
2. Die Wiggles Server Java Komponente schickt den TCL Command an den Mitspieler (Wurde früher direkt im TCL gemacht aber Wiggles = Singlethreaded und das führte zu massivsten Problemen)
3. Die Wiggles Client Java Komponente auf der Gegenseite erhält die Commands und schreibt sie in die remoteCommands Datei im Wiggles Verzeichnis
4. Die Wiggles Exe ruft (scheinbar) nahezu durchgehend die Tcl_EvalEx Methode aus der TCl dll auf und führt somit alle Aktionen der Gegenseite auch auf dem eigenen Client aus.
Das ganze funktioniert soweit auch, bis auf die Tatsache, dass bisher nicht alle Befehle übertragen werden und da leider (hoffentlich noch) nicht alles übetragen wird die Clients schnell out of Sync laufen.
Ein kleines Video wie der aktuelle Stand ausgeführt wird habe ich mal vor einigen Monaten auf dem Wiggles Discord gepostet, du kannst allerdings auch gerne Versuchen es selbst zu Laufen zu bringen, sollte prinzipiell alles da sein. (Und auch gerne weiterentwickeln und/oder mit guten Ideen weiterhelfen)
Das letzte große Problem auf welches ich gestoßen war ist, dass obwohl es einen TCL Command gibt um die grünen Grabmarkierungen zu setzen diese wohl irgendwie in der Wiggles.exe direkt ohne TCL umgesetzt werden und sich daher schwer übertragen lassen ... (Vllt mit einem fixed memory offset o.Ä. den Speicherort finden an dem immer die Markierungen gespeichert sind und so übertragen? Kp ob das so funktionieren kann )
Hey tilk, um die TCL dll abzuändern habe ich mir den sourcode von TCL 8.3 runtergeladen (welcher zum Glück Open Source ist), dann editiert und mithilfe von den im Download enthaltenen Buildscripten dann wieder neu kompiliert. Leider hat das kompilieren mit einem modernen compiler nicht funktioniert, weshalb ich mir eine alte Visual Studio Version heruntergeladen habe (Visual Studio 5?) womit es dann funktioniert hat.
Angepasst wurde alles was in der C Datei im Repository unter dem "Custom Wiggles Code" Kommentar steht. Prinzipiell aber eigentlich nur das folgende:
Wiggles prüft immer dann wenn die Tcl_EvalEx Methode aufgerufen wird mit, ob im Wiggles Verzeichnis eine neue Datei mit TCL commands abgelegt wurde. Sofern dort eine liegt, führt es die Commands aus und löscht die Datei.
Der gesamte Workflow sieht so aus:
1. In den Wiggles TCL Skripten wurde bei allen Aktionen (wie laufen oder essen usw.) ein Codeblock integriert, welcher den ausgeführten Befehl als TCL Command 1:1 rausschreibt.
2. Die Wiggles Server Java Komponente schickt den TCL Command an den Mitspieler (Wurde früher direkt im TCL gemacht aber Wiggles = Singlethreaded und das führte zu massivsten Problemen)
3. Die Wiggles Client Java Komponente auf der Gegenseite erhält die Commands und schreibt sie in die remoteCommands Datei im Wiggles Verzeichnis
4. Die Wiggles Exe ruft (scheinbar) nahezu durchgehend die Tcl_EvalEx Methode aus der TCl dll auf und führt somit alle Aktionen der Gegenseite auch auf dem eigenen Client aus.
Das ganze funktioniert soweit auch, bis auf die Tatsache, dass bisher nicht alle Befehle übertragen werden und da leider (hoffentlich noch) nicht alles übetragen wird die Clients schnell out of Sync laufen.
Ein kleines Video wie der aktuelle Stand ausgeführt wird habe ich mal vor einigen Monaten auf dem Wiggles Discord gepostet, du kannst allerdings auch gerne Versuchen es selbst zu Laufen zu bringen, sollte prinzipiell alles da sein. (Und auch gerne weiterentwickeln und/oder mit guten Ideen weiterhelfen)
Das letzte große Problem auf welches ich gestoßen war ist, dass obwohl es einen TCL Command gibt um die grünen Grabmarkierungen zu setzen diese wohl irgendwie in der Wiggles.exe direkt ohne TCL umgesetzt werden und sich daher schwer übertragen lassen ... (Vllt mit einem fixed memory offset o.Ä. den Speicherort finden an dem immer die Markierungen gespeichert sind und so übertragen? Kp ob das so funktionieren kann )
Re: Wiggles Coop-/Multiplayer Mod
Prima, danke für die Infos! Ich find die grundsätzliche Idee sehr cool. Hier im Forum habe ich schon öfters Spekulationen über Multiplayer gelesen, aber ich glaub darauf kam noch keiner.
Ich hatte schon vermutet, dass ich das komplette TLC 8.3 Repo kompilieren müsste, um die .dll zu reproduzieren. Wollte mich aber nochmal absichern, bevor ich viel Zeit reinstecke
Dann versuch ich das mal lokal bei mir nachzustellen. Klingt aber ziemlich fummelig, wird sicher etwas dauern.
Als Verbesserung hab ich überlegt, die Synchronisation der TLC-Commands direkt in die TLC.dll einzubauen. Statt eine Funktion in jedem Command in den TLC-Scripten hinzuzufügen würde die Tcl_EvalEx eine Art Command-Queue befüllen, die dann zwischen den Clients synchronisiert wird. Tcl_EvalEx ist vielleicht dafür auch nicht der richtige Einstiegspunkt, aber ich sehe eine Chance die Synchronisierungsfehler zu verringern. mMn sollte es auch möglich sein, einen kleinen TCP-Client in einem seperaten Thread direkt in die TLC.dll "reinzuhängen". Damit könnte man den zusätzlichen Java-Server und den lokalen Datentransfer über das remoteCommand-file rauskegeln.
Ich hab mir dein Repository geforked. Ich schick nen pull-request wenn ich was erreicht habe und meld mich dann hier wieder
Ich hatte schon vermutet, dass ich das komplette TLC 8.3 Repo kompilieren müsste, um die .dll zu reproduzieren. Wollte mich aber nochmal absichern, bevor ich viel Zeit reinstecke
Dann versuch ich das mal lokal bei mir nachzustellen. Klingt aber ziemlich fummelig, wird sicher etwas dauern.
Als Verbesserung hab ich überlegt, die Synchronisation der TLC-Commands direkt in die TLC.dll einzubauen. Statt eine Funktion in jedem Command in den TLC-Scripten hinzuzufügen würde die Tcl_EvalEx eine Art Command-Queue befüllen, die dann zwischen den Clients synchronisiert wird. Tcl_EvalEx ist vielleicht dafür auch nicht der richtige Einstiegspunkt, aber ich sehe eine Chance die Synchronisierungsfehler zu verringern. mMn sollte es auch möglich sein, einen kleinen TCP-Client in einem seperaten Thread direkt in die TLC.dll "reinzuhängen". Damit könnte man den zusätzlichen Java-Server und den lokalen Datentransfer über das remoteCommand-file rauskegeln.
Ich hab mir dein Repository geforked. Ich schick nen pull-request wenn ich was erreicht habe und meld mich dann hier wieder
Re: Wiggles Coop-/Multiplayer Mod
Freut mich sehr zu hören, dass du dich drangemacht hast den Multiplayer weiterzuentwickeln.
Das alles direkt in der TCl.dll über separate Threads umzusetzen wäre natürlich eigentlich der Idealfall und habe ich auch schon versucht. Leider gab es dabei jedoch immer wieder Probleme.
Die Umsetzung des TCP Clients über ein separates Java Tool habe ich auch eher aus Bequemlichkeit gewählt, da sich das ganze ja direkt in der DLL aufwendiger debuggen lässt und ich nicht noch mehr Komponenten drin haben wollte welche zu random crashs führen können.
Die Wiggles.exe selbst ist Single Threaded und erzeugt genau einen TCL Interpreter mit dem Wiggles TCL Command Set. Nur TCL Commands die von genau diesem einen Interpreter ausgeführt werden führen zu Aktionen im Spiel. TCL Commands in diesem Interpreter aus einem anderen Thread heraus auszuführen habe ich nicht hinbekommen, da der Multithread Support bei TCL (welcher sich in den Config Dateien für den Compiler auch in der Version schon aktivieren lässt) immer nur einen Interpreter pro Thread zulässt und keine Kommunikation zwischen diesen möglich ist. Daher die Kommunikation über die Datei welche immer wieder eingelesen wird und möglichst wenig extra Rechenaufwand für den Wiggles Mainthread.
Die Variante in der ich mal versucht hatte alles direkt in die TCL dll zu integrieren hat prinzipiell auch funktioniert, jedoch ist Wiggles immer nach einigen Minuten gecrashed (vermutlich war irgendwas nicht Threadsafe )
Es gibt bestimmt jede Menge Optimierungspotential und die Commands direkt beim Ausführen im TCL Interpreter abzufangen und dann zu übertragen und nicht über die TCL Skripte im Wiggles Ordner ist auf jeden Fall der richtige Ansatz, aber benötigt mit Sicherheit ein tieferes Verständnis davon, wie TCL intern die Befehle ausführt und auf welche Art und weise Wiggles das triggert (gab da auch Unterschiede zwischen den Commands die über die Konsole kommen und denen welche die Wiggles.exe direkt ausführt, viel zu debuggen auf jeden Fall)
Wenn du irgendwo auf Probleme stoßen solltest lass es mich gerne wissen, vielleicht bin ich irgendwann auch schonmal an derselben Stelle gehangen und kann den Lösungsweg daher etwas verkürzen
Die folgenden Probleme habe ich noch im Kopf vom letzten Stand an dem ich noch was gemacht hatte, für die ich bisher keine Lösung hatte. Vielleicht fällt dir dazu ja was ein oder du stolperst über einen Lösungsansatz im Laufe der Analyse:
- Die grünen Grabmarkierungen welche man von Hand zieht werden nicht per TCL platziert, lassen sich somit nicht übertragen und Zwerge können nur da graben wo es grün markiert ist
- Die kleinen Minibewegungen wie Strecken, 10cm laufen oder an die Wand malen lösen auch keine TCL Commands aus und lassen das Spiel somit out of sync laufen
- Die playerid lässt sich irgendwie nicht ändern (auch wenn sie überall referenziert wird) weshalb man nur mit großem Aufwand Gegeneinander und nicht im Coop Spielen kann
Sonst bin ich sehr gespannt auf das was rauskommt und freue mich auf die pull-requests. Hoffentlich bringt es uns Stück für Stück näher in Richtung eines funktionierenden Multiplayers.
Das alles direkt in der TCl.dll über separate Threads umzusetzen wäre natürlich eigentlich der Idealfall und habe ich auch schon versucht. Leider gab es dabei jedoch immer wieder Probleme.
Die Umsetzung des TCP Clients über ein separates Java Tool habe ich auch eher aus Bequemlichkeit gewählt, da sich das ganze ja direkt in der DLL aufwendiger debuggen lässt und ich nicht noch mehr Komponenten drin haben wollte welche zu random crashs führen können.
Die Wiggles.exe selbst ist Single Threaded und erzeugt genau einen TCL Interpreter mit dem Wiggles TCL Command Set. Nur TCL Commands die von genau diesem einen Interpreter ausgeführt werden führen zu Aktionen im Spiel. TCL Commands in diesem Interpreter aus einem anderen Thread heraus auszuführen habe ich nicht hinbekommen, da der Multithread Support bei TCL (welcher sich in den Config Dateien für den Compiler auch in der Version schon aktivieren lässt) immer nur einen Interpreter pro Thread zulässt und keine Kommunikation zwischen diesen möglich ist. Daher die Kommunikation über die Datei welche immer wieder eingelesen wird und möglichst wenig extra Rechenaufwand für den Wiggles Mainthread.
Die Variante in der ich mal versucht hatte alles direkt in die TCL dll zu integrieren hat prinzipiell auch funktioniert, jedoch ist Wiggles immer nach einigen Minuten gecrashed (vermutlich war irgendwas nicht Threadsafe )
Es gibt bestimmt jede Menge Optimierungspotential und die Commands direkt beim Ausführen im TCL Interpreter abzufangen und dann zu übertragen und nicht über die TCL Skripte im Wiggles Ordner ist auf jeden Fall der richtige Ansatz, aber benötigt mit Sicherheit ein tieferes Verständnis davon, wie TCL intern die Befehle ausführt und auf welche Art und weise Wiggles das triggert (gab da auch Unterschiede zwischen den Commands die über die Konsole kommen und denen welche die Wiggles.exe direkt ausführt, viel zu debuggen auf jeden Fall)
Wenn du irgendwo auf Probleme stoßen solltest lass es mich gerne wissen, vielleicht bin ich irgendwann auch schonmal an derselben Stelle gehangen und kann den Lösungsweg daher etwas verkürzen
Die folgenden Probleme habe ich noch im Kopf vom letzten Stand an dem ich noch was gemacht hatte, für die ich bisher keine Lösung hatte. Vielleicht fällt dir dazu ja was ein oder du stolperst über einen Lösungsansatz im Laufe der Analyse:
- Die grünen Grabmarkierungen welche man von Hand zieht werden nicht per TCL platziert, lassen sich somit nicht übertragen und Zwerge können nur da graben wo es grün markiert ist
- Die kleinen Minibewegungen wie Strecken, 10cm laufen oder an die Wand malen lösen auch keine TCL Commands aus und lassen das Spiel somit out of sync laufen
- Die playerid lässt sich irgendwie nicht ändern (auch wenn sie überall referenziert wird) weshalb man nur mit großem Aufwand Gegeneinander und nicht im Coop Spielen kann
Sonst bin ich sehr gespannt auf das was rauskommt und freue mich auf die pull-requests. Hoffentlich bringt es uns Stück für Stück näher in Richtung eines funktionierenden Multiplayers.