おもちゃバコ

中身スカスカ♡

「オンラインゲームを支える技術-壮大なプレイ空間の舞台裏-」を読んだ

こんにちはちみつ

「オンラインゲームを支える技術-壮大なプレイ空間の舞台裏-」を読んだ感想です.


Amazon


内容

オンラインゲーム開発の技術について,ネットワークの歴史や次世代プラットフォーム,ソケット通信などを一通り解説してます.

技術だけでなく,チート業者の目的やその対策,ハードウェアの歴史を踏まえたネットワークプログラミングについてなど,ネットワークを扱うゲームについて色々な視点から解説されているため,ネットワーク関連の業務に携わる人なら楽しく読み進められると思います.

対象

・オンラインゲーム開発を行う新人さん
・ネットワークプログラミングに興味のある人
ゲームプログラマ

個人的な感想ですが,ネットワーク関連について結構深いところに踏み込んでいるため,ネットワーク関連の書籍としては入門書と専門書の間ぐらいの内容だと思います.

ネットワークについてそこそこの知識が必要になると感じました.


要約

第0章 [速習]オンラインゲームプログラミング

ネットワークプログラミングの基礎

・インターネットプログラミングの歴史について
 TCPRFCなど.
TCPUDP
 送受信の順番・正確性を保証: TCP
 ↑が必要ないとき: UDP
・オンラインゲームではUDP
 基本はUDPで必要な時にTCP
・レイヤ5(OSI)以上はゲームごとに実装
・「UNIXネットワークプログラミング」はイイゾ
・オンラインゲームではコネクション指向のTCPを使用

ソケットプログラミング入門

・ソケットAPI
 ECHOサーバ
・同期的な呼び出しにはスレッドを使用
・オンラインゲームではC/C++が主流
 次いでJavaなど
 軽量言語としてlua, squirrelなどがある
・サーバの効率化
 C/C++は開発コストが高いのでGCがるC#Javaが使いたい.
 -> 開発サイクルは改善するが性能を犠牲に...
JavaC言語
 100MBのファイルを読むとき,Javaシステムコール前後で例外処理などを行う.
 Cのほうが約10倍ぐらい早い.

RPCの攻略

RPC: 通信に関する細かい面倒をラップし,通常の関数呼び出しと同様にホストと通信できる仕組み.
UDPの使用目的
 到達速度>信頼性の時
  FPSなど
 NATトラバーサル機能を実装する

ゲームプログラミングの基礎

・インベーダゲーム
 初期化,無限ループ,Sprite,描画
・タスクシステム
 「ミサイル1つを1フレーム進める」など,細かい単位の処理を1つの関数として定義し,ミサイル数だけ1フレーム内に順番に全て呼び出す.
・ゲームプログラミングとネットワークプログラミングの違い
 ネットワーク:全ソケットに対してselect()でポーリングし,コールバック関数を呼び出して少しずつ動作.
 ゲーム:すべての可動物に対して舞フレームポーリングし,コールバック関数を呼び出して少しずつ動作.

開発効率とプラットフォーム間の移植性の確保

・要望
 本番サーバはLinux,開発環境はWindows(VS)で開発
 サーバとクライアントで衝突判定など,同じ処理コードを使用したい
  ・C/C++/Javaの選択.
  ・ラッパでソースレベルで互換性を保つ
・ラッパの仕事
 メモリ管理:mallocは全システムで使用可能なので比較的簡単.
 ソケットAPI:WindowとUNIXではAPI仕様が違うので一通りラップする.
 スレッド:pthreadなど
 シグナル:移植性の低い方法なのでお勧めしない.
 イベント・タイマ:libeventで楽にラップ可能.
POSIX標準に近いインタフェースになるようラップすると全体の作業量が減り,楽.

オンラインゲームの歴史と進化

オンラインゲームの技術史

・1983年
 P2Pタイプのネットワーク対戦ゲームSnipesが登場
 NESのマリオやゼルダが出たころ
・1989年
 CERNにおいて,HTMLと世界初のブラウザWorldWideWebが開発される.
 1989年後半でインターネット接続ホストは約30万台.
・1990年
 SNESメガドライブ用に電話回線を使用するネットワーク対戦ゲームXBANDが登場.
  帯域速度・パケット遅延の影響で失敗に終わる.
 MMORPGでは「Meridian50」が成功.
・2000年代前半
 FF,信長の野望など,有名タイトルがオンライン化.
 NTTドコモiアプリ以降,携帯電話でもオンラインゲームが普及したがパケット代金が社会問題化した.
・2000年後半
 WebブラウザベースのMMOGの成功.
 World of Warcraftが1人用ゲームデザインで約1200万人以上の大ヒット.
 マシン性能向上によるトランザクション処理の高速化などにより課金モデルが進化.
 WiiPS3, Xbox360など,LAN接続機能が標準搭載される.

