RustからAltseedを使う

これはAmusementCreators AdventCalendar(通称ACAC)の12日目の記事です.

AltseedというC++/C#/Java製のゲームエンジンがあるのですが,それをRustから使ってみたという内容です.

VisualC++などの扱いには慣れていないので何か変なことを言っていたら指摘していただけると助かります.

Altseedとは

AltseedはAmusementCreatorsのOBやその他にも色々な人が集まって作っているゲームエンジンです.
AmusementCreatorsの作品はこのゲームエンジンを利用したものがほとんどです.
僕が説明するよりも ゲームエンジン - Altseed - などを見たほうが早いでしょう.

Rustとは

RustはFireFoxThunderbirdでおなじみのMozzilaが開発している言語です.
C++と同じくゼロオーバーヘッドを原則としている言語で,特徴はlifetimeによるdatarace安全でしょうか.
C++OCamlを足して2で割ったというイメージを持ちますがHaskellのほうにも結構引きずられている気がします.

公式ページは下です. www.rust-lang.org

もし興味があって使ってみたければrustupからインストールすると良さそげです. www.rustup.rs

RustからAltseedを使う仕組み

RustはFFIにも力をいれていてC言語の関数をかなり楽に呼び出すことができます.
なので,C++版のAltseedをC言語のインターフェースでくるんでやって,それをRustから使ってやります.

注意

本記事では僕の書いたasd-c-wrapperとかaltseed-rsを使っています.
それらは開発が始まった段階であり,この記事が公開されてからいくらか経つと記事を書いている現在と違ったものになっているでしょう.
RustでAltseedを使いたいならこの記事を読むよりもgithub上に上がっているReadmeなりを読んだ方がよいです.

実際にやっていく

環境はVisual Studio 2015とrustupを想定しています.

まずAltseedのCラッパーを準備します
git clone https://github.com/akitsu-sanae/asd-c-wrapper
として中のasd-c-wrapper.slnをVisual Studio 2015で開いてください.
Release/x86モードになっていることを確認してビルドするとlib以下にasd-c.libが生成されていると思います.
失敗した?それは辛いですね

次に作りたいゲームのRustのプロジェクトを作って色々設定します.
cargo new nyao --binとしてください(nyaoの部分は作りたいゲームの名前を入れていください)
プロジェクトの中にCargo.tomlができているので,その[dependencies]の下に
altseed = { git = "https://github.com/akitsu-sanae/altseed-rs"}
と追加してください.

Altseed_core.dllと先ほど生成されたasd-c.libをプロジェクトディレクトリに入れます.

rustcをlibファイルと対応しているものにします.
つまりrustup default nightly-i686-pc-windows-msvc としてください.

src/main.rsを編集してゲームのコードを書いていきます. 取り敢えず

extern crate altseed as asd;

fn main() {
    asd::initialize("test", 640, 480);
    let mut obj = asd::TextureObject2D::new();
    obj.texture(&mut asd::Texture2D::new("image.png"));
    asd::add_object2d(&mut obj);
    while asd::do_events() {
        asd::update();
    }
    asd::terminate();
}

とでも書いておきましょう.

これはimage.pngという画像を表示するというプログラムなので適当にimage.pngという画像を作ってプロジェクトのディレクトリに入れときます.

cargo runします.image.pngが左上に表示されているウィンドウが出たら成功です!!!

参考にしたもの

Foreign Function Interface

Rust言語でDxLibを使う - しらいとブログ

Rust と C言語 をコールバックで行き来する(Cブリッジが必要なVer) | d.sunnyone.org

F#でもゲームを作りたい!

これはmast Advent Calendar 2016 - Adventarの6日目の記事です.

はじめに

F#という言語を知っていますか?
F#はMicrosoftが開発しているML (Meta Language) でいわゆる関数型言語です.
詳しくはF# Guide を読むとよさそうです.
MLといえばOCamlStandard MLが有名ですが,F#の|>演算子OCamlに輸入されたりいい感じに高めあってる気がします.

さて,そんなF#を勉強するため試しに簡単なゲームを作ろうとしていたのですが,ggってみるとXNAを使う記事が多く見つかり残念な気持ちになります(XNAは開発中止……)
UnityというC#ベースのエンジンでF#を使うという記事がいくつかあるのですが,F#のコードをビルドして出来上がったdllをC#から使うという話であって全部F#で書けるわけではなさそう……

