ボクセルグラフィックスとVRを使用してHighload ++用のゲームを作成した方法

実際、これは技術的に長引く軽いものです。本を読んだ後、何らかのゲームを作成することにさらに興味を持つか、少なくともその仕組みを学ぶことを期待します。







スピーカーについて: Alexander Khayorov( @allexx )は、 Ingram Micro Cloudの開発部門を率いています。 アレクサンダーのチームのメンバーは、優れたエンジニアだけでなく、優れたボクセルジェダイチーム、最適化ウィザード、3Dの達人、ビッグデータの大君だと自負しています。 [注:LinkedInおよびMediumの役職に似ています]



Highload ++ 2017でのパフォーマンスの準備をしているこのクールなチームは、観客を楽しませ、スタンドのために新しくて面白いことをすることにしました。 したがって、彼らはゲームを撮影しましたが、その作成についてはさらに議論します。



ホステスへの注意:主催者側では、会議への参加に備える努力を大いに歓迎します。 彼らは何度も報い、参加者を引き付け、そして結局のところ、チームに利益をもたらします。



さあ、行こう!







多くの場合、メールを分類するとき、さまざまなニュースがフラッシュするニュースフィードの見出しを調べます。 「Who are the Indie Developers」という見出しを見たら、 何らかの理由で、彼は私を夢中にさせ、私はこの記事を読むことにしました。 私はそれを開いた-数字、文字、統計がたくさんありました。



参考:独立系開発者とは、特別な予算やコンピューターゲームの出版社からの財政的支援なしでゲームを作成する人々です。



原則として、インディーズ開発者はスクリプトとテンプレートの範囲に負担をかけられないため、かなり面白いゲーム、映画などを手に入れることができます。



この記事では、いくつかの面白い事実を見つけました。











偶然にも私たちはゲームを作り始めました。



なぜゲームを作り始めたのですか



私はいつもRedditサービスのゲームが好きでした。 私は思う、そしてあなたはあなたの人生の1ヶ月以上をこのリソースに費やした。



Redditによる社会実験



毎年、Redditは社会実験を行っています。 実際には、これらはコミュニティ向けのさまざまなゲームです。 2017年には、いつものように4月上旬(フールの日)に社会実験が行われました。







ゲームの本質は有望でした。 Reddit開発者は1,000 x 1,000ピクセルの画像を作成しました。 Redditに登録されている各ユーザー(数百万人)には、このキャンバスの1ピクセルをかなり広いパレットの1色でペイントするよう提案されました。



イベントは72時間続き、各参加者は5分ごとに画面上に1点しか描画できませんでした。 人々は異なる絵を作成し、彼ら自身の間で戦い、ピクセルを再描画しました。 いくつかの国と地域社会が集まり、一緒に働きました。



その結果、面白いパネルが出てきて、そこから誰かがパズルを作り、誰かがそのような飾りで靴下をつなぎました。



シンプルなゲームプレーヤーでも、 人々を大規模なオンラインゲームに引き込むことができるというアイデアが本当に気に入りました。 これはおそらく、オンラインゲームを作成するための主なインスピレーションでした。 一般に、ゲームは楽しいものでいっぱいだと思うし、あなたは時々異なるゲームをプレイし、それがあなたに喜びをもたらすと確信しています。



しかし、技術者にとって最も興味深いものは内部にありました。なぜなら、ゲームには膨大な数の人々が集まりました-100万人以上の登録ユニークユーザーが参加しました-毎秒最大9万人が同時にピクセルをペイントしました!



専門的には、サーバーがサーバーと通信するときにWebサービスとさまざまなM2Mサービスを開発します。 これは実際には非常に重要で責任がありますが、時には少し退屈です。 したがって、 新しい開発経験は常に興味深いものです。 今すぐ共有します。



今後は、最初から何も経験することなく、このゲームについて多くの新しく興味深いことを学びました。



ゲーム



特徴



みんなと一緒になって、ゲームをどうするかについてのアイデアの骨組みをスケッチしました。 最初に、切り札を使用して、クールな機能を作成することにしました。





ゲームはネットワーク化され 、さらには巨大であり、分割画面形式ではないことを決定しました。





経験のない2Dを作成する方がおそらく簡単ですが、チームはボリュームを望んでいました。





過大評価され、移転された技術がなければ、ゲームを成功させることは不可能だと理解しました。



そこで、機能セットを作成しましたが、特定のゲームプレイはありませんでした。



譲歩



しかし、約1週間後、ウィッシュリストを何らかの形で制限する必要があると判断し、わずかな妥協を行いました。









