更新履歴兼雑記 2003年05月分

since: 2003-05-01 update: 2003-06-01 count:
最新のものはこちら
May 28, 2003

[Program]: testsprite

忙しいと小ネタを作りたくなります。で、testsprite。

ゲームライブラリとしての SDL において重要なのは、 速度、実行パッケージサイズ、使いやすさなどってところですか。

C。200FPS。30KB。

C++。200FPS。30KB。C をそのまま使える。ラッパ多数。コンパイル遅い。

D。200FPS。90KB。 dmd for Linux でコンパイルすると phobos とかは static link するみたい。 コンパイル速い。 dli でもやってみないとね。

OCaml。180FPS。72KB。 何もかも static link してるみたい。 OCaml 素人につき非効率なコード書いてる恐れ高し。 ttf, mixer, image ごちゃまぜ。 コンパイル速い。

Eiffel。170FPS。88KB。 ちなみに処理系は SmartEiffel 使用。 image が混じってます。 jegl は結構ちゃんと DbC しているみたいです。 コンパイル遅い。

C#。 150FPS。?KB。 Zinniaさん作。 mono で実行。なんか速いんですけど…

Java。165FPS。150KB。 C# のソースをいじって作りました。 つうかパクるんだったらパクるで シンボルの名前を無駄に変えるんはやめてくれ、C#。 VM ってこと考えると敵ながらあっぱれな数字ではあるかなあ。 まあ VM をインストールしてくれ、 っていう要求をしなけりゃならんのがなんともきつい。

Ruby。135FPS。130KB。 mixer, ttf, image, sge, smpeg, sdlskk がオプション。 RUDL ではなく Ruby/SDL。 今のところスクリプト言語では圧倒的な速さなのだけれども。 元のソースをほんの少しいじっています。

Perl。33FPS。140KB。 image, mixer, net, ttf, smpeg, gfx, console, sfont となんでもアリ。 この尋常じゃない遅さはナゼ?

Lua。88FPS。270KB。 組込み向き言語に低レベルAPI である SDL を触らせる理由が思いつきません。 サイズの巨大さは Lua と tolua の定義を持ってるからっぽい。なんで? testsprite.lua は luaSDL 付属サンプルの 汎用的なゲームフレームワークっぽいものから作ったので、 かなり非効率だと考えられます。 あと、環境作りがとても大変。lua-4.0.1, tolua, luamodule patch が必要。 全くお勧めできない。

Erlang は testsprite が入ってるんですが、うまく実行できませんでした。 Objective-C, Pascal, Python, PHP あたりが見てみたいところです。 が、testsprite を書くのはもう飽きました。

testsprite なんてほとんど描画処理のはずで、 その証拠に testsprite 自体のコンパイルオプションを 変えてもほとんど FPS に変化は無いんですが、 そういうプログラムがただ言語のせいだけで遅くなる、 ってのは複雑な処理をするプログラムではかなりの障害になるはずで、 実際問題としてはなかなか使いずらいもんですね。

あといずれのソースもかなりいい加減に書いています。 う飲みにせんで下さい。

ていうか Windows でも試せとか思いました。 あと HW_SURFACE が生きる環境でも。 そのへんの色んな比較を Knowledge Foundation でできると 面白いかもしれないと思いました。

さあ、あなたならどれを使いますか? C ですかそうですね。

追記です。ごにいさんが testsprite for python 作ってくれたので早速チェック。 python のインストールに実に手間取る。110FPS。?KB。 確かにちょっと Ruby に負ける。 全部動的モジュールになってて使うものを好きに選べるんですかね。 しかし一つ一つがやたらでかいんですけど。 スクリプト言語のなかでは自由度的にも速度的にも Ruby/SDL が良く見えます。

もいっこ追記。ごにいさんが testsprite for ObjectiveC 作って下さったので早速(但し11月8日) チェック。 200FPS。30KB。

そろそろ10回ほど icon.bmp が無いよ、というエラーを見たような。 しかし私のマシンにゃ何個言語処理系が入ってるんだろう… 微塵も変わらないのは gcc だから当り前なのかな…

[Program]: EnemyML とはあまり関係無くデータとかスクリプトとか。

キターということで。 あと、Lua は楽でいいですよ。 自分で独自言語作るなんて馬鹿らしくなってきます。