技術遍歴から見えてくるゲーム文化/経済圏

・文化圏
 ハッカー,コンソル・アーケードビジネス,Microsoftの3つの文化圏が生まれる.
 日本の会社は,自身の知識やソースコードを公開することに消極的でないため,技術レベルが衰退してしまいそう.
  CEDECの誕生.

Column

・売れるオンラインゲームプログラマの条件
 1.ゲームが好き
 2.プログラミング・実作業が好き

オンラインゲームとは何か?

「オンラインゲーム」の用語の定義

・物理的な側面
 コンピュータ
  クライアント機器:PC,家庭用ゲーム機,携帯電話,PDAなど
  サーバ機器:データセンタにあるサーバ
  ロードバランサ
 ネットワーク
  インターネットプロトコル
  ローカルエリアの物理ネットワーク:RS-232,MIDI,USBなど

オンラインゲームの概念的な側面

・概念的な側面
 ゲームプレイの基本
  認知・判断・操作の繰り返し.
 ゲームの進行
  同じゲーム進行を共有する.

オンラインゲームのビジネスとしての側面

・ビジネス的な側面
 おもしろくしたい,素早く・安く完成したい,長く・安く運営したいなど
 テストプレイヤを効果的に集めたい
  オフラインゲームよりデバッグが難しい.
  オープンベータテスト
 頻繁に更新したい
  定期パッチ,大規模パッチ,緊急メンテなど
 攻撃者を安く・素早く・確実に排除したい
  RMT業者,botの排除など
・オンラインゲームを支える技術の大区分
 C/S型とP2P
 MMO型とMO型
・ゲーム本体を支える3つの軸
 データ形式,通信形式,反応速度(レイテンシ)

開発コストを左右する技術的ポイント

データ形式
 disposable: ゲーム内容を毎回初期化して捨てる
  MO型
 persistent: ゲーム内容が永続的にサーバ側に存在
  MMO型
・通信形式
 P2P: 中央サーバが存在しない端末間直接通信方式
 C/S: クライアント・サーバ間のみ通信するスター型通信方式
・反応速度
 ゲームサイクルに大きくかかわる.
 特に,認知と認知の間の時間0.0167秒(1フレーム)を意識すること.
・ネットワーク遅延の3パターン
 25m: 格ゲーなど
 100m: FPSやストラテジーなど
 300m: MMORPGなど

オンラインゲームのアーキテクチャ

ゲームプログラムの特性

NESとCPUサイクル
PS3とCPUサイクル

オンラインゲーム特有の要素

・避けられない遅延
・通信帯域
 C/S MMO: 10kbps~100kbps
 P2P MO: 30kbps~300kbps
・チートはなぜ行われるのか
 RMTで儲かるから
 利益=チートの価値ーチート開発のコスト
・チートの内訳
 メモリハック,パケットハック,データファイルハック,DLLハック,タイマハック,UIハックなど
 チートでないがダメなもの:規約違反,バグの不正利用,サーバに過負荷など
ノイマン型コンピュータの宿命
 チートと対策のいたちごっこノイマン型(プログラム内蔵方式)のコンピュータである限り永遠に続く.

[実践]C/S MMOゲーム開発

実際のゲームを題材としたゲーム開発について.

[実践]P2P MOゲーム開発

実際のゲームを題材としたゲーム開発について.

オンラインゲームの補助的システム

負荷テストなど.

オンラインゲームの開発体制

ソースコードの規模
・プロジェクトの保守

感想

読み始める前はオンラインゲームの技術について簡単に解説されているぐらいの認識でしたが,読んでみると結構ガッツリと技術解説されていて面白かったです.

まだ薄っすらとしか理解できていないので,ネットワークプログラミングについて勉強してからもう一度読みたいと思います.

Unity: 進行方向を表示する

こんにちハルマゲドン
水太りしてきました.

Unityで進行方向を可視化したときの備忘録です.


参考文献

なし


目的

進行方向を矢印で可視化したかった.


方法

矢印の画像を使用して,入力値に応じてGameObjectを回転させます(まんま).

f:id:lambda410:20210526215350p:plain
使用した画像

手法

  1. 入力取得
    x,yともに[-1.0, 1.0].
  2. 回転角度計算
    右ベクトルを基準として,入力値との角度を計算.
    f:id:lambda410:20210526215857p:plain

スクリプト

角度の向きを状況に応じて変更してます.
必要に応じて豪華にしてください.


動作

f:id:lambda410:20210526221055g:plain


まとめ

Unityは便利ですね.

Unityで自動生成の迷路を作る

こんにちはみがきこ
網戸にカメムシの卵があったので,急いで殺虫剤を買いました.

今回はUnityで迷路を自動生成したときの備忘録です. 自動生成に使用したアルゴリズムは穴掘り法です.

