CryptoBotWars oder Wie man beschissene Demos erstellt und warum

Warum beschissen? Weil ich Selbstverachtung mag und das Spiel nicht annähernd produktiv ist.

Token, Roboter, Zahlungskanäle und Live-Streams

Also baute ich CryptoBotWars, ein Spiel im Raiden Network.

Willst du es spielen? Weiter lesen…

Werfen Sie einen Blick hinter die Kulissen des Spiels oder sehen Sie sich ein Live-Stream-Beispiel an. Und nehmen Sie an unserem Riot-Chat teil!

Warum? … Ich hatte einige Fragen:

  1. Ist es jetzt einfach, etwas auf Raiden zu bauen? Fehlt etwas, das sich leicht ändern lässt?
  2. Wie würde Raiden im Moment für Eins-zu-Viele- und Viele-zu-Eins-Zahlungen arbeiten? Fälle, die häufig mit Unternehmen zusammenhängen
  3. Würden die Leute in Raiden Fehler finden? Die besten Tester sind die ahnungslosen, neu hinzugekommenen Tester.
  4. Würde sich Raiden bei hohem Durchsatz gut verhalten?
  5. Würden Zahlungen erfolgreich vermittelt (verschiedene Standorte und Systemeinstellungen)?

Ein Spiel, das insbesondere mit einem gewissen Maß an Unterhaltung verbunden ist, kann neue Leute dazu anregen, Raiden auszuprobieren. Umso mehr, wenn Sie einige Belohnungen hinzufügen.

Ein Spiel… oder ein sehr seriöser Dienst, der Off-Chain-Zahlungen akzeptiert , aber ich hatte nicht genug Zeit für Letzteres, also los geht's:

Dark Vader und Blue Yoda. Suppenschüssel & Ping-Pong-Weihnachtsmütze! Sieht großartig aus! … Aus 4m Entfernung

Dieser Blogpost ist zum Teil dem thailändischen Restaurant gewidmet, in dem ich meine Lieblings-Berliner Kokos-Tofu-Gemüsesuppe bekomme. Aus diesem Grund haben wir immer ein paar Schüsseln für die Herstellung von Vader-Helmen und Weihnachtsmützen in der Hand.

Wie ist die Idee entstanden?

Eines Tages diskutierten wir beim Mittagessen über Ideen für den Devcon4 Raiden Network-Workshop und versuchten, eine unterhaltsame und einfache App zu finden, die auf Raiden aufbauen kann. Irgendwie kamen wir zu dem Schluss, dass ein Spiel möglicherweise mehr Menschen dazu anregt, es auszuprobieren.

Ich dachte etwas später darüber nach und entschied, dass ein Spiel mit einer unbegrenzten Anzahl von Benutzern Raiden besser präsentieren könnte, da es den Durchsatz testen würde.

Aber welche Spiele kannst du zwischen einer unendlichen Anzahl von Spielern spielen? Vielleicht etwas, für das man für ein Ergebnis stimmen musste.

Ich erinnerte mich an das Prisoner's Dilemma-Muster, bei dem zwei Spieler versuchen, ihren Verlust zu minimieren, ohne miteinander kommunizieren zu können, aber keine passende Spielvariante für meinen Zweck finden konnten.

Ich ging dann zum Zeichenbrett zurück und stimmte für ein Ergebnis.

Dann wurde mir klar, dass das Einfachste, was Sie tun können, eine Stein-Papier-Schere ist. Zwei Spieler, drei Züge, jeder Benutzer wählt einen Spieler und einen Zug und die Mehrheit pro Spieler entscheidet über den letzten Zug. Dann kann das eigentliche Spiel zwischen den beiden Mehrheitszügen gespielt werden.

Schließlich präsentierte das Team ein unterhaltsames Rennen zwischen Deva und einigen bekannten Personen im Weltraum und kombinierte den Einführungsworkshop mit Devcon-geeigneten Memes (und etwas Aufregung).

Aber ich wollte trotzdem meine Rock-Paper-Scissors-Demo bauen und ETHSingapore schien ein guter Zeitpunkt dafür zu sein! (Dark Vader und Blue Yoda besuchten Singapur, wurden aber aufgrund anderer technischer Probleme, die ich lösen musste, nicht in die Demo aufgenommen )

Roboter wollen Krypto

Du hast ein Spiel, Raiden, warum fügst du der Gleichung eine weitere Variable hinzu?

