[News]MURASAMA αテスト開始
MURASAMAのαテスト開始しました。
まだまだ非常に不安定でゲームとはいえない状態ですが、テスト参加者と動作レポートをお待ちしています。
今すぐαテストに参加する
[アイデンティティ]オンリーワン
とあるMatzにっきより。
しかし、この記事中のある一節 『一方で、そのままでいいと言われても、いまの自分はまだ何者でもない。 焦燥感もある。真のオンリー・ワンになる道は、ナンバー・ワンになるよりはるかに険しいこともわかっている。 』 を読んで、 『「真のオンリーワン」なんてものは結局ナンバーワンのことだ。 そんなこと言ってる人は「オンリーワン」のことが分かってない 』 と語った妻の言葉を聞いて、このことについて改めて考えてみた。
というわけで改めて考えてみる。
日ごろから思っているのは、いずれオレはナンバーワンになるということ。ずっと前からナンバーワンを目指しているし、おそらくなれるだろう。 しかし、身近な人間を見るとナンバーワンを目指している人間はすごく少ない。昔はなぜ目指さないのか理解できず人と話すたびに驚いたものだ。今は自分が「ナンバーワン」について人と違う捕らえ方をしていると知っているから驚くことはない。
ナンバーワン、ナンバーツーと順位をつけるからには明確な「ものさし」が必要だ。収入、身長などは「ものさし」になるし、スポーツの種目だってそれぞれがものさしだ。どのものさしにもナンバーワンが存在する。そして重要なのは世の中にはものさしが無限に存在するということだ。学校で順位をつけないという価値観があるようだが、学力に順位をつけたり偏差値で評価したりして競争させることはいいことだと思う。しかし学力が唯一の重要な「ものさし」であると教えることは絶対に間違っている。
オレは無限にあるものさしの中で最も自分の好きなものを選べばいい。そしてナンバーワンになる。つまりそれはオンリーワンだ。
[blog]I love CUI
Ruby/Tkを調べているさなかCUIに関するすばらしいサイトを発見した。これを知っているか知らないかで仕事効率が何倍も変わりそうだ。仕事にCUIを使ってない人がこれを習得すれば多大な恩恵を受けることができるだろう。 それはプログラマであれデザイナであれ同じことだ。
Linux の膨大なツールの数や EMACS などのコマンドの数を見ると、 何をどの程度習得すれば良いのか戸惑います。 このホームページでは、Linux を知的生産の道具として活用するためには、 最低限どのツールをどの程度使いこなせば良いかを考えました。
コンピュータを勉強している人には是非身につけてもらいたい。 もっと早くこのページを知っていればLinux依存度が高まっていたことだろう。
[ゲーム]ピクミン2
ゲームキューブのピクミン2。 今回はむらさきピクミンやしろピクミンなど種類も増えるようだ。 前作と違って今回は時間制限がなくなるのだという。まったりと蓄積できる安心したゲームになりそうだ。もとのゲーム性からするとまったりプレーのほうがあっている感じはする。
公式ページがすごくシンプルだ。参考にしたい。
[開発ログ]Mrs排他ロック
いままであまり考えていなかったが、そろそろ排他ロックを考える。 MrsはCGIだから排他制御をしないと同時にいくつものセッション起動が可能になってしまう。 基本はbaskelianOLのときに検証済み(実はいくつかのバグがあった。stockがマイナスになるバグは有名)で、 ユーザのコマンド発行時とショップ売買時に排他処理を行えばいい。 今回はページ遷移にロケーションを取り入れたので、全てのDB書き換えをコマンド専用CGIの処理として一本化できそうだ。 トランザクションもコマンド処理の前後だけで行えばいい。
sql.query("BEGIN;") location = write_proc(cgi,sql,mode)#--modeで指定されたコマンド処理を行い、ジャンプすべきURLを返す sql.query("COMMIT;")
baskelianOLはファイルロックで排他ロックを実現していたが、今回はMySQLのロック機能を使いたい。 しかし、仕様がいまいち不明だ。データベースは種類が多くそれぞれ仕様がまちまちだし、MySQLはバージョンによってもサポートされている機能がかなり違う。 もう少し勉強するか。
※追記 2004-04-26
このBEGINの開始位置は間違い。SELECTを使用する前からBEGINを開始する必要あり。
[開発ログ]WEB拡張パッケージシステム
外部テンプレートの定義システムが動くようになっているものの、これを実装してからは危険すぎてお試し公開すらできなくなってしまった。
HTMLそのものを置き換えることができるので、見た目のみならずリンク構造を変えてインターフェースを作り替えることも可能だ。 ここまではいい。予定通り画期的な拡張パッケージシステムだ。
問題はセキュリティホールだ。テンプレートはrhtmlのなでHTMLの中にRubyスクリプトを埋め込むことができる。これはもう何でもできてしまうということになる。ゲームシステムの変更、データベース改ざん削除、そしてサーバのroot権限の奪取など、文字通り何でもできてしまう可能性がある。
カスタマイズの自由度の高さを維持しつつ安全なシステムを慎重に作らなければならない。思ったよりも時間がかかりそうだ。
total 6001 lines .cgi 834 .rb 3642 .sql 325 .txt 43 .htm 453 .html 704
HTML
tDiaryとかRDの楽さや生産性の高さに触れてしまうと、もう手でHTMLを書く気にはなれない。今は付属ページのいくつかをHTMLで書いているが、これもそろそろやめた方がいい。今は3ページほどだからいいが、ページ数がこれ以上増えると手に負えなくなり、やがて更新が滞ることだろう。PukiWikiのようなデザインは好きじゃないが、少し調べてみたい。tDiaryの別モードも調べてみようと思う。
[開発ログ]過去のプロジェクトのソース行数
BOL
total 39966 lines .cgi 5817 .rb 9862 .pl 337 .sql 26 .txt 1611 .htm 1729 .html 20584
某MMORPGα版
total 64305 lines .cgi 9396 .rb 32808 .pl 1904 .sql 1072 .txt 8685 .htm 33 .html 10407
某PS2ソフト
total 147506 lines .c 3671 .cpp 102282 .h 23221 .rb 8501 .pl 9831
Cのソースをこんなに書いていたとは。数えたことがなかったが今までオレ一人で20〜30万行はC言語のソースを書いてきたのだろう。それからするとLinuxカーネルの550万行は多くない。
[開発ログ]ソースの行数
Linuxカーネル2.6のソースは550万行あるという。Jewelの現在のソースの行数を計ってみる。
total 5658 lines .cgi 739 .rb 3438 .sql 325 .txt 43 .htm 453 .html 660
テンプレートとhtmlを含めて5658行。あっという間に万単位になるだろう。
計測に使ったスクリプトはこれ。
def srcvol(dir,fname_end) tsize = 0 Dir.glob("#{dir}/**/*#{fname_end}") do | file_name | size = File::readlines(file_name).size puts c = "#{size}\t#{file_name}" tsize += size end tsize end out = '' asize = 0 ['.cgi','.rb','.sql','.txt','.htm','.html'].each{|fname_end| tsize = srcvol('.',fname_end) puts "#{tsize}\t#{fname_end} total\n\n" asize += tsize out += " #{fname_end}\t#{tsize}\n" } puts " total\t#{asize} lines" print out
[ハッカーの悩み]ベッキーちゃん
昨日の夜、電車から下りる間際にようやくリーナスの著書それがぼくには楽しかったからを読み終えた。ビルゲイツの本も少しは面白かったけど、僕にとってはこっちの方が100倍エキサイティングだ。
で、いまの悩みはデスクトップ環境をLinuxに移行できるか?だ。著書を読んでリーナスのファンになったし、もっとLinuxというものを知りたいし、そして何よりも今後オープンソースという物がどこへ向かい何を実現するのかを身近に体感したい。一日の活動時間のほとんどをパソコンの前で過ごしているが、はたして僕はパソコンで何をしているのだろう。その作業はLinuxデスクトップでも可能だろうか。日頃よく使うアプリケーションはこれらだ。
- エディタ(WZ EDITOR)
- ブラウザ(IE(Moon Browser))
- メーラー(ベッキーちゃん)
- エクセル
- ワード
エディタはLinux版のXZ EDITORというのがあるし、他にもよりプログラムに適したエディタは絶対に存在する。 ブラウザはMozillaでもたぶん我慢できる。 ネックはベッキーちゃんだ。過去の仕事のログはベッキーちゃんが持っている。ベッキーちゃんの記憶を引き継いで、さらにフィーリングがあうメーラーが見つかるだろうか。今なら探せば見つかるのかもしれない。 エクセル、ワードは自分で編集することはあまりないが、毎日数件の添付データが送られてくるし、それを紙に印刷することも多い。OpenOffice.Orgでどこまで正確な印刷ができるのか気になる。エクセル、ワードはちょっとした非互換が致命傷になりえる点で非常に難しい。
もうひとつ大きな問題がある。みんながゲームをやるのはWindows上なのだ。 僕はゲームをやらないからゲームをするためのWindowsは不要だけど、Windowsで動くゲームを作るためにWindowsが必要なのだ。これこそが最大のネックかもしれない。これさえ除けばそろそろ潮時かなと思う。少なくとも試してみる必要はありそうだ。
重要なのはフィーリングだ。たとえ列挙できる機能が同等であってもだめだ。 ユーザインターフェースはそんな単純なものじゃない。バーに表示されるフォントの位置がほんの少しずれるだけで気に食わなかったりする。使い勝手には慣れの要素も大きい。
今のWindowsが最高だとは思わないけど、十分にいいとは言える。WindowsのGUIは十分に優れている。乗り換えるにはショックが必要かもしれない。先日見たMac OS Xは衝撃的だった。はたしてこういう衝撃的なグラフィカルインターフェースをオープンソースが生み出すことになるのか。非常に興味深い。
[OSS]オープンソースのゲーム開発は成功する?
はたして、オープンソースでのゲーム開発は成功することができるか。 この問いする答えは今しばらく出せそうにない。
JewelとLinuxカーネルを比べてみる。まず違うのはここだ。LinuxユーザはLinux環境を手に入れた時点で、自ら好きなようにそのカーネルシステムを修正する(ハッキングする)権限を有する。 Jewelシステムにこれはあてはまらない。一人が運営するサーバで10000人の一般ユーザ(ゲームを遊ぶユーザ)を抱えている場合、サーバシステムを修正できる権限を持つのは運営者一人で、それ以外の10000人のユーザは自分が接続している直接のソースを修正する権限を持たない。
ならば今度は、WWWサーバであるApacheと比べてみる。WWWサーバシステムでは管理者対圧倒的多数の一般ユーザという構図である。そうApacheはインフラだ。しかしおそらくは、Jewelはインフラではない。
っと、書いているうちにまだ考察がまとめるに至っていないことに気づく。この問いへの答えは宿題とさせて頂きたい。
[個人的なメモ]Jewelのこと(書きかけ)
Rubyを使ってJewelというシステムを開発しています。 Jewelとは僕個人が開発しているMMORPGのシステムです。 オープンソースのゲームシステムでほとんどをRubyで実装します。 Jewelは固有の世界観を持たないある程度汎用的なネットワークゲームシステムです。
2004年の初めから開発をスタートしました。当面は僕一人で全てのシステムを実装していくことになるでしょう。まず、WEBゲームのひとつから開発しています。今年中にいくつかのWEBゲームと基礎的なMMOサーバ/クライアントを動作させることが目標です。
Jewelシステム構成概要
僕が作りたいのはこんなものです。
- MMOサーバ
- MMOクライアントが接続するサーバ。数千規模の同時接続が可能
- MMOクライアントアプリケーション
- マルチプラットフォーム対応
- ユーザ登録システム
- CGIインターフェース
- 携帯電話端末にも対応
- WEBブラウザで遊ぶミニゲーム
- CGIインターフェース
- 携帯電話端末にも対応
- WEBブラウザからのワールドログインシステム
- CGIインターフェース
- 携帯電話端末にも対応
- チャットベースのコミュニケーションツール
Jewelの特徴
- オープンソースである(GPLライセンス)
- サーバからクライアントまでRuby+Ruby拡張モジュールで実装
- マルチプラットフォーム対応
- サーバもクライアントもともにマルチプラットフォーム対応
- ※サーバはUnix系OSを推奨?
- データベースにMySQLを使用
- ユーザレベルで世界観のカスタマイズが可能(※詳細は後述する)
- 拡張パッケージの使用で世界観を簡単に差し替え可能
ユーザレベルで世界観をカスタマイズ
クライアントアプリケーションのカスタマイズ
この仕組みはJewelの最大の特徴です。
ローカルマシンのファイルを編集したり差し替えたりするだけで、ゲーム世界に登場するほとんどのリソースを自由にカスタマイズできます。
具体的にカスタマイズできるのは次のものです。
- 全ての固有名詞
- アイテム名
- 人物名
- クラス名、能力名、技名、魔法名
- 地名
- 他全ての固有名詞
- 全ての画像データ
- 全てのサウンドデータ
- BGM
- 効果音
- ボイス
- テキストデータ
- キャラの台詞
- 状況説明
- 変更例
- 「この『薬草(固有名詞)』を持っていきなされ。では十分に気をつけるのじゃ」⇒「はい、これ私の作った『手作りのお弁当』。では今日も一日お仕事がんばってね!」
- 「○○○は『スリープ』の呪文を唱えた」⇒「○○○の『催眠』術!」
- 「○○○は15のダメージを受けた」⇒「15キロワットのエネルギーを吸い取られた○○○であった」
例えば、ゲーム内に登場するキャラクタの顔を全て差し替えることが可能です。キャラクタの顔画像データファイル(BMPかPNG)を置き換えてしまえば、ゲーム内に登場するキャラクタの顔が変わります。そしてそのキャラクタの台詞を変えることもできます。
ただし、イベントの発生条件を変えることはできません。ワールド内に、話しかけると、毎朝薬草をくれるお爺さんがいたとします。このお爺さんの顔と台詞を変更して、かわいらしい女の子にすることはできますが、「話しかけると、毎朝回復アイテムをくれる」というイベント発生条件を変えることはできません。もちろん回復アイテム『薬草』のアイテム名を『タマゴサンド』に変えることは簡単です。
グラフィックデータやサウンドデータ(BGM、効果音、ボイス)は全て変更可能なので「中世ファンタージ」、「SFロボット物」、「学園物」等何でも表現できます。完全にユーザの自由です。
拡張パッケージの作成と配布
カスタマイズ可能なデータはひとつのディレクトリ以下にまとまっているので、そのディレクトリ以下を圧縮して固めるだけでオリジナルの拡張パッケージが完成します。そして自分が作った拡張パッケージをWEBで公開することもできますし、人の作った拡張パッケージを使用するのも簡単(ファイルをコピーするだけ)です。
※拡張パッケージを公開する場合の注意
既存のマンガ、アニメ、ゲーム等著作物のキャラクタや画像、音楽データ等を使用する場合はその著作権に十分注意してください。
Jewel作者は、Jewel及び拡張パッケージについて一切責任を負いません。
ゲーム性
プログラムの修正でゲームロジックを変更
ユーザレベルで決して変更できないのが、ゲーム性、つまりゲームのロジックです。 当然ですがユーザレベルではゲームバランスを変更することすらできません。
ゲーム性を拡張、変更するにはプログラムを書き換える必要があります。 ゲーム性の変更はできるだけ簡単できるようにシステムが設計されています。 また、このゲーム性のロジックはRubyで実装されているので、手軽に修正することが可能です。
WEBブラウザで遊ぶミニゲーム(CGIインターフェース)
- カードバトル
- 生産ゲーム
- 栽培ゲーム
その他
[アイデンティティ]試練
頂いたレポートでJewelのユーザ登録システムの欠陥に気づく。個人で使っているあるプロバイダのSMTPを使って登録認証メールを発行するという、いい加減な作りの部分のことだ。
おそらくは自分のサーバにSMTPを立てないといけない。そういえば、今のサーバはsendmailも正しく動作しない。一度設定を試みたが途中で挫折したのだ。この手のサーバ設定は極力やりたいくない。この作業はすごくコストの高いものであるし、デザインとは全く別のモードに頭を切り換えなければならない。サーバ関係の作業をしている間は表面上のゲーム開発が完全にストップするだけでなく、創造にあてるべき力が吸い取られてしまうのだ。普通、ゲームの企画者は見当はずれの仕様書をプログラマに渡し、プログラマは文句を言いながらゲームデザインを再設計しなおすものだ。ただしオレには下手な仕様書を押しつけるプログラマもしないし、文句を言うための仕様書を作ってくれる人もいない。昔から両方を自分の手でやり遂げないといけない不運な人間なのだ。
これはテストだ。そう、オレはいまテストされているのだ。本当にゲームを作る人間なのかどうかを。 肝心なことは決して作業を止めないことだ。少しずつでもいいから進めて、決して一日も止めない方がいい。オレは3日も空けるとその創造的な活動に対しての興味を急激に失うタイプである。
きっとこのテストに通ればひとつの大きなアイデンティティを確立できるに違いない。そもそもデフォルト名を持つ意義は小さかったのだ。
[Mrs]仕様の肥大化
α版公開までの作業工数が予想以上に多くなっていることに気づく。Mrs(マーサ)の仕様が見積もりより肥大化しているからだ。最小限の機能で公開しようと考えていたはずなのに、いつの間にか多くを詰め込みはじめていた。これは非常に危険な傾向だ。
この手の非商用ゲーム開発プロジェクトは9割がバージョン1.0が完成しないまま消滅すると相場がきまっている。だからとにかく遊べるものを早急に公開しなければいけないことははじめからわかっていた。しかし、実装を進めるうちに無意識にいろいろ想定以上のものを組み込んでしまった。それは公開した後、特にオンラインのユーザを抱えた後に新しいシステムを追加することが難しいのを知っているためだ。機能は公開前にあらかじめ組み込んでおいたほうが圧倒的に楽なのだ。その将来の懸念が無意識に仕様を肥大化させてしまった。
モチベーションとゲームの面白さ、そして将来のメンテナンスコストのバランスの問題だ。モチベーションの欠落はすべてをゼロにしてしまう。一人で開発しているので今やめても誰も文句を言うまいというのも危険な状態だ。やはり少しでも多くの人を巻き込むべきだろうか。いや、何も出来ていないのに協力してくれる人はそうはいない。すでに発注したバナー作成依頼を糧にモチベーションを保つとしよう。
[開発ログ]α公開まであと100時間
100時間後に公開されるという意味ではない。あと100時間ほど作業すれば公開できるものが作れるという意味だ。
100時間というのはドラクエ7をクリアするのに必要な時間と同じだ。100時間なら社会人でも1ヶ月でなんとかなる時間だ。筆者の場合、好きなゲームには凄まじい集中力を発揮するので、働きながらでもひと月で400時間ほどのプレイをしたことが何度かある。
100時間が長いようでもあるし短いようでもある。最近発売されたドラクエ5ばシリーズの中でも最高に好きなタイトルだったので、購入しようと思っていた。しかし、こっちの開発のほうが面白いのでしばらく開発に専念しようと思う。
[コンセプト]決めたいこと
以下は草稿。
dGames
Jewel
- Jewelとは
- Jewelの特長
- 入手法
- ホームページ
- メーリングリスト
- コンパイル・インストール
- 移植
- 配布条件
- 著者
Kugutsu
ロードマップ
- ?
難しいのはdGamesとJewelのサイト構成だ。dGamesを消去してJewelサイトだけで一本立ちさせることも可能だ。 例えばRubyはhttp://www.ruby-lang.org/で全てが済んでいる。
dGamesは何なのだろう。dGamesはコミュニティだ。ゲーム開発者とユーザのコミュニティだ。しかしこれはJewelコミュニティにもなり得る。もしdGamesの成果物がJewel以外にもあるのであればdGamesコミュニティとJewelコミュニティは別物として確立し得るが、dGamesに複数のプロジェクトを提供する余裕はない。Jewelが提供できる成果物になるかどうかが最大の問題であるというレベルにあるにすぎない。
問題はオレ自身がなにを目指しているかということかもしれない。コミュニティの構築が目的なのか、システム・アプリケーションの制作が目的なのか。おそらくはコミュニティを必要としている。システムの構築だけでなくそこから派生するであろう未来のプロジェクトも視野に入れている。
そうか、Jewelコミュニティ(一般のゲームユーザを含む)から派生した未来のプロジェクトのひとつを運営するのがdGamesだ。dGamesは数あるJewelユーザのひとつ(「楽しいJewel」という書籍を執筆)となるのだ。つまり、将来の他のJewelユーザにとってはdGamesは直接関係ないのだ。さらなる考察が必要だが、おそらく、dGames-devの将来はJewel開発者そのものではないといことだ。
JewelはdGamesに育てられ成長し、やがてdGamesから離れて独り立ちする。 そして、オレはJewelの生みの親なのだ。
[ハッカーの悩み]Windows vs Linux
ここ数日Linuxの作者リーナスが書いた「それがぼくには楽しかったから」を読んでいる。僕が本を読むのはきまって電車の中だけど、この本もいつものように電車の中で読んでいる。そしてこの本はすごく面白くて僕に感動とやる気を与えてくれる!
まずこの本を読みはじめてからリーナスに対する印象が変わった。 これまで単に知らなかっただけだけど、実際はすごく好感のもてる人物だ。そしてリーナスの言うことはすごく興味深いし何より面白い。 これは僕にハッカーの資質がある証拠だ。リーナスのいっていることはほとんど理解できる。自分に似た点も多い。しかし違う点もある。彼はOSを書く人だが僕はアプリケーションを書く人間だ。同じプログラマでもこれは非常に大きな違いだ。
リーナスの方がコンピュータに近くて僕の方が人間に近い。ここでいう人間とはアプリケーションが提供するユーザインターフェースとそれを使う人間という意味。OSはコンピュータを制御するものだけど、アプリケーションは人間を制御するものだ。普通は人間がアプリケーションを制御すると思うだろうけど、僕はいつもこの視点でゲームを設計するんだ。
いつも僕はプランナーとしての仕事をするのが本分だと思っている。というのはゲームを作りたいという理由があるからその道具であるプログラムを使用するだけであって、もしもゲーム制作に必要な技術が別のもの(例えば木工技術)ならそれをマスターする努力をするというだけのことだ。と、いいたいところだけど単純にそういうわけではないという気はする。僕の父は生粋のエンジニアだ。今でも現役で開発の仕事をしている。父はソフト屋ではなくハード屋さんではあるけどね。父が大手電機メーカーのエンジニアであったせいで、物心がついたときには家にコンピュータがあったし、先天的にも確実にエンジニアの資質を受け継いでいるので、プログラマとして仕事をしているのはごく自然な成り行きだと思う。僕が2才とか3才のときに、家にあった8インチのフロッピーディスクにドライバー(プラスとかマイナスのドライバーね)で穴を開けたという話を何度も聞かされたし(きっと当時は高価なものだったのだろう)、まあ小さいころから、プログラマーとして才能を開花させるには十分な環境が用意されていた。
でもやっぱりプログラマが本分ではない。コンピュータゲームを作りたいからプログラムを勉強しただけだ。そしてここには僕の最大の長所がある。本分はゲームデザイナーであるのに自分自身でプログラムを書くことも出来るのだ。これはものすごく幸運なことだ。例えば、歌をうたうミュージシャンが自分で作詞作曲が出来て、しかもルックスまでかっこい!ってところかな(ひとつひとつの能力では劣るけど総合力が重要だ。)。実際プログラムが出来なかったらゲームの開発を仕事に出来たかどうかも怪しい。今だって猛烈に作りたいと思うゲームのアイデアを持っている。ゲーム好きだったらこういう人は多いと思う。しかし僕の場合は実際に自分で作ることが出来てしまうのだ。ゲームデザインを本分(すぐれたデザイナであるかは別にしても)としているにもかかわずプログラムまで出来てしまうだ。僕はいつもこの幸運に感謝しているのだ。ん、あれこんな話をしたいんじゃなかった。脈絡もなくどんどん話がずれているぞ。ほんとうは僕にとっての「Windows vs Linux」について書きたかったんだ。そしてそれはベッキーちゃんの話に行き着くんだけど、それはまた今度。。。
と、リーナスっぽくハッカー風に書いてみる。
[開発ログ]Murasamaシステム仕様書プロトタイプメモ
DBテーブル仕様
mrs_tbls.sql
大会運営フロー
user_mrs_data(ユーザデータ)準備。エントリする大会IDを入力しておく必要あり ↓ compe_state(大会)作成 ↓ compe_ranking(順位・成績テーブル)作成。user_mrs_data.compeIDでエントリ判定 ↓ compe_rankingの総合順位を更新 ↓ league_data,league_data_user作成(リーグ編成)。このときNPCを作成し空きにエントリさせる ↓ compe_rankingの総合順位を更新(NPCが追加されているので) ↓ compe_rankingのエントリリーグID,グレードを更新
[開発ログ]リーグ生成
リーグ生成処理が一部しっくりこない。
#----------------------------------------------------------------------------- # 大会ステータス # 新規は手動で作成。このレコードの存在=大会の存在である。 #----------------------------------------------------------------------------- CREATE TABLE compe_state ( ID INT primary key auto_increment, stageCounter INT not null default 1, dayMax INT, # 経過日数がこの値に達すると大会が終了し、新しいリーグが組まれる # 試合数ではなく休日を含めたあくまで日数 dayCounter INT, # 経過日数 # NULLだとリーグ新規作成 gameMax INT not null, # 奇数:1リーグの試合数。ここから1リーグの参加人数(gameMax+1)が決まる turn INT not null, # 同じ相手と戦う回数。ステージの試合数は(gameMax*turn) gameCounter INT not null, # すでに終了した試合数 schedule CHAR(255) not null, # 1,1,1,1,1,0,0,1,1,1,1,0 スケジュールリスト gradeMax INT not null, leagueNums CHAR(255) not null, # 1,3,9,0… グレード別のリーグ数。必ず最後が0 downNums CHAR(255) not null, # 3,3,3,3,… グレード別の降格人数 # 最後(最高ランク)の数字は基本的に0。1以上ならその人数が抜ける→NPCで補充 updatedTime TIMESTAMP, # 更新日時 creationTime TIMESTAMP, # 作成日時 ); #----------------------------------------------------------------------------- # リーグデータ #----------------------------------------------------------------------------- CREATE TABLE league_data ( ID INT primary key auto_increment, CompeID INT not null, # 大会ID StageID INT not null, # ステージ Grade INT not null, # グレード GroupID INT not null, # グループ WinAward INT not null, # 勝利時の賞金 DrawAward INT not null, # 引き分け時の賞金 state ENUM("Playing","After") not null default "Playing", UserList CHAR(255) not null, # teamid1,teamid2,teamid3,… エントリー順 # デバッグ用。正式にはleague_data_usersで管理される updatedTime TIMESTAMP, # 更新日時 creationTime TIMESTAMP, # 作成日時 UNIQUE (CompeID,StageID,GroupID,Grade) ); #----------------------------------------------------------------------------- # リーグデータユーザーズ # そのリーグにエントリしているユーザーのリスト #----------------------------------------------------------------------------- CREATE TABLE league_data_user ( UserID INT not null, LeagueID INT not null, EntryIdx INT not null, UNIQUE (userID,LeagueID), UNIQUE (LeagueID,EntryIdx), ); #----------------------------------------------------------------------------- # 順位テーブル # 順位とリーグ中の成績を記録。試合終了時に更新。 # インサートはリーグ更新時だけなので、過去の大会の順位ログが残っていく。 # # リーグ作成時にこのリストも作成される。 #----------------------------------------------------------------------------- CREATE TABLE compe_ranking ( userID INT not null, CompeID INT not null, # LeagueIDからも引けるが持っておく StageID INT not null, # LeagueIDからも引けるが持っておく LeagueID INT, Grade INT, ranking INT, # リーグ内順位 gRanking INT, # ランク内順位 cRanking INT, # 大会総合順位 win INT not null default 0, draw INT not null default 0, lose INT not null default 0, score INT not null default 0, UNIQUE (userID,LeagueID) ); #----------------------------------------------------------------------------- # 対戦データ # 試合の対戦記録。リーグ更新時にまとめて作成される。 # 試合が行われたときに更新される。 # スケジュールの役割も果たす。 # # 容量計算 # 4*4+3+80+80=179+index ≒ 200 # 5000(games) × 200(Byte) × 1000(days) = 1,000,000,000 = 1G # よって 1万人1000日稼動でHDD消費1ギガ #----------------------------------------------------------------------------- CREATE TABLE vs_data ( ID INT primary key auto_increment, LeagueID INT not null, DayCount INT not null, # 何日目に行われる何試か GameCount INT not null, # 何試合目か homeID TINYINT not null, # 試合会場のID homeUserID INT not null, awayUserID INT not null, homeScore TINYINT, # NULLなら試合が行われていないとみなす awayScore TINYINT, # NULLなら試合が行われていないとみなす UNIQUE (LeagueID,GameCount,homeUserID) );
leaguefactory.rb
#============================================================================= # リーグ工場 # # 新規にリーグを作成 # vs_data(対戦スケジュール)もここで作成 # 既存のリーグに途中参加のユーザを追加 # #============================================================================= class LeagueFactory #--------------------------------------------------------------------------- # ひとつのリーグを新規作成 # vs_data(対戦スケジュール)もここで作成 #--------------------------------------------------------------------------- def LeagueFactory.make(sql,compeID,stageID,member,grade) end #--------------------------------------------------------------------------- # 大会参加者全員分のリーグを作成 # # 順位順にソートし、上から順にグループに振り分ける # リーグのエントリに不足があればNPCを作成してエントリさせる #--------------------------------------------------------------------------- def LeagueFactory.make_all(sql,compeID,stageID) end end
ranking.rb
#============================================================================= # compe_rankingテーブルに対する操作を行う # # #============================================================================= class Ranking #--------------------------------------------------------------------------- # compe_ranking作成 #--------------------------------------------------------------------------- def Ranking.make_new(sql,compeID,stageID) end #--------------------------------------------------------------------------- # compe_ranking.cRankingを成績にソートした順位で更新する #--------------------------------------------------------------------------- def Ranking.update_cranking(sql,compeID,stageID) end #--------------------------------------------------------------------------- # leagueIDを設定 #--------------------------------------------------------------------------- def Ranking.update_leagueID(sql,compeID,stageID) end end
_test_all.rb
init_test(sql) CardDealer::deal_to_all(sql) stageID = -1 compeID = make_compe_state(sql) Ranking::make_new(sql,compeID,stageID) Ranking::update_cranking(sql,compeID,stageID) LeagueFactory::make_all(sql,compeID,stageID) Ranking::make_new(sql,compeID,stageID) Ranking::update_cranking(sql,compeID,stageID) Ranking::update_leagueID(sql,compeID,stageID)
明日もう一度考えてみよう。