雑感。 well-known な形式である以上既存のライブラリの存在やら、 XML の愉快な仲間達は相当に魅力的ではあるんですが、 まあそれにしてもゲームに使うには重いし冗長だし、 最適解だとはとても思えないと思う。 まあでもネタとしては面白いし、 PC でやるんなら潤沢なリソースがあるし、 わりと良い解ではあると思うんだけれども。

んじゃ理想は何かっていうと、 YAMLLua なんてどうじゃろ、と思いました。 YAML はスクリプト言語のデータ構造に 直にマッピングしやすいように作ってある言語で、 理想的には MVC の M = YAML, V = コンパイル言語, C = Lua みたいなことができれば面白いんでないかと。 YAML はコンパイル言語とは特別相性が良くないので、 M と V の接続が弱いのが厳しいところですが。

もうコンパイルするプログラムはエフェクトだの オブジェクトの保持だのといった処理のかかるところだけにして、 基本的なゲームの動きは Lua に任せてしまうというか。

あと、Lua のテーブルは元々 M を意識して作られてるけど、 YAML にも XML みたいな愉快な仲間達が出てくると予測されるので、 Lua と分離するメリットは十分にある気がする。

でも、それ使って弾幕書くかっていうと、 かなり前から弾幕書くのも飽きてるんで、 まあ別の機会に何かやってみたいところです。 D と Lua と YAML でゲーム作ったら相当マニアックで良いと思った。

[Program]: BulletML とスタイル指定

それはそうと、弾の色とかを指定できるようにしようと思う。 今のところは以下のような感じを妄想。名前はいいかげん。

<barrage>

<barrageInfo>
 <group>user</group>
 <title>タイトル</title>
 <description>2説明</description>
 <capture>攻略</capture>
</barrageInfo>

<barrageStyles>

 <bulletStyle figure="ball" color="white" />  <!-- label が無いのはデフォルト -->
 <bulletStyle label="bomb" figure="bomb" color="red"/>
 <bulletStyle label="laser" figure="laser" color="blue" type="laser" />

 <bulletLanguage name="bulletml" />   <!-- Lua とかもここで指定するとか -->

</barrageStyles>

<bulletml type="vertical" xmlns="http://www.asahi-net.or.jp/~cs8k-cyu/bulletml">
 ... もちろんこの中に <bullet label="laser"> とかがあるわけ。 ...

本当は barrage 単体がルートノードというのは嫌で、 barrage と bulletml が両方ルートノードになれれば 今までのプログラムとも矛盾が発生しにくいと思うんだけど、 XML ってルートノード二つ持ってもいいんだろうか。

基本的には HTML とスタイルシートみたいな関係で、 bulletml の方は全く変更無しで、 スタイルだけ外から指定するってのと、 同じファイルに何がなんでも詰めこみたいなあと思っています。


May 25, 2003

[Program]: testsprite

testsprite for C# 関係で、面白そうだったので quick hack。 testsprite for Dtestsprite for Ocaml。 D言語版は C 言語版と diff すればいかに何もしてないかがわかるかと。 OCaml版は OCamlSDL の sample である testalpha.ml のソースを流用しまくっています。

さて、FPS ですが、 C のが 200FPS, D のが 200FPS, OCaml のが 175FPS ってとこでした。 OCaml は不慣れなんで非効率なことをしている気がします。

しかし 1/3以下というのはキツいっすね。 だって Ruby/SDL でも 130FPS ということで半分以上は出てますし。

[Program]: 目指せ ioccc

といっても終わってしまっている上に C++ は対称範囲外ですが。

#include <vector>
#include <iostream>
template <class T=int> struct C {
    T b(T _=0) const { return ~_<<_?_<_^_>_:_>>_; }
};
template <template <class> class T, class U, class V>
U a(U (V::*g) (U) const) {
    return sizeof((T<U>().*&T<U>::size)()) (C<>().*g)(0[""]);
}
int (*f(int (*g) (int (C<>::*) (int) const))) (int (C<>::*) (int) const) {
    return (int (* const) (int (C<>::*) (int) const))g;
}
int main() {
    std::cout << f(a<std::vector,int,C<> >)((1,&C<>::b)) << std::endl;
    return 0;
}