ヘルプ:ボクセルはほぼピクセルですが、3次元の世界です。 たとえば、Minecraftでは、世界はボクセルで表されます。









私たちはしばらくこれに別れ、将来、特にゲームプレイとルールについて議論するために、ビジネスについてのみ話すことにしました。



ゲームプレイとルール



ゲームプレイは非常に単純なもののようです! StarCraft、Doom、Quackのプレイ方法はよく知っています。 しかし、ゲームを作成するときには、膨大な数のアイデアがあります。 これらの考えはさまざまな方向に散在しており、ゲームがどのように見え、何が起こるかについて合意することは非常に困難です(特にチーム内)。



このプロセスは私たちにとって線形ではなく、すぐにすべてを決定することはできませんでした。 ルールの最終バージョンは非常にシンプルに見えます。











これに関して、すべての管理機能を決定し、アーキテクチャを実行することを決定しました。



建築



エンタープライズ製品を作成しているので、ゲームのエンタープライズアーキテクチャから始めることにしました。 私たちは間違いなく以下を含むべきだと考えました:



  1. プレーヤー
  2. 仮想現実のヘルメットで遊ぶための特別なスタンド
  3. ブラウザ 、ブラウザゲームになると判断したため。 人々はそこに来てそこからデータを受け取ります。
  4. ある種のストレージ 」-ネットワーク上にマルチプレイヤーゲームがあるため、別のプレイヤーに関するデータをどこかに保存する必要があります。


これは、オリジナルの、かなり素朴なアーキテクチャスキームでした。







分散システムでのレプリケーションの問題



「ストレージ」はブラウザとどのように通信する必要がありますか?ゲームはどこで機能しますか? ここから面白い瞬間が始まります。私はあなたをもっと身近な地域に連れていきたいです。



一般に、分散システムでのレプリケーションの問題はよく理解されています。 レプリケーションは業界で毎日使用されています。 しかし、ゲーム、特にネットワーク化されたゲームは、ゲームの発生時にのみ複製を保証する必要がある場合、複製の非典型的な状況です。 分散システムのプレイヤー間の複製と接続性、一貫性がない場合、ゲームをプレイすることは不可能であるため、ゲームを完了することができます。







2種類のレプリケーションが区別されます。



  1. たとえば、あるクライアントからデータを直接取得して他のすべてのプレーヤーに送信する場合、プレーヤーがフラグをキャプチャしたという情報が送信されます。 他のクライアントでは、まったく同じアニメーション、同じイベントなどが発生します。
  2. パッシブレプリケーション 。この場合、プレーヤーはサーバーに情報を送信し、このサーバーは既に他のすべてのプレーヤーにデータ転送を提供します。


ここで塩が何であるか、何が良い、悪いか、アクティブレプリケーションとパッシブレプリケーションの間に違いがあるかどうかを把握してみましょう。



アクティブレプリケーションの長所と短所:



+アクティブレプリケーションでは、すべてがシンプルで直感的です。データを取得し、他のすべてのプレーヤーに送信し、他のすべてのプレーヤーから情報を取得します。



+ 2番目の重要な点-このシステムは非常に効果的です。 実際、他のプレイヤーとデータを受信、処理、送信するサーバー形式の追加デバイスは必要ありません。



-しかし、巨大なマイナスがあります-アクティブレプリケーション上に構築されたシステムは非常に脆弱です。 損失、遅延、顧客との困難などのネットワークの問題の発生は十分であり、完全に一貫性のないシステムであることがわかります。 同期が壊れ、私たちの仕事は同じ共通世界を持つことです。



実際、同期が壊れている状況から抜け出すことは簡単ではありません。 これにはさまざまなプロトコル、たとえばPaxosがありますが、それらはすべて、アクティブレプリケーションの単純なスキームを感知できないほど複雑にし、時間と計算リソースを必要とします。



たとえば、古典的なStarCraftゲームはアクティブレプリケーションに基づいていると言えます。 これは、シンプルでありながらもろいモデルを使用する明確な例の1つです。 そのため、同期で特定の問題が発生した場合、原則としてゲームを完了して再起動する必要があります。



パッシブレプリケーションの長所と短所:



+アクティブとは異なり、パッシブレプリケーションは非同期化に対して非常に抵抗力があります。 何かがうまくいかない場合、特別なデバイスがあります-システムを正常に戻すことができるサーバー。



