{"id":959,"date":"2019-11-04T16:22:19","date_gmt":"2019-11-04T15:22:19","guid":{"rendered":"https:\/\/clockwork-origins.com\/spine-tutorial-5-multiplayer\/"},"modified":"2019-11-04T16:33:53","modified_gmt":"2019-11-04T15:33:53","slug":"spine-tutorial-5-multiplayer","status":"publish","type":"page","link":"https:\/\/clockwork-origins.com\/de\/spine-tutorial-5-multiplayer\/","title":{"rendered":"Spine Tutorial 5 &#8211; Multiplayer"},"content":{"rendered":"\n<h2 class=\"wp-block-heading\">Voraussetzungen<\/h2>\n\n\n\n<ul class=\"wp-block-list\"><li>Ikarus Script-Paket: <a rel=\"noreferrer noopener\" href=\"https:\/\/forum.worldofplayers.de\/forum\/threads\/1299679-Skriptpaket-Ikarus-4\" target=\"_blank\">Thread @ World of Gothic<\/a><\/li><li>LeGo  Script-Paket : <a rel=\"noreferrer noopener\" href=\"https:\/\/forum.worldofplayers.de\/forum\/threads\/1505251-Skriptpaket-LeGo-4\" target=\"_blank\">Thread @ World of Gothic<\/a><\/li><li>Spine  Script-Paket : <a rel=\"noreferrer noopener\" href=\"https:\/\/github.com\/BonneCW\/Spine-Scripts\" target=\"_blank\">Download @ GitHub<\/a><\/li><li><a href=\"https:\/\/clockwork-origins.com\/de\/spine-tutorial-1-initialization\/\">Tutorial 1 &#8211; Initialisierung<\/a><\/li><\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">Einleitung<\/h2>\n\n\n\n<p>Dieses Tutorial zeigt auf, wie mithilfe von Spine ein Multiplayer realisiert werden kann. Die aktuelle Funktionalit\u00e4t ist dabei allerdings nicht auf MMO-Server ausgelegt, sondern auf direkte Multiplayer-Partien zwischen x Spielern, die gleichzeitig ein Spiel suchen.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Die Funktionen<\/h2>\n\n\n\n<p>Die verschiedenen Funktionen dieses Moduls sollen hier kurz vorgestellt werden.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Spine_SetHostname<\/h3>\n\n\n\n<p>Mit <em>Spine_SetHostname<\/em> l\u00e4sst sich der Hostname des genutzten Servers angeben. Standardm\u00e4\u00dfig steht der Wert intern auf dem Spine-Multiplayer-Server. Allerdings erlaubt dieser nur Mods zu Testzwecken und genehmigte Mods. Wer einen eigenen Server aufsetzen will, muss die entsprechende API daf\u00fcr implementieren und mit dieser Funktion den Server setzen. Wer nur einen kleinen Multiplayer hat, kann auch anfragen, ob er direkt \u00fcber Spine gehostet wird.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Spine_SearchMatch<\/h3>\n\n\n\n<p>Mit <em>Spine_SearchMatch<\/em> kann man nach einem Match suchen. Dazu gibt man an, wie viele Spieler das Match am Ende haben soll. Au\u00dferdem wird ein Identifier ben\u00f6tigt. Der Identifier kann genutzt werden, um unterschiedliche Level oder Spielmodi zu repr\u00e4sentieren. Ein Match wird gefunden, wenn f\u00fcr den gleichen Identifier die angegebene Anzahl an Spielern gefunden wurde. Dabei gilt: Wer zuerst ein Match sucht, kriegt auch zuerst eines. Bei eigener Implementierung des Servers kann das Verhalten nat\u00fcrlich beliebig angepasst werden. Das bedeutet, dass man mit<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Spine_SearchMatch(2, 0);<\/code><\/pre>\n\n\n\n<p>ein Match mit zwei Spielern (aktueller Spieler + ein weiterer) f\u00fcr Identifier 0 suchen kann.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Spine_SearchMatchWithFriend<\/h3>\n\n\n\n<p>Mit <em>Spine_SearchMatchWithFriend<\/em> kann man nach einem Match gezielt mit einem Freund suchen. Dazu gibt man an, wie der Freund hei\u00dft. Au\u00dferdem wird ein Identifier ben\u00f6tigt. Der Identifier kann genutzt werden, um unterschiedliche Level oder Spielmodi zu repr\u00e4sentieren. Ein Match wird gefunden, wenn f\u00fcr den gleichen Identifier ein Match mit dem angegebenen Freund gefunden wurde.  Das bedeutet, dass man mit<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Spine_SearchMatchWithFriend(0, \"Bonne\");<\/code><\/pre>\n\n\n\n<p>ein Match mit f\u00fcr Identifier 0 suchen mit dem Freund &#8222;Bonne&#8220; suchen kann. Erst, wenn dieser Spieler ebenfalls ein Spiel sucht (egal ob er auch nach einem Freund sucht oder nicht), wird ein Match gefunden. Das l\u00e4sst sich gut mit dem Freunde-Modul in <a href=\"https:\/\/clockwork-origins.com\/de\/spine-tutorial-6-friends\/\">Tutorial 6<\/a> kombinieren.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Spine_StopSearchMatch<\/h3>\n\n\n\n<p>Mit <em>Spine_StopSearchMatch<\/em> kann man die Suche nach einem Match wieder beenden.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Spine_IsInMatch<\/h3>\n\n\n\n<p>Mit <em>Spine_IsInMatch<\/em> l\u00e4sst sich \u00fcberpr\u00fcfen, ob bereits ein Match gefunden wurde. Da es keinen Callback-Mechanismus daf\u00fcr gibt, muss man nach dem Aufruf von <em>Spine_SearchMatch<\/em> selber \u00fcberpr\u00fcfen, wann <em>Spine_IsInMatch<\/em> <em>TRUE<\/em> zur\u00fcckliefert, um dann entsprechend das Spiel zu starten.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Spine_GetPlayerCount<\/h3>\n\n\n\n<p>Mit <em>Spine_GetPlayerCount<\/em> l\u00e4sst sich abfragen, wie viele Spieler im aktuellen Match vorhanden sind.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Spine_GetPlayerUsername<\/h3>\n\n\n\n<p>Mit <em>Spine_GetPlayerUsername<\/em> l\u00e4sst sich f\u00fcr jede Spielernummer (beginnend bei 0) der Name des Spielers herausfinden.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Spine_CreateMessage<\/h3>\n\n\n\n<p>Mit <em>Spine_CreateMessage<\/em> kann man eine Nachricht erstellen. Eine Nachricht ist ein Container f\u00fcr Daten, den man anschlie\u00dfend \u00fcber das Internet versenden kann. <em>Spine_CreateMessage<\/em> ben\u00f6tigt als Parameter den Nachrichtentyp, der erstellt werden soll. Derzeit verf\u00fcgbare Nachrichtentypen sind:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>SPINE_MESSAGETYPE_BASE: Basisnachricht, enth\u00e4lt nur einen Usertyp, kein Platz f\u00fcr Daten<\/li><li>SPINE_MESSAGETYPE_INT: Nachricht, die einen Integer \u00fcbertragen kann<\/li><li>SPINE_MESSAGETYPE_STRING: Nachricht, die einen String \u00fcbertragen kann<\/li><li>SPINE_MESSAGETYPE_INT4: Nachricht, die vier Integer \u00fcbertragen kann<\/li><\/ul>\n\n\n\n<p>Jede Nachricht hat als beliebig zu setzendes Feld den<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>var int userType;<\/code><\/pre>\n\n\n\n<p>Dieser Kann genutzt werden, um den selben Spine-Nachrichtentyp (z.B. <em>SPINE_MESSAGETYPE_INT<\/em>) f\u00fcr unterschiedliche modspezifische Zwecke zu nutzen, die Nachrichten aber trotzdem unterscheiden zu k\u00f6nnen. Dazu sp\u00e4ter mehr in einem Beispiel.<\/p>\n\n\n\n<p>Wichtig ist, dass man die Werte <em>_vtbl<\/em>, <em>messageType<\/em> und <em>username<\/em> <strong>NIEMALS<\/strong> ver\u00e4ndert. Diese sind intern wichtig und <em>messageType<\/em> und <em>username<\/em> k\u00f6nnen in der Mod abgefragt werden, um die Nachricht zu identifizieren.<\/p>\n\n\n\n<p>Je nach erstellter Nachricht, kann man dann weitere Daten setzen, z.B. Integerwerte oder auch Strings. Der aktuelle Umfang an Nachrichtenklassen entspricht den bisher ben\u00f6tigten f\u00fcr die existierenden Multiplayer-Modifikationen. Wenn neue Daten \u00fcbermittelt werden sollen, kann jederzeit <a href=\"https:\/\/clockwork-origins.com\/de\/kontakt\/\">Kontakt zu uns<\/a> aufgenommen werden, um weitere Klassen hinzuzuf\u00fcgen.<\/p>\n\n\n\n<p>Die Funktion gibt einen Pointer auf die Klasse zur\u00fcck und muss daher noch mit <em>MEM_PtrToInst<\/em> in eine Klasse umgewandelt werden.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Spine_SendMessage<\/h3>\n\n\n\n<p><em>Spine_SendMessage<\/em> sendet eine Nachricht direkt an alle anderen Spieler. Hier muss ein Nachrichten-Pointer \u00fcbergeben werden. Wichtig ist, dass die Nachricht nach dem Aufruf dieser Funktion intern gel\u00f6scht wird und daher nicht mehr benutzt werden darf.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Spine_ReceiveMessage<\/h3>\n\n\n\n<p>Alle Nachrichten, die der aktuelle Spieler von anderen Spielern erh\u00e4lt, werden in Spine der Reihe nach gespeichert und k\u00f6nnen mit <em>Spine_ReceiveMessage<\/em> in der Mod abgeholt werden. Die Nachricht wird beim Aufruf der Funktion aus dem Buffer in Spine entfernt und muss daher direkt verarbeitet werden. Auch hier bekommt man wieder einen Pointer zur\u00fcck.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Spine_DeleteMessage<\/h3>\n\n\n\n<p>Mit <em>Spine_DeleteMessage<\/em> muss jede Nachricht, die \u00fcber <em>Spine_ReceiveMessage<\/em> empfangen wurde, wieder gel\u00f6scht werden. Andernfalls w\u00fcrde sich unreferenzierter Speicher ansammeln und Gothic irgendwann abst\u00fcrzen.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Example<\/h2>\n\n\n\n<p>Um das ganze Konzept etwas klarer darzustellen, soll anhand der Schach-Mod kurz dargestellt werden, wie man die Funktionen richtig nutzt, um einen Multiplayer zu realisieren.<\/p>\n\n\n\n<p>Begonnen wird beim Klick der Dialogoption &#8222;Gegner suchen&#8220; mit einem Aufruf von<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Spine_SearchMatch(2, SPINE_SCORE_1);<\/code><\/pre>\n\n\n\n<p><em>SPINE_SCORE_1<\/em> ist dabei eine Score-Konstante f\u00fcr den Highscore und hat den Wert 0. Nur wird nach einem Match gesucht. In einer sek\u00fcndlichen Schleife wird \u00fcberpr\u00fcft, ob bereits ein Spiel gefunden wurde.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>if (Online_Kampf == 1) \n&amp;&amp; (hero.aivar[AIV_Invincible] == FALSE) \n&amp;&amp; (Match_Running == FALSE) \n{ \n        var int foundMatch; foundMatch = Spine_IsInMatch(); \n \n        BinDran = FALSE; \n \n        if (!foundMatch) { \n                PrintScreen    (\"Warte auf Gegner!\", -1, 90, FONT_SCREEN, 2); \n \n                PrintScreen    (\"Zum Abbrechen oder Spiel beenden \u2019M\u2019 druecken!\", -1, 85, FONT_SCREEN, 2); \n        } else { \n                var string name; name = Spine_GetPlayerUsername(0); \n                if (Hlp_StrCmp(name, username)) { \n                        oppname = Spine_GetPlayerUsername(1); \n                        Online_Host = TRUE; \n                } else { \n                        oppname = name; \n                        Online_Host = FALSE; \n                }; \n                PrintScreen    (ConcatStrings(\"Gegner: \", oppname), -1, 95, FONT_SCREEN, 2); \n \n                Match_Running = TRUE; \n \n                if (Online_Host == TRUE) { \n                        PLAYER_COLOUR = Hlp_Random(2) + 1; \n \n                        var int msgPtr; msgPtr = Spine_CreateMessage(SPINE_MESSAGETYPE_INT); \n                        var Spine_IntMessage sendColorMsg; sendColorMsg = MEM_PtrToInst(msgPtr); \n                        sendColorMsg.userType = MSGTYPE_COLOR; \n \n                        if (PLAYER_COLOUR == COLOUR_WHITE) { \n                                BinDran = TRUE; \n \n                                sendColorMsg.param = 2; \n                        } else { \n                                BinDran = FALSE; \n \n                                Wld_SendUnTrigger      (\"CAM_WHITE\"); \n                                Wld_SendTrigger(\"CAM_BLACK\"); \n \n                                sendColorMsg.param = 1; \n                        }; \n \n                        Spine_SendMessage(msgPtr); \n                } else { \n                        BinDran = 2; \n                }; \n        }; \n};<\/code><\/pre>\n\n\n\n<pre class=\"wp-block-code\"><code>var int foundMatch; foundMatch = Spine_IsInMatch();<\/code><\/pre>\n\n\n\n<p>holt den Status der Suche ab. Wenn <em>foundMatch<\/em> nach diesem Aufruf <em>FALSE<\/em> ist, wird nur eine Ausgabe gemacht, dass weiter nach einem Spiel gesucht wird und die Suche abgebrochen werden kann. Andernfalls jedoch, wird ermittelt, welcher der beiden Spieler Spieler 1 ist. Das ist wichtig, um zu ermitteln, welcher Spieler f\u00fcr Verwaltungsaufgaben genutzt wird. Beispielsweise wird bei der Schach-Mod die Farbe der Spieler einmalig beim Start ausgew\u00fcrfelt. Das Ausw\u00fcrfeln \u00fcbernimmt dabei der Host. Die Ermittlung des Hosts geschieht \u00fcber<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>var string name; name = Spine_GetPlayerUsername(0); \nif (Hlp_StrCmp(name, username)) { \n        oppname = Spine_GetPlayerUsername(1); \n        Online_Host = TRUE; \n} else { \n        oppname = name; \n        Online_Host = FALSE; \n};<\/code><\/pre>\n\n\n\n<p><em>username<\/em> ist dabei eine globale String-Variable, die den Namen des aktuellen Spielers enth\u00e4lt. Dieser wurde \u00fcber <em>Spine_GetCurrentUsername<\/em> abgefragt. Wenn Spieler 0 (der erste in der Liste) gleich dem aktuellen Spielernamen ist, dann ist der Spieler Host und der Gegnername ist bei Index 1. Ansonsten wird der Gegner Host.<\/p>\n\n\n\n<p>Nach einer Ausgabe des Gegnernames kommt nun das Erstellen und Versenden der ersten Nachricht, wenn der aktuelle Spieler der Host ist.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>if (Online_Host == TRUE) { \n        PLAYER_COLOUR = Hlp_Random(2) + 1; \n \n        var int msgPtr; msgPtr = Spine_CreateMessage(SPINE_MESSAGETYPE_INT); \n        var Spine_IntMessage sendColorMsg; sendColorMsg = MEM_PtrToInst(msgPtr); \n        sendColorMsg.userType = MSGTYPE_COLOR; \n \n        if (PLAYER_COLOUR == COLOUR_WHITE) { \n                BinDran = TRUE; \n \n                sendColorMsg.param = 2; \n        } else { \n                BinDran = FALSE; \n \n                Wld_SendUnTrigger      (\"CAM_WHITE\"); \n                Wld_SendTrigger(\"CAM_BLACK\"); \n \n                sendColorMsg.param = 1; \n        }; \n \n        Spine_SendMessage(msgPtr); \n};<\/code><\/pre>\n\n\n\n<p>Zuerst wird in diesem Beispiel die Farbe des aktuellen Spielers ausgew\u00fcrfelt. Dann wird mit<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>var int msgPtr; msgPtr = Spine_CreateMessage(SPINE_MESSAGETYPE_INT);<\/code><\/pre>\n\n\n\n<p>eine Nachricht angelegt, die einen Integer enth\u00e4lt. Daraus wird mit<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>var Spine_IntMessage sendColorMsg; sendColorMsg = MEM_PtrToInst(msgPtr);<\/code><\/pre>\n\n\n\n<p>eine Instanz der Nachrichtenklasse gemacht, damit wir daran nun auch Werte setzen k\u00f6nnen. Da es immer m\u00f6glich ist, dass wir mehrere Nachrichten vom Typ SPINE_MESSAGETYPE_INT verschicken, gibt es noch die Zeile<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sendColorMsg.userType = MSGTYPE_COLOR;<\/code><\/pre>\n\n\n\n<p>Hier wird der userType auf einen f\u00fcr die Schach-Mod definierten Wert gesetzt. In der Schach-Mod gibt es folgende drei Usertypes:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>const int MSGTYPE_UPGRADE = 0; \nconst int MSGTYPE_ZUG = 1; \nconst int MSGTYPE_COLOR = 2;<\/code><\/pre>\n\n\n\n<p>Je nach eigener Farbe wird in der Nachricht dann der Parameter entsprechend gesetzt, entweder auf<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sendColorMsg.param = 1;<\/code><\/pre>\n\n\n\n<p>oder auf<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sendColorMsg.param = 2;<\/code><\/pre>\n\n\n\n<p>Nach dem Bef\u00fcllen der Nachricht muss sie nur noch abgeschickt werden. Das geschieht \u00fcber<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Spine_SendMessage(msgPtr);<\/code><\/pre>\n\n\n\n<p>Wie im Beispiel zu sehen, wird hier noch nichts f\u00fcr den Spieler gemacht, der nicht der Host ist. Dieser muss nat\u00fcrlich die vom Host gesendete Nachricht erhalten und auswerten. Daher wurde er mit <em>BinDran = 2;<\/em> in einen internen Zustand gesetzt, der signalisiert, dass auf die Farbsynchronisation gewartet wird. Dies geschieht wieder in der sek\u00fcndlichen Schleife und sieht folgenderma\u00dfen aus.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>if (Match_Running == TRUE) { \n        if (BinDran == 2) { \n                msg = Spine_ReceiveMessage(); \n \n                if (msg == 0) { \n                        PrintScreen    (\"Warte auf Farbe\", -1, 90, FONT_SCREEN, 2); \n                } else { \n                        var Spine_Message smsg; smsg = MEM_PtrToInst(msg); \n                        if (smsg.userType == MSGTYPE_COLOR) { \n                                var Spine_IntMessage colorMsg; colorMsg = MEM_PtrToInst(msg); \n                                PLAYER_COLOUR = colorMsg.param; \n \n                                if (PLAYER_COLOUR == COLOUR_WHITE) { \n                                        BinDran = TRUE; \n                                } else { \n                                        PLAYER_COLOUR = COLOUR_BLACK; \n \n                                        BinDran = FALSE; \n \n                                        Wld_SendUnTrigger      (\"CAM_WHITE\"); \n                                        Wld_SendTrigger(\"CAM_BLACK\"); \n                                }; \n                        }; \n                        Spine_DeleteMessage(msg); \n                }; \n        }; \n};<\/code><\/pre>\n\n\n\n<p><em>msg = Spine_ReceiveMessage();<\/em> holt die aktuell erste Nachricht ab und speichert sie in der lokalen Integer-Variable <em>msg<\/em>. Wenn noch keine Nachricht angekommen ist, ist msg 0. Ansonsten wird aus dem Pointer eine Instanz der Basisklasse gemacht und in <em>smsg<\/em> gespeichert. Nun kann ganz einfach der userType \u00fcberpr\u00fcft werden. Wenn dieser tats\u00e4chlich <em>MSGTYPE_COLOR<\/em> ist, wird die Nachricht in eine Integer-Instanz der Spine-Nachricht umgewandelt, damit auch ein Zugriff auf den \u00fcbermittelten Parameter m\u00f6glich ist. Dann kann ganz einfach mit <em>PLAYER_COLOUR = colorMsg.param;<\/em> die Farbe des Spielers gesetzt werden. Danach wird noch je nach Farbe entschieden, ob der Spieler nun am Zug ist oder nicht und die Kamera entsprechend umgesetzt.<\/p>\n\n\n\n<p>Wichtig ist noch die letzte Zeile in diesem Zweig, wo mit <em>Spine_DeleteMessage(msg);<\/em> die verarbeitete Nachricht gel\u00f6scht wird, um kein Speicherleck zu verursachen.<\/p>\n\n\n\n<p>Die weiteren Nachrichten funktionieren \u00fcber das gleiche Prinzip.<\/p>\n","protected":false},"excerpt":{"rendered":"<div class=\"entry-summary\">\nVoraussetzungen Ikarus Script-Paket: Thread @ World of Gothic LeGo Script-Paket : Thread @ World of Gothic Spine Script-Paket : Download @ GitHub Tutorial 1 &#8211; Initialisierung Einleitung Dieses Tutorial zeigt auf, wie mithilfe von Spine ein Multiplayer realisiert werden kann.&hellip;\n<\/div>\n<div class=\"link-more\"><a href=\"https:\/\/clockwork-origins.com\/de\/spine-tutorial-5-multiplayer\/\" class=\"more-link\"><span class=\"screen-reader-text\"> &ldquo;Spine Tutorial 5 &#8211; Multiplayer&rdquo;<\/span> weiterlesen\u00a0&hellip;<\/a><\/div>\n","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"iawp_total_views":0,"footnotes":""},"tags":[51,43,42,50],"class_list":["post-959","page","type-page","status-publish","hentry","tag-spine-de","tag-spine","tag-tools","tag-tools-de","entry"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.4 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Spine Tutorial 5 - Multiplayer - Clockwork Origins<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/clockwork-origins.com\/de\/spine-tutorial-5-multiplayer\/\" \/>\n<meta property=\"og:locale\" content=\"de_DE\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Spine Tutorial 5 - Multiplayer - Clockwork Origins\" \/>\n<meta property=\"og:description\" content=\"Voraussetzungen Ikarus Script-Paket: Thread @ World of Gothic LeGo Script-Paket : Thread @ World of Gothic Spine Script-Paket : Download @ GitHub Tutorial 1 &#8211; Initialisierung Einleitung Dieses Tutorial zeigt auf, wie mithilfe von Spine ein Multiplayer realisiert werden kann.&hellip; &ldquo;Spine Tutorial 5 &#8211; Multiplayer&rdquo; weiterlesen\u00a0&hellip;\" \/>\n<meta property=\"og:url\" content=\"https:\/\/clockwork-origins.com\/de\/spine-tutorial-5-multiplayer\/\" \/>\n<meta property=\"og:site_name\" content=\"Clockwork Origins\" \/>\n<meta property=\"article:modified_time\" content=\"2019-11-04T15:33:53+00:00\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Gesch\u00e4tzte Lesezeit\" \/>\n\t<meta name=\"twitter:data1\" content=\"8\u00a0Minuten\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/clockwork-origins.com\\\/de\\\/spine-tutorial-5-multiplayer\\\/\",\"url\":\"https:\\\/\\\/clockwork-origins.com\\\/de\\\/spine-tutorial-5-multiplayer\\\/\",\"name\":\"Spine Tutorial 5 - Multiplayer - Clockwork Origins\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/clockwork-origins.com\\\/#website\"},\"datePublished\":\"2019-11-04T15:22:19+00:00\",\"dateModified\":\"2019-11-04T15:33:53+00:00\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/clockwork-origins.com\\\/de\\\/spine-tutorial-5-multiplayer\\\/#breadcrumb\"},\"inLanguage\":\"de\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/clockwork-origins.com\\\/de\\\/spine-tutorial-5-multiplayer\\\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/clockwork-origins.com\\\/de\\\/spine-tutorial-5-multiplayer\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/clockwork-origins.com\\\/de\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Spine Tutorial 5 &#8211; Multiplayer\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/clockwork-origins.com\\\/#website\",\"url\":\"https:\\\/\\\/clockwork-origins.com\\\/\",\"name\":\"Clockwork Origins\",\"description\":\"\",\"publisher\":{\"@id\":\"https:\\\/\\\/clockwork-origins.com\\\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/clockwork-origins.com\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"de\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/clockwork-origins.com\\\/#organization\",\"name\":\"Clockwork Origins\",\"url\":\"https:\\\/\\\/clockwork-origins.com\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"de\",\"@id\":\"https:\\\/\\\/clockwork-origins.com\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"https:\\\/\\\/clockwork-origins.com\\\/wp-content\\\/uploads\\\/2018\\\/02\\\/cropped-ClockworkOrigins_Icon_256xx-1.png\",\"contentUrl\":\"https:\\\/\\\/clockwork-origins.com\\\/wp-content\\\/uploads\\\/2018\\\/02\\\/cropped-ClockworkOrigins_Icon_256xx-1.png\",\"width\":256,\"height\":256,\"caption\":\"Clockwork Origins\"},\"image\":{\"@id\":\"https:\\\/\\\/clockwork-origins.com\\\/#\\\/schema\\\/logo\\\/image\\\/\"}}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Spine Tutorial 5 - Multiplayer - Clockwork Origins","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/clockwork-origins.com\/de\/spine-tutorial-5-multiplayer\/","og_locale":"de_DE","og_type":"article","og_title":"Spine Tutorial 5 - Multiplayer - Clockwork Origins","og_description":"Voraussetzungen Ikarus Script-Paket: Thread @ World of Gothic LeGo Script-Paket : Thread @ World of Gothic Spine Script-Paket : Download @ GitHub Tutorial 1 &#8211; Initialisierung Einleitung Dieses Tutorial zeigt auf, wie mithilfe von Spine ein Multiplayer realisiert werden kann.&hellip; &ldquo;Spine Tutorial 5 &#8211; Multiplayer&rdquo; weiterlesen\u00a0&hellip;","og_url":"https:\/\/clockwork-origins.com\/de\/spine-tutorial-5-multiplayer\/","og_site_name":"Clockwork Origins","article_modified_time":"2019-11-04T15:33:53+00:00","twitter_card":"summary_large_image","twitter_misc":{"Gesch\u00e4tzte Lesezeit":"8\u00a0Minuten"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/clockwork-origins.com\/de\/spine-tutorial-5-multiplayer\/","url":"https:\/\/clockwork-origins.com\/de\/spine-tutorial-5-multiplayer\/","name":"Spine Tutorial 5 - Multiplayer - Clockwork Origins","isPartOf":{"@id":"https:\/\/clockwork-origins.com\/#website"},"datePublished":"2019-11-04T15:22:19+00:00","dateModified":"2019-11-04T15:33:53+00:00","breadcrumb":{"@id":"https:\/\/clockwork-origins.com\/de\/spine-tutorial-5-multiplayer\/#breadcrumb"},"inLanguage":"de","potentialAction":[{"@type":"ReadAction","target":["https:\/\/clockwork-origins.com\/de\/spine-tutorial-5-multiplayer\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/clockwork-origins.com\/de\/spine-tutorial-5-multiplayer\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/clockwork-origins.com\/de\/"},{"@type":"ListItem","position":2,"name":"Spine Tutorial 5 &#8211; Multiplayer"}]},{"@type":"WebSite","@id":"https:\/\/clockwork-origins.com\/#website","url":"https:\/\/clockwork-origins.com\/","name":"Clockwork Origins","description":"","publisher":{"@id":"https:\/\/clockwork-origins.com\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/clockwork-origins.com\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"de"},{"@type":"Organization","@id":"https:\/\/clockwork-origins.com\/#organization","name":"Clockwork Origins","url":"https:\/\/clockwork-origins.com\/","logo":{"@type":"ImageObject","inLanguage":"de","@id":"https:\/\/clockwork-origins.com\/#\/schema\/logo\/image\/","url":"https:\/\/clockwork-origins.com\/wp-content\/uploads\/2018\/02\/cropped-ClockworkOrigins_Icon_256xx-1.png","contentUrl":"https:\/\/clockwork-origins.com\/wp-content\/uploads\/2018\/02\/cropped-ClockworkOrigins_Icon_256xx-1.png","width":256,"height":256,"caption":"Clockwork Origins"},"image":{"@id":"https:\/\/clockwork-origins.com\/#\/schema\/logo\/image\/"}}]}},"_links":{"self":[{"href":"https:\/\/clockwork-origins.com\/de\/wp-json\/wp\/v2\/pages\/959","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/clockwork-origins.com\/de\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/clockwork-origins.com\/de\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/clockwork-origins.com\/de\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/clockwork-origins.com\/de\/wp-json\/wp\/v2\/comments?post=959"}],"version-history":[{"count":1,"href":"https:\/\/clockwork-origins.com\/de\/wp-json\/wp\/v2\/pages\/959\/revisions"}],"predecessor-version":[{"id":960,"href":"https:\/\/clockwork-origins.com\/de\/wp-json\/wp\/v2\/pages\/959\/revisions\/960"}],"wp:attachment":[{"href":"https:\/\/clockwork-origins.com\/de\/wp-json\/wp\/v2\/media?parent=959"}],"wp:term":[{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/clockwork-origins.com\/de\/wp-json\/wp\/v2\/tags?post=959"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}