typedef せずに関数ポインタは使うなというおはなし。 意味のある動作をするように育てていきたいところ。 今はそれぞれのトピックをばらしている感じだけど、 C 本来の邪悪コードと C++ の邪悪コードを うまく混ぜれば楽しいことになるに違いない。 trigraph はアリなのかねえ。

struct C {
  C operator()() { return *this; }
  C operator()(C c) { return *this; }
  C operator==(C c) { return *this; }
  C operator<=(C c) { return *this; }
  C operator>=(C c) { return *this; }
  C operator<(C c) { return *this; }
  C operator>(C c) { return *this; }
  C operator<<(C c) { return *this; }
  C operator>>(C c) { return *this; }
};

int main() {
  C c(C()((C()())<=C(C()>>C()<C())));
};

そういえばどこかに…と探したところこんなのも見つけた。

[Misc]: ttyplay

そう、screen は status line 喰っちゃうんですよね… タイトルに出すって手もあるんですが、 私はタイトルバーを 使っていないもんで。 そもそも端末関係なんて何もわからないんで、 タイトルの変え方もよくわかってないんですが。 あと、ちなみに ttyplay にしか手は入れてません。

ナローバンド向け STAR WARS 配信サイト。 凄い暇人だなあ… さっそくストリーム録画しました。

追記… そのエスケープシーケンス が /etc/termcap のどこに書いてあるんだろう… と悩んでいたのでした。 man termcap を見る感じでは、 「タイトルを変更するエスケープシーケンス」 というようなものを指定する項目が無いんですよね。 このあたりを見ても termcap には指定できなさそう。

まあ私は screen で status line にさえ出てくれれば良いので、 /etc/termcap に

ttyplay|for ttyplay only:\
        :hs:ts=\E]2;:fs=\007:ds=\E]0;\007:tc=screen:

などとして、 alias ttyplay="TERM=ttyplay ttyplay -h" としました。

これで、screen 上では status line を使って、 非 screen では title を使うようになりました。 TODO: screen で title に出す方法は?


May 22, 2003

[Misc]: おひっこし

おひっこしですが、 たぶん両方の URL が生きてる期間って無いと思いますし、 ひっこし先が http://shinh.skr.jp/ であるという確証も無いんで、 引き続きここに来られる変わった方は 私のアンテナ経由で来られると確実かな、と思いました。

[Program]: ttyrec's information in status line

ttyrec にステータスライン使って情報を表示する パッチを作った。

ファイル名、経過時間、現在の速度を表示します。 status line が使える端末で、ttyplay -h で起動すると良いかと。 試した環境は kterm on linux だけ。 しかし巻戻し機能欲しい…

ついでに… レベル1 でノームの炭坑町まで行って僧侶に AC を 8つ落としてもらった ttyrec ムービー。 炭坑町に行くまでの努力が重要なのに、 ttyrec り忘れてて炭坑町からでしょんぼり。 現状レベル1で AC -11。 この後はもうちょっとレベル1での AC を追及して、 寺院乗っ取りでもしようかな。

[Program]: D言語 で遊ぶ。

1年半ほど真剣に期待している言語です。 K.INABAさんの解説が超秀逸です。

K.INABAさんが細かく見ておられないところを見ていこうかと。 とりあえず partial specialization をチェックすることに。 C++ 的なコンパイルメタプログラミングはどうしても 再帰を多用したプログラミングになるということで、 再帰の例としてよく使われるけど全く例としてふさわしくないとして、 Efficient C++ で絶賛されているフィボナッチ数列を。 とりあえず C++ だと…

#include <stdio.h>
template <int lp>
struct p {
    enum { fib = p<lp-1>::fib   p<lp-2>::fib };
};
struct p<0> {
    enum { fib = 0 };
};
struct p<1> {
    enum { fib = 1 };
};
int main() {
    printf("%d\n", p<1000>::fib);
    return 0;
}

Dで書くと…

template p(int lp) {
    instance p(lp-1) p1;
    instance p(lp-2) p2;
    enum { fib = p1.fib + p2.fib };
}
template p(int lp : 0) {
    enum { fib = 0 };
}
template p(int lp : 1) {
    enum { fib = 1 };
}
int main(char[][] arg) {
    instance p(1000) pi;
    printf("%d\n", pi.fib);
    return 0;
}