参考文献

algoful.com

完成図

サイズ: 5×5
f:id:lambda410:20210424205040p:plain サイズ: 51×51
f:id:lambda410:20210424205042p:plain
サイズ: 101×101 f:id:lambda410:20210424205036p:plain

穴掘り法

すごく簡単に言うと「穴を掘り続けて迷路を作る」アルゴリズムです.(そのまんま)
今回は下記の条件でアルゴリズムを実装しました.

・制約
1.迷路の横・縦のサイズは奇数.
2.横・縦の最小サイズは「5」.

・実装したアルゴリズム
1.奇数座標(x, y)をランダムに取得し,基準座標とする.
2.基準座標の上・下・右・左の4方向から1方向をランダムに取得.
3-1.ランダムに取得した方向の2マス先が壁ならば,そのマスまで掘る.
3-2.進めないならば,その方向を除いた他の方向をランダムに取得し,手順3-1.
3-3.全方向に進めないならば,1つ前の座標に戻り,残りの方向をランダムに取得し,手順3-1.
4.既定の回数になるまで手順2,3を繰り返す.

おそらく再帰かスタックを使用すると思います.
自分はスタックで実装しました.


ソースコード

若干無駄な処理がある かつ このままでは動かない気がします.
あくまでアルゴリズムの参考までに.


まとめ

今度はスタートからゴールまでを探索するAIを書いてみたいですね.
多分生成と同じ方法で解けると思ってます.

Unity: スプライトの表示順を変更する

こんにちワンダーランド

Unityでスプライトの表示順を変更したときの備忘録です.


参考文献

この記事を読めば理解できます.
tsubakit1.hateblo.jp


設定

今回はスクリプトや面倒な設定はなしです.

[Sorting Group]をアタッチして[Order in Layer]の値を変更するだけです.
f:id:lambda410:20210524213830p:plain

「値が大きい」ならば「一番上に描画」されます.
以上.


結果

f:id:lambda410:20210524214043p:plain
f:id:lambda410:20210524214103p:plain
f:id:lambda410:20210524214333p:plain

奥行きの配置に関係なく描画順が決まります.


まとめ

本当にただの備忘録.

「Game Programming Patterns ソフトウェア開発の問題解決メニュー」を読んだ

こんにちハードディスク

この記事は「Game Programming Patterns ソフトウェア開発の問題解決メニュー」を読んだ感想についてです.


Amazon


内容

ゲームプログラミングを題材としたデザインパターンについての解説書です.
対象はゲームプログラマですが,ソフトウェア開発に携わっている人にもおススメできる内容です.

対象

ゲームプログラマ,組み込みプログラマデザインパターンに興味のある人.
すでにデザインパターンを知っている人は少し簡単かもしれません.


要約

Part1. イントロダクション

ゲーム開発において,プロトタイプ開発時に殴り書きでコーディングすることがあるが,プロトタイプ完成後に使用する可能性も考慮して初めから綺麗にコーディングすることが大切.
・抽象化と分離は重要だが,プロジェクトが柔軟性を欲するまではこの工程に時間を割くべきではない.
・低レベルの最適化は最後に行うべき.(一般的に最適化は難読化しやすいため)
ゲームデザインの変更に素早く対応することは大事だが,後できれいにしましょう.
・不要なソースコードに時間をかけることはやめよう.

Part2. デザインパターン再訪

コマンド

要求をオブジェクトとしてカプセル化する.
・関節参照を利用し,実装はコマンドクラスにカプセル化する.
・「取り消し」と「再実行」の実装が簡単.
・コマンドキュー(コマンドストリーム)のようなものとして扱える.

フライウェイト

共有を利用して効率よくオブジェクトを処理する.
・省リソース化.

オブザーバ

オブジェクト状態が変化したときに他のオブジェクトに通知する.
・PSのトロフィーシステムのようなもの.
・ある状態が変化したという通知を受けるときに便利.

プロトタイプ

インスタンスからインスタンスを(プロトタイプとして)コピーして生成する.
・生成は面倒だがコピーが楽なときに便利.

シングルトン

単一のインスタンスを保証し,グローバルなアクセスポイントを提供.
・遅延初期化に注意.
・staticクラスでもいいかもね.

ステート

オブジェクト内部の状態変化に応じて振る舞いを変化させる.
・有限状態機械による管理.
・入口と出口処理で入退場処理を簡単に.
・階層型状態機会もいいよ.
・キャラクタの行動が内部状態によって変化するときに便利.

Part3. シーケンスのパターン

ダブルバッファ

逐次処理の複数作業を同時に処理したように振る舞う.
OpenGLDirectXにあるスワップチェーンのこと.
・状態が変更中であることを外部アクセスするコードにバレたくないときに有効.

ゲームループ

