前書き
第1章 Amethystとは
第2章 Amethystの開発手引き
第3章 Amathystでブロック崩しを作ってみる
終わりに
この度は本書を手に取っていただきありがとうございます。本書はRust初学者に向けて、Amethystというゲームエンジンを紹介する本です。RustとAmethystの紹介から始まり、Amethystで実装する上での基礎を解説し、最後にブロック崩しを実際に実装しながら話を進めていきます。Amethystの設計や機能、それに付随するRustの実装を学び、最終的にAmethystを用いてRustでゲーム開発を行う手順を習得するのが本書のゴールとなります。本書がRustやゲーム開発の勉強の材料として、読んだ方の助けになれば幸いです。
本書は以下のような読者を対象としています。Rustの記法についての説明は省略している箇所もありますので、ご了承ください。
・Rust初学者の方(The Rust Programming Languageを通して理解している程度)
・Rustでゲームを作ってみたい方
・Rust製のゲームエンジンに興味のある方
・ECSアーキテクチャに興味のある方
Amethystはグラフィックの機能についてgfx-rsに依存していますが、MacbookなどのOS Xの環境下においてはうまく描画が更新されない場合があります。これは執筆時の最新バージョンであるAmethyst ver1.15.3が参照するgfx-rsのバージョンが古いことに起因するものです。issue自体は上がっており、開発段階である1.16.0以降では修正されるかもしれませんが、現状はこの問題が発生することがあります。問題が発生した際は、Windowをリサイズしたりすることで無理やり再描画させることで検証を行うことは可能です(実行後、画面が更新されなくなったらリサイズをかける)。ただ、当然検証に支障は出てしまうので、可能であればWindowsやLinuxといった別の環境での開発を執筆時点では推奨します。
本書では最後にブロック崩しのサンプルを用いて説明を行います。ブロック崩しのソースコードは著者のGitHub上で公開しています。使用する画像もリポジトリに内包されています。
https://github.com/Nitudon/sample_amethyst_breakout
本書の中で、Amethystの機能について基礎的なものから説明します。機能の役割や使い方について説明しますが、より詳細な説明を知りたいはこちらの公式のドキュメントを参照しながら読み進めてください。
・Amehyst Book: https://book.amethyst.rs/book/stable/
・Amethyst API Reference: https://docs.amethyst.rs/api/stable/amethyst/
本書で使用しているツールやライブラリのバージョンは以下の通りです。
・cargo: 1.50.0
・amethyst: 1.15.3
・amethyst_tools: 0.11.0
Rustの開発環境としてcargoが使える前提として話を進めますので、環境が整っていない方は整えてから読んでいただけると幸いです。
AmethystはRust製でデータ指向設計のゲームエンジンです。OSSのゲームエンジンでGitHub上にソースが公開されています。公式サイト1も整えられており、ドキュメント2やロードマップ、コミュニティなどの情報を得ることができます。執筆時点ではまだ開発中の部分も多いゲームエンジンですが、簡単な動くものを作るだけの機能は揃っています。ここではAmethystの特徴について、グラフィックスとアーキテクチャの2点を紹介します。
グラフィックの機能はgfx-rsを使用しています。gfx-rsはDirectX、OpenGL、Vulkan、Metalといった複数のグラフィックスAPIによる処理について、Rustで抽象化して取り扱えます。gfx-rsによってAmethystは複数のグラフィックスAPI上で実行させることが可能です。そして、2Dはもちろん3Dのゲームも開発可能で、レンダリングパイプラインのカスタムといった応用的な使い方もできます。
なんといってもAmethystの特徴は、データ指向設計ということでECSアーキテクチャを採用している点です。AmethystはRustに加えこのECSアーキテクチャを採用することによる高いパフォーマンスを特徴として大きく掲げています。このECSアーキテクチャについて、ゲーム開発をされている方は馴染みのある方もいるかと思いますが、ECSアーキテクチャについて説明します。
ECSアーキテクチャとはEntity(エンティティ)、Component(コンポーネント)、System(システム)という大きな3つの役割からなる設計思想になります。
・Entity オブジェクトの識別子
・Component オブジェクトの機能を表すデータ
・System Componentに作用するロジック
Entityはいわゆるゲーム内のオブジェクトの識別子です。たとえばゲーム内にキャラクターやステージがあるとして、自キャラクター、敵キャラクター、ステージの障害物など、ゲーム内に存在するオブジェクトそれぞれを表すEntityが存在します。Entityはあくまでもシンプルなオブジェクトの識別子として扱い、Entity単体では具体的な機能は持ちません。そしてEntityには紐づけるComponentが存在します。Componentは機能を分解したデータです。たとえば位置やスケールを定義する機能であったり、画像や3Dモデルの描画機能など、ゲーム内の機能を構成するデータがComponentとなります。ECSアーキテクチャではこの機能を表すComponentは配列的に管理されます。同一の機能を配列的に管理することで、機能のデータの管理をメモリ的に連続した配置で管理できます。そして、このComponentへの作用を行うのがSystemです。ゲーム内のロジックをComponent単位で考え、Componentを入出力する処理として実装します。SystemはComponent配列に対して一括で処理を行い、ゲーム内のロジックを実現します。ゲームでよくあるオブジェクト指向の設計においては、機能のデータはオブジェクトごとに確保されます。ゲーム内のロジックはオブジェクトの配列に作用しますが、そのデータのメモリ配置はオブジェクトごとになるので断続的となり、データの参照にコストがかかってしまうことが懸念としてあります。しかし、データ指向のECSアーキテクチャであればゲーム内のロジックが作用するのはデータであるComponentの配列となります。データは連続したメモリ配置になり、オブジェクト指向の設計の懸念を解決することができます。大量かつ同一の機能のデータが存在するようなゲームにおいて、このECSアーキテクチャは大きな役割を果たします。以上がECSアーキテクチャという考え方です。このECSアーキテクチャという考え方を踏まえて次章からのAmethystの説明を読み進めてください。
本章ではAmethystで開発を進めるための知識や、Amethystの機能について紹介します。実際に何か作りながら学びたいという方は、本章は飛ばしてブロック崩しを実装する部分を進めながら本章を参照する形でも大丈夫です。
まずはAmethystの開発環境を構築します。最初はcargoを使ってリスト2.1のコマンドを入力します。
cargo install amethyst_tools
amethyst_toolsはAmethystのプロジェクトを作成するためのツールです。ディレクトリ構成やCargo.tomlのテンプレート生成に役立ちます。プロジェクトを作成する時はリスト2.2に示すコマンドを入力します。
amethyst new プロジェクト名
リスト2.2は必要なCargo.tomlとディレクトリの階層構造を自動生成します。リスト2.3に生成されるディレクトリの階層を示します。
├── Cargo.toml
├── README.md
├── assets
├── config
│ └── display.ron // ウィンドウの設定
└── src
└── main.rs
assetsが画像のようなゲーム用のアセットを置く場所で、configが設定の定義ファイルを置く場所です。configにあるdisplay.ronはタイトルや画面サイズの設定になります。実際にはスクリプト側で読み込むのですが、それについては後述します。そして自動生成されるCargo.tomlについては、依存するamethystのcrateとfeaturesが記述されます。生成されるCargo.toml内容をリスト2.4に示します。
1: [package]
2: name = "test"
3: version = "0.1.0"
4: authors = []
5: edition = "2018"
6:
7: [dependencies]
8: amethyst = "0.15.3"
9:
10: [features]
11: default = ["empty"]
12: empty = ["amethyst/empty"]
13: metal = ["amethyst/metal"]
14: vulkan = ["amethyst/vulkan"]
最後のfeatureの部分はグラフィックスAPIに合わせた実行オプションになります。ゲームの実行時には使用するグラフィックスAPIに合わせてリスト2.5に示したようにfeatureをつける必要があります。オプションをつけない場合はdefaultに指定したfeatureが指定されます。基本的にはdefault実行であるcargo runで実行する形で大丈夫です。つける場合はリスト2.5のような実行コマンドになります。
cargo run --feature metal
cargo run --feature vulkan
以上がAmethystの環境構築の説明になります。ここからはAmethystの機能や設計について説明します。