CryptoBotWarsまたはShittyデモの作成方法とその理由

どうしてくだらないの?私は自己廃止が好きで、ゲームは生産に近い場所ではないからです。

トークン、ロボット、支払いチャネル、ライブストリーム

そこで、雷電ネットワークのゲームCryptoBotWarsを作成しました。

プレイしたいですか?読む…

ゲームの舞台裏、またはライブストリームのサンプルをご覧ください。そして、Riotチャットに参加してください!

どうして? …いくつか質問がありました。

  1. 今、雷電の上に何かを構築するのは簡単ですか?かなり簡単に変更できるものが不足していますか?
  2. 1対多および多対1の支払いで、ビジネスに頻繁に関連するケースで、雷電は今どのように機能しますか
  3. 雷電にバグが見つかるでしょうか?最高のテスターは、無知で、新たにオンボードされたテスターです。
  4. 雷電は高いスループットでうまく動作しますか?
  5. 支払いが正常に仲介されますか(さまざまな場所とシステム設定)

特にある程度のエンターテイメントと組み合わせたゲームは、新しい人々に雷電を試してみる誘因になる可能性があります。さらに、報酬を上に追加すると。

ゲーム...またはオフチェーンの支払いを受け入れる非常に深刻なサービス、しかし、私は後者のための十分な時間を持っていなかったので、そこに行きます:

ダークベイダーとブルーヨーダ。スープボウルとピンポンサンタ帽子!素晴らしく見える! …4m離れたところから

このブログ投稿は、私のお気に入りのベルリンのココナッツ豆腐野菜スープgetを手に入れるタイ料理店の一部です。これが、ベイダーヘルメットとサンタ帽子を作るために、常にたくさんの持ち運び用のボウルを持っている理由です。

アイデアはどのようにして生まれましたか?

ある日、昼食を食べながら、Devcon4 Raiden Networkワークショップのアイデアについて話し合い、雷電の上に構築できる楽しくてシンプルなアプリを考えていました。どういうわけか、私たちはゲームがより多くの人々にそれを試そうと誘うかもしれないという結論に達しました。

その後、私はそれについてもう少し考えて、無制限のユーザー数のゲームがスループットをテストするので、雷電をよりよく紹介するかもしれないと決めました。

しかし、無限の数のプレイヤー間でどんなゲームをプレイできますか?たぶん、結果のために投票を必要としたもの。

囚人のジレンマパターンを思い出しました。2人のプレーヤーが互いに通信することなく損失を最小限に抑えようとしますが、目的に合った適切なゲームバリアントを見つけることができませんでした。

それから私は図面に戻り、結果に投票しました。

それから私はあなたができる最も簡単なことはじゃんけんであることに気づきました。 2人のプレーヤー、3つの動き、各ユーザーがプレーヤーと動きを選択し、プレーヤーごとの過半数が最終的な動きを決定します。その後、実際のゲームは、2つの多数決の動きの間でプレイできます。

最終的に、チームはDevaとスペース内の既知の人々との楽しいレースを紹介し、導入ワークショップをDevconに適したミームと興奮と組み合わせました。

しかし、私はまだじゃんけんのデモを作成したかったので、ETHSingaporeはそれを行うのに良い時間のように思えました! (Dark VaderとBlue Yodaはシンガポールを訪問しましたが、他のさまざまな技術的な問題を解決しなければならなかったため、デモには含まれていませんでした)

ロボットには暗号が必要

ゲームがあり、雷電があります。なぜ方程式に別の変数を追加するのですか?

ロボットは大きな痛みを引き起こしますが、私はロボット黙示録について話していません。ご存知のように、私はしばらくの間、忍耐強い人間の一人となる準備をしてきました:uRaiden Devcon3 Robo、ドローンは暗号も欲しい

  1. 私と実際にDevcon3 RCカーを構築したパートナーは、本当にロボットが好きです。そして、彼はすでに彼らの軍隊を家に連れてきました…それは、成長したくない人々のための野生のロボウエストです。
  2. ロボットは楽しくてかわいいです(vs.ミームの決闘!)
  3. 私はヨーダの声を機能させました! (さらに別のキャリアの始まり..)
  4. しかし、実際にはロボットは私たちに未来がどうなるかという感覚を与えてくれます。