ゲーム内の時間進行をユーザの入力やプロセッサ速度から分離.
・ゲームループは開発者コードまたはプラットフォームのどちらにあるか気を付ける.
・フレームレート制御.
・電力消費の制限に気を付けること.

更新メソッド

フレーム更新のたびに一斉に1フレーム分のふるまいを実行する.
・UnityにあるUpdate().

Part4. ビヘイビアのパターン

バイトコード

ゲームのふるまいをバーチャルマシンの命令として記述する.
C++に組み込まれるluaみたいなもの.
VMを実作することが楽しい.

サブクラスサンドボックス

基底クラスを使用してサブクラス内に振る舞いを実装.
・派生クラスの多い基底クラスの結合度を最小化したいとき.
・サブクラス間で胸中する振る舞いを簡略化したいとき.

型オブジェクト

コンパイルなしに新しい型や既存の型を修正したいときに便利.

Part5. 分離のパターン

コンポーネント

複数のドメインを利用するクラスがあり,互いに分離したいときに便利.
・UnityのGameObjectで使用されている.
コンポーネント間の通信.

イベントキュー

メッセージイベント送信と受信処理を時間的に分離する.
・リングバッファ便利だよね.

サービスロケータ

サービス利用するコードに対して,結合なしにグローバルアクセスを提供する.
・NULLサービス.
・Singletonと似ている.

Part6. 最適化のパターン

データ局所化

CPUキャッシングを有効利用する.
・データ配置の工夫.
・ホット・コールド分離.

ダーティフラグ

結果が必要となるまで不要な処理を行わない.
・物理シミュレーションなどで有効.

オブジェクトプール

メモリ割り当て・解放を行うのでなく,再利用することで実行効率とメモリ使用効率を向上.
・オブジェクトの生成・破棄が頻繁に必要.
・BVHなどでも利用されている.


感想

クソコードを量産して怒られたのがキッカケで読み始めましたが,凄くためになる内容ばかりでした.
特にステートパターンの状態をクラスで管理するという考え方は,今までswitch文でバグを量産してきた自分には目から鱗と骨が零れ落ちました.

コマンド・シングルトン・ステート・バイトコードなど,自分で実装した内容に関しては理解できましたが,サービスロケータやサブクラスサンドボックスなど,実装したことがないものに関しては理解できていないので,プログラマとして成長した後に読み直したいと思います.

Unity: AddForceで慣性なし移動を実現する

こんにち花束
寝ても眠いです.

今回はAddForceで慣性なし移動を実現する方法についての備忘録です.

Unity 2019.4.24f1 Personal


参考文献

今回はなし


動機

慣性なしの移動処理を実現したい

AddForceからMovePosition(this.transform.position)にするか

MovePosition(this.transform.position)は瞬間移動なので壁をすり抜ける

じゃあ,どうにかしてAddForceの慣性を消したい

って感じです.


実装

超簡単でRigidbodyの速度を変えるだけ.


比較

通常のAddForce(慣性あり)
f:id:lambda410:20210516213543g:plain
慣性がありますね(当たり前).

MovePosition(瞬間移動)
f:id:lambda410:20210516214101g:plain
移動量が小さいときは壁ぬけしませんが,大きくなると壁ぬけしますね.

実装したAddForce(慣性なし)
f:id:lambda410:20210516214344g:plain
慣性がなく,壁抜けも起きていません.
今のところ,この実装で困ったことにはなっていないのでたぶん大丈夫だと思います(本当か?).


まとめ

簡単な実装でAddForceの慣性を消してみました.
Google検索ではAddForceの慣性をなくす記事はなかなか見つからなかったので,誰かのお役に立てれば幸いです.

Unity: ステートパターンでプレイヤを管理する

こんにちハロウィン
最近,だんだんと暑くなってきましたね.

今回の記事は,ステートパターンを使用した時の備忘録です.

参考文献

ステートパターンはこの本で知りました.


この記事の元ネタで,かなりわかりやすいです.
てか,ほとんど参考にさせていただきました.
qiita.com プレイヤの動きなどは過去の記事のコピペです.
lambda00.hatenablog.com


ステートパターンとは

State パターン - Wikipediaより

プログラミングで用いられる振る舞いに関する(英語版) デザインパターンの一種である。
このパターンはオブジェクトの状態(state)を表現するために用いられる。
ランタイムでそのタイプを部分的に変化させるオブジェクトを扱うクリーンな手段となる[1]。


実装

今回は参考文献のQiitaをほとんど移しただけなので,解説は割愛します.
詳細は,元の本家様の記事をご覧ください.

コントローラ

ステート

プレイヤ


感想

今までただの列挙型を使用して,switch文で分岐していましたが,クラスを状態に持つことでこんなに綺麗になるなんでビックリしました.
今度は階層型有限状態機械にも挑戦してみたいですね.