+ 2番目のポイントは、多くの場合非常に過小評価されており、重要です。ゲームの安全性です 。 最近、 Vdpixel Battleゲームが登場しました-RedditのPlaceゲームに直接類似しており、ボードをペイントすることもできました。 このゲームは数時間にわたってハッキングされました( ソース )。 パッシブモデルでは、多くのことを制御できるサーバーがあるという理由で、ゲームのセキュリティを提供するのが非常に簡単です。



-しかし、マイナスのないプラスはありません。 データの送受信を行うサーバーであるサーバーの出現により、古典的な障害点が発生します。 シャーディング、ノードへの分離などの特別なツールを使用しない場合、サーバーをクラッシュさせることでゲーム全体を失う可能性があります。



私たちは長く考えなかったし、すべての現代のゲームの開発者のように、複製の受動的な方法を選びました。 実際、今ではゲームの大部分(約99%)がパッシブレプリケーションを使用しています。 そのため、強力なエンタープライズアーキテクチャに別の強力なコンポーネントが登場しました。ゲームバックエンドは、同期のタスクを引き受けます。







データ構造



ストレージシステムについて少し話しましょう。 実際のところ、一部のサークルでは慣習的であるように、ストレージの選択に依存しているということです。



データを保存する場所を理解するには、データの表示方法を知る必要があります。 これはおそらく、特定の基準を定義する最も重要な問題です。 ゲームで可能なデータ構造を考慮してください。







ボクセルが多く、世界は限られています。 キューブ(ボクセル)に関するすべての情報を取得し、通常の線形の大きな配列に格納できます。 これは非常にシンプルで簡単な方法です。 その主な利点は、セルへの継続的な書き込みと読み取りです。 ボクセルに関する情報を安全に取得でき、一定の時間がかかります。



実際、Minecraftを含む多くの現代のゲームは、まさにそのようなモデルから始まり、非常に成功していることが証明されました。



ここでの欠点は、 大量のメモリ消費です。 実際、私たちの世界は3次元で成長しているため、このデータを格納するために必要なメモリ量は非線形に増加します。



この問題は、たとえばoctree treeを使用して解決できます。 私たちはそれが何であるかに入るつもりはありません、私はちょうど絵を見て理解することを提案します。







3次元の世界が大きな立方体の形で表示される場合、8つの部分に分割できます-okta。 それぞれを8つのセクションに分割することもできます。 このメカニズムにより、データのない領域のためにストレージ構造を大幅に節約できます。



明確なプラスがあります-これは、 ストレージの観点からより好ましい構造です。 マイナスは最初はそれほど明白ではありませんが、実際にはすぐに消えます。 事実、異なるキャッシュを使用する必要があるということです。 原則として、octreeを使用するすべての人は、octreeが通常の配列よりも著しく動作が遅いと文句を言います。







最後に、3番目のオプションがあります。これを妥協と呼びます。通常の線形配列を使用して、一定の領域(チャンク)に分割できます。 これにはいくつかの利点があります。 たとえば、通常の配列とは異なり、個々のブロックをロードできます。 1人のユーザーの全世界をダウンロードする必要はありません。 そこから来るブロックのみをロードできます。



しかし、マイナス点があります-もちろんチャンクへのリンクを保存したり、チャンクを操作したり、ゲームのフロントエンドにロジックを追加したりする必要があるため、これは通常の配列のモデル全体を複雑にします。



私たちのゲームでは、最後のオプションが最適であると判断し、それを選択しました。 その後、私たちのストレージの選択は気付かれませんでした:私たちは決めました-MongoDBにします。 私は今、このトピックでホリバーを繁殖させたくありません-他の多くの優れたデータベースでもこれを実装できると確信しています。 ただし、このベースを使用した経験はほとんどなかったため、実験のためにこのベースを使用することにしました。



フロントエンドとバックエンド間の相互作用のプロトコル



特定の構造があり、クライアントが存在します。おそらく、すべてが表示されるブラウザが表示されます。 しかし、ストレージとゲームの間でデータを転送する方法は? プロトコルについて考える時が来ました。



すでに知っているように、私たちの世界は、ベースが1000×1000、高さが200の平行六面体の形で表示されます。高さは無視して、アンロード時に常に最大の高さを使用できます。 これにより、ゲームの作成が大幅に簡素化されます。



同様に、各正方形は標準に従って、内部で32×32ボクセルの塊に分割しました。



先ほど言ったように、MongoDBを使用することにしました。 ボクセルは非常に簡単に格納されます。これには通常のドキュメントを使用します。 文書の内部は次のスライドのようになります。