どのようにして構築を始めましたか?

ETHSingaporeの初期セットアップとロボットプロトタイプの接続には、約5.5日で十分でした。

その後、冬の休暇中に、最初のプロトタイプの上に現在のゲームを構築しました。

まず最初に:Robot SDKのテスト

私のパートナーは、Wonder RobotsにPython SDKがあることを既に知っていて、いくつかのコマンドをテストしました。これは私たちの友人であるClaudiuをプログラミングに紹介する良い機会でした。ロボットをプログラミングするよりも楽しいことは何ですか?だから彼はやった!彼は、カスタムサウンドトラックとともに、勝ち/負け動作用のコマンドを追加しました。

ゲームの流れ

ゲームがどのように見えるかについて、すでにいくつかのアイデアを書いていました。そこで、この時点で実際にゲームの論理図を作成する代わりに、実装フェーズにジャンプしました。これは悪い動きでした。全体像が見えないために間違った決定を下すのに「助け」になったためです(リファクタリングされたゲームの状態とUI、結果の計算に関するゲームサーバーロジックの誤り、この悪用バグ)。

最終的には後で修正し、より良いロジックシーケンスを作成しました。

最終コンポーネント

  1. Dark Vader RobotServerおよびBlue Yoda RobotServer
  2. GameGuardianServer
  3. GameGuardianRaidenNode
  4. GameClient
  5. Twitchのライブストリーム

2、3、4は、Digital Ocean VPSでホストされています。

ロボットサーバーは、2台のホームコンピューターでホストされています。

これらのコンピューターの1つは、Webカメラを介したライブストリーミングも行います。最も人気のあるものから自己分散型のソリューションまで、多くのライブストリームオプションを試しましたが、すべてに欠点がありました(遅延、解像度、動的ストリームID、セットアップに時間がかかるなど)。

GameClient UI

私は実際に最初にUIから始めました。

私のパートナーは、私が既にPipelineで持っていたものと同じスライダーを使用し、個々のスライドに各ゲームの状態を表示することを提案しました。これは素晴らしいアイデアだと思いました。絵本のように感じました。

export const GameState = {
    null:0、//現在実行中のゲームはありません
    open:1、//ゲーム中、ユーザーは動きをすることができます
    closed:2、//ゲームの解決時に、ユーザーは結果と支払いを待ちます
    解決済み:3、//ゲームと解決が終了しました。
}

ここで、ゲーム状態ビューのコードを見ることができます。

GameGuardianServer

ゲームの状態について考えた後、データベースMongoDBコレクションに対応するゲームの定義とモデルの移動に進みました。現在のバージョンはこちらをご覧ください。

次に、GameGuardian Raiden APIを追加し、ゲーム結果ロジックを実装して、勝者を計算し、オフチェーンの支払いを送信し、ロボットの動きをトリガーしました。コードによってトリガーされましたか?それを改善するためにPRをしてください!

moves = await moveController.find({where:{gameId:id}、order:["_id ASC"]});
raidenPayments = await this.getRaidenPayments(TOKEN)
moves.forEach(sentMove => {
    if(
        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);
        }
    }
});