両方ともオーバフローしまくってますが、 同じ結果が出ました。 素晴しいのがコンパイル速度。

g++ -o partial partial.cc -ftemplate-depth-100000  3.57s user 0.09s system 98% cpu 3.723 total
dmd partial.d  1.04s user 0.04s system 99% cpu 1.088 total

速い速い。 dmd ってのは Linux 用コンパイラです。 残念ながら dli ではコンパイルできませんでした。

今度は DbC を見てみよう…

[Book]: Efficient C++

さっきの話に少しでてきた本。読んでのは一年前。

書いてあることは普通なんだと思います。可もなく不可もなく。 私の場合 C++ での暗黙で発生するオーバーヘッドなんてのは 大体知ってたつもりだったんで確認程度になった位で、 逆にハードよりなメモリの並びによってキャッシュ効率がうんぬん、 とかはあまり知らなかったことなんで、ためになった、といったところでした。 だから普段から効率のことばっかり考えていてその道のプロな人には たぶん役に立たないのではないかと思いました。 中級者の確認と初級者の勉強用ですかね。

[Book]: Exceptional C++

ついでだから In depth series を全部書いとこう… これも一年前読んだ本。

必読本かと。 Effective より難しくて、More Effective となら どっこいどっこいな難易度の C++ 実用 HowTo 本。 C++ って言語は例えば、コンパイラに無茶な負荷がかかるんで、 コンパイル速度が遅くならないようなプログラミングを 心がけるとよかったりしますが、そういう本当に実用本意な話が多くて、 夢は無いけど現実的な問題の解が得られます。 特に例外についての情報量はとても多いです。

[Book]: Accelerated C++

他とうって変わって入門書。 中級者の確認にもならんと思います。 でも人に教える教え方としては結構面白いと思います。 C を学ばず C++ を勉強したい人や C++ 屋を育てる教育者には参考になるような気がします。

Modern C++ Designここがあるから省略。

[Program]: 白い弾幕くんのいろいろな値。

game specific な値を書き出しておきます。

画面サイズは 300x400。 最初の敵の位置は (150, 100), 自機は (150, 350)。 スピードを省略した bullet の速度は 1。 速度 v の bullet は 1 秒で v ピクセル進みます。 BulletML の実行は必ず約 60FPS。 プレイヤー速度はコンフィグの値の 1.5倍(糞仕様)。 direction の type 省略時は aim。 term 要素は 0 と 1 は同義 1 を推奨。 action を持つ弾が発生したターンには その action は実行されない。 changeSpeed ででかい速度にして wait 1 してから 停止させるのは FPS 次第で動く量が変わったりするので非推奨(ダメ仕様)。 あと XML 形式のコメントが書けないのに最近気付いたのですが、 ただのバグなんで次回修正します。

東方スキンのデキが良いと思った。見やすい。 あと 東方弾幕も。 どっちも紫月飴さんに教えてもらいました。

I-Saint さんが XMLでスクリプトを作られているということで期待… EnemyML の夢が。


May 17, 2003

[Update]: zsp

リナザウでプロットを。 学校で実験という授業があるのですが グラフ用紙にプロットとかをマジメにやるのがめんどいんで作りました。 すごくやるきのない物体です。すいません。

[Misc]: おひっこしとか。

たぶん 6月1日に URL が変わるんじゃないかと思います。 たぶん、 http://shinh.skr.jp/ が新しい場所なんじゃないかと思います。 (今は 404) メールアドレスもたぶん変わります。

cppll で紹介されてたベンチマークを見て作った ベンチマークです。 gcc, icc, kylix の速度比較。 Duron でも icc 速い…

観光客で昇天しかけた (けどデータが飛んだ) 時の ttyrec を発見。 もう死ぬ要素なかったな…


May 11, 2003

[Misc]: LuaBullet 補足。

いいかげん書いておかないと困ったことになりそうなので。

前回でっちあげた LuaBullet ですが、以下のような弱点があります。

これらは対処すればなんとかなりはするのですが、 さらに一番の問題として、XML でない、というか、 well-known なフォーマットではない、ということがあります。 BulletML で書いたならば、他のゲームで使い回せたり、 swf になったり、morph したり、Eclipse で開発できたり、 といような恩恵が実際にあるのです。 ということで BulletML で書けるものは BulletML で書くことを推奨します。