Und Roboter verursachen große Schmerzen und ich spreche nicht von der Roboter-Apokalypse. Wie Sie sehen, bereite ich mich schon seit einiger Zeit darauf vor, einer der tolerierten Menschen zu werden: uRaiden Devcon3 Robo, Drones wollen auch Krypto

  1. Ich und mein Partner, der das Devcon3 RC Car gebaut hat, mögen Roboter wirklich. Und er hat bereits eine Armee von ihnen ins Haus gebracht ... es ist das wildeste für Leute, die nicht erwachsen werden wollen.
  2. Roboter sind lustig und niedlich ((gegen Meme Duell jetzt!)
  3. Ich setze meine Yoda-Stimme ein! (der Beginn einer weiteren Karriere ..)
  4. Aber eigentlich geben uns Roboter einen Eindruck von der Zukunft .

Wie habe ich angefangen zu bauen?

~ 5,5 Tage reichten aus, um die Erstkonfiguration und die Prototyp-Roboterverbindungen für ETHSingapore durchzuführen.

Dann, während der Winterferien, baute ich das aktuelle Spiel auf dem ersten Prototyp auf.

Das Wichtigste zuerst: Testen des Robot SDK

Mein Partner wusste bereits, dass die Wonder Robots ein Python SDK haben und testete einige der Befehle. Dies war ein guter Zeitpunkt, um Claudiu, einen Freund von uns, mit dem Programmieren vertraut zu machen - was kann mehr Spaß machen, als Roboter zu programmieren? Also tat er es! Er fügte Befehle für das Gewinn / Verlust-Verhalten sowie benutzerdefinierte Soundtracks hinzu.

Spielablauf

Ich hatte bereits einige Ideen geschrieben, wie das Spiel aussehen könnte. Anstatt zu diesem Zeitpunkt die Logikdiagramme des Spiels zu erstellen, bin ich zur Implementierungsphase übergegangen. Dies erwies sich als ein schlechter Schachzug, da es mir "geholfen" hat, einige falsche Entscheidungen zu treffen, da ich nicht das ganze Bild sehen konnte (überarbeitete Spielzustände und Benutzeroberfläche, fehlerhafte Logik des Spielservers bei der Berechnung des Ergebnisses, dieser Exploit-Bug).

Ich habe irgendwann Dinge später behoben und eine bessere logische Abfolge erstellt:

Letzte Komponenten

  1. Dark Vader RobotServer und Blue Yoda RobotServer
  2. GameGuardianServer
  3. GameGuardianRaidenNode
  4. GameClient
  5. Live Stream auf Twitch

2, 3, 4 werden auf einem Digital Ocean VPS gehostet.

Die Roboterserver werden auf zwei Heimcomputern gehostet.

Einer dieser Computer überträgt auch das Live-Streaming über die Webcam. Wir haben viele Live-Stream-Optionen ausprobiert - von den beliebtesten bis hin zu selbst gehosteten und sogar dezentralen Lösungen. Alle hatten jedoch Nachteile (Latenz, Auflösung, dynamische Stream-ID, Zeitaufwand für die Einrichtung usw.).

GameClient-Benutzeroberfläche

Eigentlich habe ich zuerst mit der Benutzeroberfläche angefangen.

Mein Partner schlug vor, denselben Schieberegler zu verwenden, den ich bereits in der Pipeline hatte, und jeden Spielstatus auf einer einzelnen Folie anzuzeigen. Ich fand das eine großartige Idee. Es fühlte sich an wie ein Märchenbuch.

export const GameState = {
    null: 0, // Kein aktuelles Spiel läuft
    offen: 1, // Während des Spiels können Benutzer Züge machen
    closed: 2, // Während der Spielauflösung warten Benutzer auf Ergebnisse und Zahlungen
    gelöst: 3, // Spiel und Auflösung sind beendet.
}

Sie können den Code der Spielstatusansichten hier sehen.

GameGuardianServer

Nachdem ich eine Vorstellung von den Spielzuständen hatte, definierte ich die Spiel- und Bewegungsmodelle, die den MongoDB-Sammlungen der Datenbank entsprechen. Die aktuelle Version finden Sie hier.

Anschließend habe ich die GameGuardian Raiden-API hinzugefügt und die Spielergebnislogik implementiert, um die Gewinner zu berechnen, die Off-Chain-Zahlungen zu senden und die Roboterbewegungen auszulösen. Ausgelöst durch den Code? Machen Sie eine PR, um es zu verbessern!

moves = warte auf moveController.find ({where: {gameId: id}, order: ["_id ASC"]});
raidenPayments = warte darauf.getRaidenPayments (TOKEN)
moves.forEach (sentMove => {
    wenn (
        sentMove.amount &&
        sentMove.move &&
        sentMove.amount> = game.move_amount
    ) {
        raidenPayment = raidenPayments [0] .find ((payment) => {
            return payment.identifier === sentMove.paymentIdentifier;
        });
        if (raidenPayment) {
            total_amount + = sentMove.amount;
            move_count [sentMove.playerId] [sentMove.move] + = 1;
            validMoves.push (sentMove);
        }
    }
});

sortiert_moves_1 = Object.entries (move_count ['1']). sort ((a: any, b: any) => {return a [1] - b [1]});
sortiert_moves_2 = Object.entries (move_count ['2']). sort ((a: any, b: any) => {return a [1] - b [1]});
move1 = sortiert_moves_1 [2] [1]> 0? sortiert_moves_1 [2] [0]: null;
move2 = sortiert_moves_2 [2] [1]> 0? sortiert_moves_2 [2] [0]: RockPaperScissorsGetLoser [move1];
// Wenn wir einen Spieler haben, stellen Sie sicher, dass er gewinnt
if (! move1) {
    move1 = RockPaperScissorsGetLoser [move2];
}
winningMove = RockPaperScissorsGetLoser [move1] === move2? move1: move2;
validMoves.forEach ((move) => {
    // Wir belohnen beide Spieler, wenn ihre letzten Züge gleich sind
    if (move.move === winningMove) {
        winningMoves.push (bewegen);
    }
});
guardian_amount = total_amount / 10;
total_amount - = guardian_amount;
winner_amount = total_amount / winningMoves.length;
gameUpdate = {
        winningMove,
        player1:  {
            Anzahl: sortierte_Züge_1 [0] [1] + sortierte_Züge_1 [1] [1] + sortierte_Züge_1 [2] [1],
            move: move1,
            move_count: move_count ['1'],
        },
        player2:  {
            count: sortiert_moves_2 [0] [1] + sortiert_moves_2 [1] [1] + sortiert_moves_2 [2] [1],
            move: move2,
            move_count: move_count ['2'],
        },
        Menge: winner_amount,
        amountGuardian: guardian_amount,
        Spieler: Moves.Length,
};

this.updateById (id, gameUpdate);
// Raiden-Zahlungen an Gewinner ausführen
winningMoves.forEach ((move) => {
    this.sendRaidenPayment (
        ZEICHEN,
        move.userAddress,
        winner_amount,
        move.paymentIdentifier
    );
});
this.sendRobotCommands (move1, move2, winningMove);

Zeitmanagement: Der Schlüssel zum Erfolg

Oder der Schmerz, Timer auf der Clientseite zu implementieren, die mit dem Server übereinstimmen müssen.

Das Spiel ist zeitlich festgelegt und die Spielzustände sind ebenfalls zeitlich festgelegt. Da ich unendlich viele Benutzer gleichzeitig haben wollte, musste ich die Unterstützung auf jeweils nur ein Spiel beschränken, um die Entwicklung einfach zu halten.

Also, wer startet das Spiel?

Das Einrichten eines Server-Cron-Jobs oder Ähnliches zum regelmäßigen Erstellen von Spielen schien der schlechteste Ansatz zu sein, da hierdurch die Datenbank auf unbrauchbare Weise gefüllt würde.

Ich habe mich für einen Client entschieden, der einen neuen Spielstart auslöst. Kurz gesagt, wenn kein aktuelles Spiel ausgeführt wird, wird eines vom Client erstellt. Wenn dies der Fall ist, werden die Spieldaten an den Client gesendet.

Die Spieldaten enthalten auch die Startzeit des Spiels, zusammen mit gameTime (wie lange dauert der offene Zustand) und resolveTime (wie lange dauert die Auflösung). Der Client verwendet diese Werte, um die Timer hier und hier einzustellen.

Die Timer werden verwendet, um einige der Anforderungen an den GameGuardianServer auszulösen. Wenn beispielsweise der GameOpen-Status beendet ist, sendet der GameClient die rohen Bewegungsdaten. Wenn der GameResolved-Status erreicht ist, wird eine Anfrage an den Server gesendet, um den Spielstatus aufzulösen oder den Auflösungsstatus zurückzugeben, falls er bereits aufgelöst wurde. Dadurch wird der GameGuardianServer dazu veranlasst, die Gewinner zu berechnen, die Off-Chain-Zahlungen zu senden und die Roboterbewegungen auszulösen .

Roboter - letzte Handgriffe

Die Roboterserver werden auf zwei Heimcomputern gehostet. Warum zwei? Weil beide Dash & Cue-Roboter Bluetooth verwenden, um eine Verbindung zum Computer herzustellen. Das aktuelle SDK trennt zuerst alle angeschlossenen Geräte und verbindet dann den entsprechenden Roboter.

Jeder Roboter hat mehrere Routen für: Verbinden mit dem Roboter, Einstellen des Erscheinungsbilds, Bewegen von Sprachbefehlen, Gewinnen / Verlieren von Befehlen. Ich habe mich für Gunicorn entschieden, weil wir den Verbindungsprozess während aller Befehle am Leben erhalten müssen.

Beachten Sie, dass wir die Roboter von Zeit zu Zeit live streamen und dies unser Zuhause in ein seltsames Pantomimenstudio verwandelt hat.

Die Internetverbindung und der Heimrouter haben die Arbeit nicht einfacher gemacht.

Schlussfolgerungen

Haben Sie Interesse geweckt? Probieren Sie das Spiel aus: https://cryptoplayer.one

Chatten Sie mit uns, um Feedback zu geben oder um Hilfe bei der Einrichtung Ihrer Raiden-Kanäle zu bitten, oder rufen Sie uns an, um die Roboter zu wecken! Aufruhr-Chat

Teil 2 kommt bald mit weiteren Schlussfolgerungen und Robotertricks… aber ich muss hier ein paar Klatschen sehen!

Lesen Sie: CryptoBotWars - Teil 2: Schlussfolgerungen