sort_moves_1 = Object.entries(move_count ['1'])。sort((a:any、b:any)=> {a [1]-b [1]}を返す);
sort_moves_2 = Object.entries(move_count ['2'])。sort((a:any、b:any)=> {a [1]-b [1]}を返す);
move1 = sort_moves_1 [2] [1]> 0? sort_moves_1 [2] [0]:null;
move2 = sort_moves_2 [2] [1]> 0? sort_moves_2 [2] [0]:RockPaperScissorsGetLoser [move1];
//プレーヤーが1人いる場合は、そのプレーヤーが勝利することを確認します
if(!move1){
    move1 = RockPaperScissorsGetLoser [move2];
}
winnerMove = RockPaperScissorsGetLoser [move1] === move2? move1:move2;
validMoves.forEach((move)=> {
    //最終的な動きが同じ場合、両方のプレイヤーに報酬を与えます
    if(move.move === winnerMove){
        winnerMoves.push(move);
    }
});
guardian_amount = total_amount / 10;
total_amount-= guardian_amount;
winner_amount = total_amount / winingMoves.length;
gameUpdate = {
        winnerMove、
        player1: {
            カウント:sorted_moves_1 [0] [1] + sorted_moves_1 [1] [1] + sorted_moves_1 [2] [1]、
            移動:move1
            move_count:move_count ['1']、
        }、
        player2: {
            カウント:sorted_moves_2 [0] [1] + sorted_moves_2 [1] [1] + sorted_moves_2 [2] [1]、
            移動:move2
            move_count:move_count ['2']、
        }、
        金額:winner_amount、
        amountGuardian:guardian_amount、
        プレイヤー:moves.length、
};

this.updateById(id、gameUpdate);
//勝者への雷電支払い
winnerMoves.forEach((move)=> {
    this.sendRaidenPayment(
        トークン、
        move.userAddress、
        winner_amount、
        move.paymentIdentifier
    );
});
this.sendRobotCommands(move1、move2、winningMove);

時間管理:成功への鍵

または、クライアント側でタイマーを実装する際の苦痛は、サーバーと一致しなければなりません。

ゲームのタイミングが調整され、ゲームの状態もタイミングが調整されます。同時ユーザーの数を無制限にすることを選択したため、開発を簡単にするために、一度に1つのゲームのみにサポートを制限する必要がありました。

だから、誰がゲームを始めますか?

サーバーcronジョブなどを設定して定期的にゲームを作成するのは、無駄な方法でデータベースがいっぱいになるため、最悪のアプローチのようです。

クライアントが新しいゲームの開始をトリガーすることを選択しました。要するに、現在実行中のゲームがない場合は、クライアントによって作成されます。存在する場合、ゲームデータがクライアントに送信されます。

ゲームデータには、ゲームのstartTime、gameTime(open状態が続く時間)およびresolveTime(解像度が続く時間)も含まれます。クライアントはこれらの値を使用して、こことここでタイマーを設定します。

タイマーは、GameGuardianServerへのリクエストの一部をトリガーするために使用されます。たとえば、GameOpen状態が終了すると、GameClientは生の移動データを送信します。または、GameResolved状態に達すると、要求がサーバーに送信されてゲームの状態を解決するか、既に解決されている場合は解決状態を返し、GameGuardianServerをトリガーして勝者を計算し、オフチェーンの支払いを送信し、ロボットの動きをトリガーします。

ロボット—最後の仕上げ

ロボットサーバーは、2台のホームコンピューターでホストされています。なぜ2つ? DashとCueの両方のロボットがBluetoothを使用してコンピューターに接続しているためです。現在のSDKは、最初に接続されているすべてのデバイスを切断してから、適切なロボットを接続します。

各ロボットには、ロボットへの接続、外観の設定、音声コマンドの移動、勝ち/負けコマンドのための複数のルートがあります。すべてのコマンドで接続プロセスを維持する必要があるため、Gunicornの使用を選択しました。

私たちは時々ロボットをライブストリーミングし、これが奇妙なmime studioの私たちの家を変えたことに注意してください。

インターネット接続とホームルーターが仕事を簡単にしませんでした。

結論

興味を起こさせましたか?ゲームを試してください:https://cryptoplayer.one

私たちとチャットしてフィードバックを送ったり、雷電チャンネルの設定やロボットの目覚めのために私たちにpingを送ってください!暴動チャット

パート2では、さらなる結論とロボットトリックが近日公開されますが、ここで拍手が必要です。

読む:CryptoBotWars —パート2:結論