で、ならなんで LuaBullet なんてものを作ったか、ですが、 BulletML ではその簡易性ゆえ、表現しきれない弾幕が ちょこちょこあるわけで、例えば壁での跳ね返りができないのです。

で、そういうのをどうするか、っていうと、 長い間 BulletML を適当に拡張しようと思っていたのですが、 それだと結局 well-known な形式じゃなくなってしまうわけで、 なんともつまらない、と。

で、どちらにせよ BulletML の拡張なんていう面倒そうなことは やるモチベーションがどこにも無いわけで、 一番簡単にやれそうな Lua に白羽の矢が、というわけです。

[Misc]: 整理

容量がいい加減きついので、ちょっとサイト内を整理しました。 容量は全然変わらなかったので、時間のムダでした。


May 04, 2003

[Update]: 白い弾幕くん

新弾幕記述言語 LuaBullet をでっちあげました。 詳しくはダウンロードパッケージ中の LuaBullet.txt を参照。 ちなみに Lua 歴一晩なんで、間抜けなミスをやっているかもしれません…

BulletML は簡単かつ結構強力ですが、 LuaBullet は難しいけどなんでもできます。 プログラミング言語ですし。 今回追加した弾幕は BulletML ではちょっと表現しきれないものばかりかと。 黄流発狂を再現する日が来るとは思わなんだ。

ただエラーハンドリングとかドキュメントとかが不足しまくりなんで、 敷居は尋常じゃなく高いはず。API もとっても不親切。

弾幕 9個追加。 おたくツーさんから6弾幕、 自分で作った LuaBullet のサンプルを兼ねてるものが3弾幕。

斑鳩スキンと撃破伝スキンを おたくツーさんに頂きました。


May 01, 2003

[Program]: 細々と gcc pch

前回

結果を一個追加。 3.4-1 は使っているライブラリを stdcpp.h に全部収めて、 それをプリコンパイルしてあります。 3.4-2 は STL を大体プリコンパイルしてあります。

cppll から持ってきたこのソース。 個々にコンパイルすることによってちょっと遅くなった。

2.96 : g++ -c cppll.cc  0.88s user 0.04s system 100% cpu 0.915 total
3.4  : g++ -c cppll.cc  2.68s user 0.22s system 77% cpu 3.728 total
3.4-1: g++ -c cppll.cc  0.43s user 0.06s system 101% cpu 0.483 total
3.4-2: g++ -c cppll.cc  0.59s user 0.11s system 20% cpu 3.496 total

bpo。 個々にコンパイルすることによってかなり速くなった。

2.96 : make  165.99s user 5.73s system 93% cpu 3:03.42 total
3.4  : make  218.56s user 5.21s system 95% cpu 3:53.78 total
3.4-1: make  247.63s user 6.12s system 95% cpu 4:26.22 total
3.4-2: make  214.95s user 5.43s system 96% cpu 3:49.18 total

これまでのまとめとして、

ということから、STL だの、汎用的によく使うライブラリなどは 全部一つずつプリコンパイルしておいて、 個々のプロジェクト内でよく使うライブラリは 一つの stdafx.h にまとめてそれをプリコンパイル、かな。

ていうか VC って多分そんな感じじゃないのかな… きっと熟練した Windows プログラマには何を今更な話に違いない…

[Misc]: sdmkun for solaris

色々困っておられる方を発見。なんか申し訳無いです。 ちなみに私は大学の Solaris8 & gcc-2.95.3 という 環境で動作確認したことがあります。 いや、あの時は SunOS-5.6 だったかも。 とりあえずそのエラーは SunPro で作ったライブラリなのかなあ、と。

とりあえず、久しぶりにコンパイルしました。 getopt が無いけどしったこっちゃ無い、と config.h を編集。 SDL 入れ直して make 完了。実行できました。

参考。これまでの動作実績。 Linux, SunOS 5.6, Solaris8, FreeBSD, NetBSD, QNX, リナザウ, Win32。 Mac と Be をやってみたいところ。


home / index

全てリンクフリーです。 コード片は自由に使用していただいて構いません。 その他のものはGPL扱いであればあらゆる使用に関して文句は言いません。 なにかあれば下記メールアドレスへ。

shinichiro.hamaji _at_ gmail.com / shinichiro.h