現在、少なくとも2つのタスクがあります。 たとえば、プレーヤーを監督します。 彼はある時点で世界で生まれました。



  1. プレイヤーが見ることができる最も近いチャンクを決定し 、半径を形成します。 実際、これは完全に正しい名前ではありません。 距離の理解を形成し、それが影響するチャンクの数を確認します。 次に、データベースへのgetリクエストを作成します。このリクエストでは、プレーヤーの現在の座標とこの半径を指定します。
  2. セット -マップ上のブロックまたはキューブを作成します。 設定するキューブの座標を送信するだけで十分です。


これらは、リポジトリへの直接リクエストです。



逆の方向では、他のキューブを更新する要求を監視できます。







この場合、世界にいて初期状態の一部を受け取ったという事実について話しているのは、他のユーザーが作成する新しいキューブを観察したいということです。 これを行うために、イベントにサブスクライブし、ゲームに表示されるすべてのサイコロに関する更新されたメッセージを受け取ります。



最後に、ゲームに少しインタラクティブ性を追加したかったので、ユーザーのアクティビティに関する特別なメッセージを追加しました-誰かがゲームに入ったとき、外出したとき、またはポイントを獲得できるフラグを傍受したときです。



そこで、相互作用のプロトコルを作成しました。



バックエンドとフロントエンド間で通信する方法について、HTTP、WebSocket、HTTP2の小さな選択がありました。 明白な理由で、可能性のある潜在的な遅延を直感的に減らすために、 WebSocketで停止することにしました。



また、ゲームの結果を取得するのは良いことだと考えました。たとえば、誰がゲームに参加したか、どのポイントを獲得したかを確認することです。 これを行うために、別の「ビュー」を作成しました。これをフロントエンドに固定し、HTTPを使用して、許可せず、このプロセスを複雑にしないようにしました。



そのため、アーキテクチャに特定のスタックを形成しました。 相互作用の重要なポイントはWebSocketでした。



ゲームバックエンド



少なくとも、バックエンドはシステムの心臓部と言えます。









そこで、完全に伝統的なスタックを得て、

指定されたプロトコルに従ってデータを交換します。



ゲームフロントエンド



これが私たちのゲームのハイライトです-ゲームが生きて存在し始める方法です。



まず、ゲームエンジンの作成方法、ゲームの一般的な作成方法、およびそれがどのように機能するかという質問がありました。 素材の短い研究の後、多くを可能にするWebGLライブラリがあることに気付きました。 OpenGLライブラリで動作します。OpenGLライブラリは、すでに機器、ドライバー、ビデオカードなどで動作しています。



したがって、最初の考えは、通常のネイティブJavaScriptを使用して、どのAPIがWebGLを提供するかを確認し、ゲームの作成を開始することでした。 Web開発の経験から、Webサーバー自体の開発は非常に奇妙で長い間行われていることがわかったため、私たちはこの考えをすぐに却下しました 。 また、あまり時間がありませんでした。



短い検索の後、 Voxel.jsというJSライブラリが見つかりました。 実際、それは非常に多くのツールを表しているため、私たちにとって聖杯になっています。







ライブラリは3年以上存在し、著者が主張するように、実際には、最新のブラウザーゲームとボクセルゲームを作成するためのツールキットです。 必要なものがすべて含まれています。





スタック全体の様子









実際、three.jsを使用したシーン、特にそれを使用するVoxel.jsを使用したシーンの作成はそれほど簡単ではありません。 長い目で見れば複雑なことは何もないように見えますが。



コードを見てみましょうが、事前に怖がることはありません。







ブラウザーでクールな3D画像を作成するには、本当に3〜4個のものが必要です。



  1. まず、普通の世界のように、 シーンが必要です。
  2. このシーンにはカメラが必要です。カメラオブジェクトを作成し、その中に表示される寸法と最大/最小距離を指定します。
  3. その後、レンダリングするデバイスが必要です-シーンのカメラ用に見たいものを作成します。 これを行うには、 renderを作成します 。 この場合、WebGLテクノロジが使用されており、ビデオカードは世界を作成するために機能します。


基本的に、ゲームが機能するためのすべてが揃っています。 唯一のものは、いくつかのオブジェクトがありません。



4.オブジェクトを作成するには、次のものが必要です。





ジオメトリとマテリアルを組み合わせることで、いわゆるメッシュ(またはある種のオブジェクトメッシュ)が得られます。



次に、単純なアニメーション関数が呼び出されます。 ブラウザのsetIntervalと同様に、新しいフレームを描画するたびにアニメーションが表示されます。 実際、このメカニズムは通常の3Dゲームで使用され、ブラウザーで使用できます。



バーチャルリアリティ