というわけでゲームエンジン - Altseed -というものを使ってF#でゲームを作る方法を紹介したいと思います.
実はAltseedは正式にF#に対応しているわけではないのですが,C#版のライブラリをF#から使ってやっていきます.

環境はVisual Studio 2015を想定していますが,Visual Studio 2017 RCでもほとんど同じでした.

F#をはじめてまだ日が浅いので何か変なことを書いていれば指摘していただけると嬉しいです.

環境の準備

  1. http://altseed.github.io/ の左のカラムの「導入」 > 「ダウンロード」からC#版のWindows向けのものを入手して解凍
  2. Visual Studioを開いてVisual F#のコンソールアプリケーションのプロジェクトを作る
  3. 解凍した中のRuntimeフォルダに入っているAltseed.dll, Altseed_core.dll, Altseed.XMLをプロジェクトのディレクトリにコピー
  4. コピーしたAltseed.dllとAltseed_core.dllをVisual Studioの右欄にあるソリューションエクスプローラーにドラッグ
  5. Altseed.dllとAltseed_core.dllそれぞれに対して右クリック > プロパティ から「出力ディレクトリーにコピー」を「コピーしない」から「新しい場合はコピーする」に変更
  6. ソリューションエクスプローラー内の「参照設定」を右クリックして「参照の追加」
  7. 出てきたダイアログの下の方にある「参照」からプロジェクトフォルダ内のAltseed.dllを「追加」して「OK」

適当にソースコード内に「asd.」と書いてみてインテリセンスが効いているようなら多分大丈夫.
実はこの流れはほとんどC#版と同じなので困ったらC#版のドキュメントをみるといいかもしれません.

コードの例

ウィンドウを出してみる

Program.csに

[<EntryPoint>]
let main argv =
    ignore (asd.Engine.Initialize("test", 640, 480, new asd.EngineOption()))
    while asd.Engine.DoEvents() do
        asd.Engine.Update()
    done
    asd.Engine.Terminate()
    0

と書いてF5を押す.
うまくいけばtestっていうタイトルの真っ黒なウィンドウが表示されるはず.

画像を出してみる

適当な画像をプロジェクトに追加してAltseed.dllとかと同じように「出力ディレクトリーにコピー」を「新しい場合はコピーする」に変更.
例えば画像の名前をnyan.pngとすると

type Neko =
    inherit asd.TextureObject2D
    new() as self = {} then
        self.Texture <- asd.Engine.Graphics.CreateTexture2D("nyan.png")

[<EntryPoint>]
let main argv =
    ignore (asd.Engine.Initialize("test", 640, 480, new asd.EngineOption()))
    let neko = new Neko ()
    ignore(asd.Engine.AddObject2D(neko))
    while asd.Engine.DoEvents() do
        asd.Engine.Update()
    done
    asd.Engine.Terminate()
    0

みたいな感じに書くと左上に画像がでてくる.
個人の好みで継承とか使ってるのでもっと短く書こうと思えば書ける.

Altseedの使い方はC#版のドキュメントを読めばだいたいそれがF#でも通用する.

おわりに

めっちゃ簡単にMLでゲームを作れる環境を見つけれたので個人的にとてもうれしい.
F12を押して宣言に移動とかも普通にできる.うれしい.
これまでゲーム書くときはC#を使ってたけど,これからはF#に移住するかもしれないです.

修正重力理論の概説

これはAmusementCreators AdventCalendat、通称ACACの21日目の記事です()。 現代物理学の授業で修正重力理論という面白い話を聞いたのでここで紹介してみたいと思います。
修正重力理論を採用すればダークマター等を考える必要がなくなるそうです。

そもそもダークマターは何故必要なのか?

まず、地球が太陽の周りを公転している様子を思い浮かべてください。  {m}を地球の質量、 {M}を太陽の質量、 {V}を地球の速度、 {r}を太陽から地球までの距離とすると、 この時引力と遠心力がつり合っていることから
 { \displaystyle
G\frac{mM}{r^{2}} = \frac{mV^{2}}{r}
}
 { \displaystyle
\therefore V = \sqrt{\frac{GM}{r}}
}
です。
よって、銀河の公転速度は銀河の中心から離れているものほど遅くなると推測できます。
しかし、実際に測ってみると銀河の外側でも回転速度は減少しなかったのです!!
そこで、物理学者達は計算に入れなかった物質があったのではないか、と考えました。
これがダークマターです。
計算によると
 { \displaystyle
V = \sqrt{\frac{GM}{r}}
}
 { \displaystyle
\therefore M = \frac{rV^{2}}{G} \propto r
}
で、どうやらダークマターは外側に行くほど増えるような気がします。 ここでダークマターが銀河の中心を中心として球場に広がっているとし、 {\rho}ダークマターの密度だとすると
 { \displaystyle
M = \frac{rV^{2}}{G} \propto r
}から
 {  \displaystyle
\frac{4}{3}\pi r^{3}\rho = \frac{rV^{2}}{G}
}
 {
\therefore \rho = \frac{3}{4}\frac{V^{2}}{\pi G}\frac{1}{r^{2}} \propto \frac{1}{r^{2}}
}
となり、どうやらダークマターは薄く広がっているのだなということが分かります。
現在ではダークマターの正体はニュートラリーノではないかと予想されています。
ここまでがダークマターのお話しです。

修正重力理論では

修正重力理論によればダークマターなどというものは存在しません。
そもそもニュートン万有引力の法則が間違っているんだ!と主張します。
万有引力 {F = G\frac{mM}{r^{2}}}のGはニュートン先生によれば定数だが、十分大きなスケールではrに比例するのでは?と考えてみます。
そうすると距離が離れても遠心力は小さくならないので、公転速度も小さくなりません!ダークマターを導入した原因を説明できてしまいます!
ただ、宇宙の質量が無限になるのはまずいのでさらに距離が離れていればGは小さくなるということにします。

これが修正重力理論の大まかな流れです。
僕は面白いと思うのですが、残念ながらどうやら物理学者の間ではあんまり相手にされてないみたいです。

metashellの紹介

これはAmusementCreators AdventCalendar通称ACACの7日目の記事です。

metashellとは

C++の対話型環境です。テンプレートの展開などを追えるのでC++のTMPを学ぶのに 良いです。

導入

対応している環境は

です。
これらに当てはまるならここからインストーラーを手に入れることが出来ます。
また、対応していなくてもgithubからソースコードをダウンロードしてinstall_build_dependencies.shbuild.shを実行すれば自前でビルドできます。

使い方

環境

#msh environment

で何がどう定義や宣言されていたり、どのファイルがインクルードされているかを知ることが出来ます。
これらの環境を一時的に保存するには

#msh environment push

してください。これによって現在の環境か変わることはありません。
その後、一段落してもとの環境に戻りたいときは

#msh environment pop

してください。pushする前の環境に戻ったと思います。
また、現在スタック上にいくつの環境があるのかは

#msh environment stack

で教えてくれます。
他にも

  • #msh environment reload ・・・インクルードファイルを読み直す
  • #msh environment reset・・・環境を初期状態に戻す(環境のスタックは変わりません)
  • #msh environment save <path>・・・環境をファイルに保存(metashell実行時に--enable-savingを引数に与える必要あり)

などが出来ます。

デバッグモード

#msh mdb <type>

デバッグモードに入ります。デバッグモードになると先頭に(mdb)が表示されます。
typeは省略できて、省略した時は直前の計算に対するデバッグモードになります。

デバッグモードでは

  • step n・・・でnつだけ処理を進める。
  • step over n or next n・・・現在のtemplateの階層よりも深い展開を無視してnつ分処理を進める。
  • step out・・・現在のtemplateの階層を抜ける
  • rbreak <regex>・・・正規表現にマッチした所にブレークポイントを張る
  • continue・・・ブレークポイントに引っかかるまで処理を進める
  • break list・・・ブレークポイントのリストを表示する
  • finish・・・ブレークポイントを無視して最後まで処理を進める
  • forwardtrace or ft・・・これからの処理を表示する
  • backtrace or bt・・・これまでの処理を表示する
  • help <command>・・・コマンドのヘルプを見る
  • quit・・・デバッグモードを終了する