VRについて少しお話ししたいと思います。 私が言ったように、私たちは注目を集めるためにハイテク技術を使いたかったのです。 VRを使用することにしました。 これはランダムで自然発生的な選択でしたが、このトピックを研究した結果、VRはそれほど新しくも誇大広告の技術でもないことがわかりました。 この写真は20世紀初頭のものです。VRですが、20世紀のものです!







このヘルメットを使用して、実際の3Dオブジェクトを表示する必要があります-これは静的なものだけです。







オクルスの裂け目



静止画像を使用せずに、ビデオでグラフィックを作成することにしました。 そのため、 Oculus Riftを選択しました。







繰り返しますが、選択は非常に直感的で自発的でした。 Oculus Riftは少なくとも3つの基本的なデバイスで表されます。



  1. ヘルメット;
  2. 追跡、つまり頭部の動きを理解するための特別なデバイスで、本来補助的です(左)。
  3. コントローラー-さまざまな方法で表すことができるコマンドのソース

    デバイス。


VRテクノロジーとOculusヘルメットに関係する人はいませんでした。







長所:



+これは本当にVRの絵です-それは非常に現実的であり、あなたは私たちの脳を欺いて、私たちが3Dの世界にいると想像することができます。



+良好な画面解像度と非常にまともな画像リフレッシュレート。 仮想現実の最初の古いヘルメットとは異なり、私は個人的に、写真を見ながら私の幸福度の顕著な悪化を観察しませんでした。



+これは実際に非常に便利なデバイスで、手にぴったりとフィットし、頭にぴったりとフィットするように作られています。 これは本当に消費者向けデバイスだと言えます。



短所:



-VRを想像して、ヘルメットやデバイスを装着するだけでクールになります! 実際、これは膨大な数のワイヤです。 実際、各デバイスには1本または2本のケーブルが必要です。



-私にとって2番目の重要な瞬間とわずかな失望-私はいつものラップトップを持ってソファに座ってプログラムできると思っていました。 重大な制限があることが判明しました。Windows、Oculusのみを使用でき、SDKはmacOS / Linuxでは使用できません。 おそらく、これは会社の戦略またはオペレーティングシステムの機能です。私には言いにくいです。



-十分なビデオカードを接続しないと、VRで簡単なビデオやゲームを起動することさえできませんでした。 私は現代の3Dゲームの熱心なゲーマーではないため、開発を開始するためにそれを探す必要がありました。



これらの不利な点に恥ずかしくないのであれば、仮想現実の現代のヘルメットを安全に試すことができると思います。



VRゲームの作り方



私たちにとって、このトピックは完全に閉じられており、理解できません。 ガジェットや学位など、特別な魔法が必要だと考えました。 そうでもない。



Aフレーム



現在、ブラウザでもVRゲームを作成できるツールは多くありません。







おそらく、インターネットで最初に見つけることができるのは、A-Frameフレームワークです。 .



, , Oculus Rift, . , , .



, , , web-, , HTML. , — , 3D VR- .



, html-. , .



, . , . , . 3D- .. , .



VR.



— VR? VR . . . , VR-. , , . .



, . . .







enterprise-, , :



  1. Voxel.js.
  2. — A-Frame.


, ,

, . Firebase, .



最適化



.







, , . , .



1. Pre-process voxel models



, , PowerPoint. , , , .



, , . , : « , ? !»



, , , , . — 78% .



2. User Mesher



mesher. , , , . , Minecraft , -.



, ( Mesh). mesher. , , , . , , , - , , .



, mesher . c Voxel.js FPC . A-Frame , mesher .



3. Enable compression for WebSocket (RFC 7692)



, web-. WebSocket — , , .



( JSON) . . — ?



WebSocket, HTTP. , , , RFC , , WebSocket.



, . — 5 MB 1,8 MB .



, — , Chrome, Firefox, Safari — . , .



, , . — , , , , , .



- ! , , .



, コードベース、私たちはそれをオープンにしました。私たちがどのようにゲームを開発したか、それが何であるかを観察し、サーバーと2つのバージョンを含むゲームのコピーを問題なく起動できます-VR用とブラウザ専用です。



ちなみに、RIT ++ 2018では、CloudPipesと呼ばれる論理ゲームPipesのリメイクを準備しています。



論文を再確認し、会議、特に私たちの会議への参加は楽しいです!



スケジュール祭りのプレゼンテーション、mitapami、クイズや「何の?どこ?いつ?準備はできていますが、チケットを入手するチャンスはまだあります



また、わずか1か月後のHighload ++ Siberia忘れてください




All Articles