などができます。

そのほか

  • boost::mplのコンテナを使うときはmetashell/formatter.hppをインクルードしておいた方が良さそうです
  • #msh quitでmetashellを終了します
  • #msh precompiled_headers onとするとプリコンパイル済みヘッダを使えます
  • いちいちうるさいなぁと感じたら#msh verbose offにするとよいです

C++におけるgoto文について

これはAmusementCreators AdventCalendar14日の記事です。

C++にはC言語と違ってclassがあるため結構複雑になってる。

goto文が変数の宣言を飛び越える時

危険だし全く推奨されないのだけどgoto文で変数宣言を飛び越えることができる。 つまり以下は合法。

    goto some_label;
    int value;
some_label :

しかしこのようにgoto文で飛び越えれる自動ストレージ*1上の変数には以下のいずれかを満たさなければならない。

  • スカラー型である
  • trivialでdefaultなコンストラクタとtrivialなデストラクタを持つ
  • これらの型がCV修飾された型
  • これらの型の配列型

さらに

  • 初期化子なしで宣言されなければならない

という制限もある。

例を示すと

    goto some_label;
    int x;              // いい
    int x = 0;          // 悪い(初期化子がある)
    Pod obj1;           // いい
    NonPod obj2;        // 悪い(trivialでない)
    static NonPod obj3; // 良い(そもそも自動ストレージに確保されない)
    static NonPod obj4{};  // 良い(初期化子があっても上と同じ理由で)
some_label :

goto文で処理が巻き戻るとき

このような時は宣言を跨がれた変数は破棄される。当然デストラクタも呼ばれる。

some_label :
    SomeClass object;
    goto some_label; // ここでobjectが破棄される

まとめ

そもそもイディオム化した書き方以外でgoto文を使うのはやめよう。

*1:ぶっちゃけスタック領域の事だが規格上はコンパイラはスタック領域として実装する必要はない

AmusementCreators AdventCalendarの開催をいまここに宣言する

これはAmusementCreators AdventCalendar2015の一日目の記事です。

AmusementCreatorsの秋津早苗です。
AdventCalendar初回ということで我らAmusementCreatorsの紹介と一年を振り返っての感想を綴っていこうと思います。

Amusement Creatorsとは

AmusementCreatorsとは筑波大学公認のゲーム制作サークルです。

どんなところか

サークルができた当初は、ゲーム制作サークルというよりは元から自分の同人サークルを持っている人たちが技術を共有する場所だったそうです。
僕が入部した時は硬派な技術者集団といった感じでした(C++erですって言うと先輩に好きなBoostライブラリを聞かれて戸惑いました)が、今年の新歓でリソースを作れる人を求めていた事もあって技術者成分は薄れてきたのかなという感じがします。

活動

毎年サークル内で48時間ゲームジャムや6週間ゲームジャムを行って、その成果物を毎年夏コミと冬コミで発表しています。
今年も3日目東モ40bで参加します。 ただ実は、ここ数年時間の都合で6週間ゲームジャムは開催できてません…
来年こそはしたいですね。

Altseed

AmusementCreatorsの部員やOBなどが集まってAltseedというゲームエンジンを作っています。
C#C++など複数の言語を使ってほとんど同じ書き方で開発でき、僕らのサークルでのプログラミングの教育に使われています。将来的にJavaもサポートされそうです。
良いライブラリなので皆さんも是非使ってみてください。
詳細は http://altseed.github.io/ にて

今年を振り返って

今年は代表が多忙だったということもあり、サークルとしての活動はそれほど多くなかったと感じます。
でも、今年は部員が増えて色々と幅が広がったのでこれからどうなるか楽しみです。

僕個人の話だと、今年は作っているときは面白いと思っていたゲームが完成した数か月後には面白く感じられなくなるという現象が何回も起こったので精進しなきゃなと思います。

最後に

このAdventCalendarは纏められて今年の冬コミC89で頒布される予定です。
もし紙媒体で読みたいという稀有な方がいれば是非AmusementCreatorsのスペースにお越しください。
改めて言いますと3日目東モ40bです。

次の記事はラン君でshadertoyの話です。