C# Possibility for game development
現代において、大部分のゲーム開発者は、 C++ もしくは C (と若干のマシン語およびシェーダ)を使わなくてはいけません。これらの言語は、非常に強力であり、 C++ は、十分に生産的ですから、特に問題はありません。

しかし、私は、休日用に、他の言語を求めてきました。あらゆるゲーム開発者は、自身のゲームを開発することを望みます。しかし、それは、不可能なように思われます。ゲーム開発は、多くの時間を必要とするからです。大部分の開発者は、自身のゲーム開発より休暇をとって眠ることを望みます。

その目的のために、私は、最小のアーケードゲームを開発するのにいくらかのライト級のプログラミング言語を必要としました。それらは、休暇用の迅速なゲーム開発用の言語です。私は、 HSP 、 Python 、 Ruby 、 Java 、及び、ゲームエンジンのいくらかのスクリプトを試みました。(私は、一度だけ会社の仕事で Java を使ったことがありますが、二度とゲーム開発には使いたくありません)

そのようにして、私は、多くの言語を試みました。しかし、私は、いつも同じ結果を得ました。C++ がゲーム開発においては世界上で最も生産的な言語であるということです。そこで、私は、 boost ライブラリと OGRE をチェックし始めました。

しばらくして、私は、 Managed DirectX と C# 2.0 に出会いました。 Managed DirectX は、 DirectX のマネージドライブラリ版です。C# 2.0 は、 Generics 機能を持つ C# の拡張です。私は、これらが現在最も良い答えである、と思いました。そして今、マイクロソフトはゲーム開発のために調律された .NET 製品である XNA フレームワークと XNA スタジオを提供します。

C# は、低パフォーマンスです。C# や Java のような、 GC 機能を持つ言語は、リアルタイム処理に対する適性を持っていません。私が XNA との最初の接触を持っていたとき、私は、 XNA と C# はなんらかの方法で GC の問題を克服したのだと考えました。しかし、 XNA は、やっぱりひどいパフォーマンスです。

しかしながら、私も他の開発者も、それに関して同じ結論にたどり着いています。その結論は、我々が GPU 至上主義者であるべきであることです。GPU 処理では、 C++ と C# に、パフォーマンスの違いはありません。GPU が物理学等々を計算し得るというアイデアは、いくらかの本にあります。しかし、それは、生産的な方法ではないかもしれませんが...
|
ESruts
このサイトは、私のエントリによって作られたサンプルのコレクションです。そのリポジトリは、 Cube Legacy の最新のバージョンで動作可能な状態をキープされているサンプルを持っています。

私は、今まで多くのサンプルを書きました。しかし、それらの大部分は、最新のバージョンにおいて動作しません。なぜなら、 Cube Legacy は、その仕様を変えたからです。私は、それらとそれらのドキュメントをフィックスする協力者を必要とします。パッチ追跡者システムは、 XOOPS Cube プロジェクトのそれと同様に、あなたのパッチを受けます。そして、あなたが母言語の翻訳をコントリビュートできるのであれば、 UTF-8 でメールを私に送ってください。私の電子メールアドレスは、 minahito at users.sourceforge.jp です。
|
Cubson has gone to sourceforge.jp
私は、sourceforge.jp XOOPS-Shade プロジェクトページへ cubson の全資源を動かし始めました。しかし私は、sourceforge.jp においてプロジェクトページを作ってしまったことを後悔しています。

Sourceforge.net は、 sf.jp より良いリポジトリです。それは、私達にとって最良のソリューションです。なぜなら、 sf.net は、多くの優れたフィーチャーと UTF-8 を持っているからです。英語は、 sf.jp においても利用可能です。しかし、このリポジトリを世界の仲間に薦めたいと考える人はいないでしょう。

しかしながら、私は、名前に
XOOPS Cube を含んでいながら活発度 0% のプロジェクトページを持つことを望んでいません。従って、私は、 cubson が良い国際的ツールであろう状態になるまで、 sf.jp XOOPS-Shade プロジェクトを保持し続けるでしょう。それから、我々は、これらのページを sf.net に動かすでしょう。

もちろん、私は、英語で書かれたあなたのメッセージを歓迎します。そして、私は、英語でドキュメントの準備をするでしょう。
cubson に関する URLs は、下記です。

Project top page

リリースニュースは、このページにあります。Sf.net は、 RSS を公表し得ます。しかし、 sf.jp は、それをすることができません。うーん、これらのニュースは、現在日本語オンリーです。私は、十分なメンバーを集めるために日本人のための容易なニュースを必要とします……うーん

Forum

あなたは、 Google adsence の位置に驚くかもしれません。このサイトは、アフィリエイトサイトのように見えます。しかし、これは、私達のディスカッションフォーラムです。記述は、あなたのアカウントを必要とします。あなたが sf.jp にあなたのアカウントを持っていないならば、登録しましょう。

Bug Tracker

これは、 cubson のためのバグ追跡者システムです。あなたは、そこで報告するのにあなたのアカウントを必要とします。

Wiki

これは、英語では難しいもののうちの 1 つです。なぜなら、この Wiki は、日本語のためのものだからです。しかし、私は、お粗末な英語で多くのドキュメントを書いてきました。私は、 sf.net における将来のプロジェクトページに備えてそれらを準備します。この wiki は、フリーであり、そして、あなたは、あなたのアカウントを必要としません。
|
Detailed commentary on the sample message module

Installer

このモジュールは、 PM と交換されますので、このモジュールが PM の現存するデータを移動させることができればベストです。そのような目的のために、 XOOPS2 ではモジュール開発者は onInstall スクリプトを使用します。Legacy 2.1 では、カスタムインストーラが利用可能です。カスタムインストーラは、 xoops_version において宣言された特定のクラスです。通常、そのクラスは、コントロールパネルにおけるインストール機能によって使われるインストーラクラスのサブクラスです。

$modversion['legacy_installer']['installer']['class'] = "Installer";

これは、正式なクラス名ではありません。正式なクラス名は、この宣言と dirname によって生成される合成名です。それは {Dirname}_{class} です。この場合、正式なクラス名は、 "Messgae_Installer" になります。そのクラスは、 admin/class/{class}.class.php において定義されなければなりません。

命名規則は、複写可能なモジュール、及び、
D3 モジュールのためのいくらかのオプションや例外を持っています。詳細は Legacy_ModuleInstallAction のコメントを見てください。

モジュール開発者は、カスタムインストーラによってインストールプロセスの全てをコントロールすることが可能です。
onInstall より優れた仕様は、柔軟性、及び、ロギングです。インストーラクラスは、そのメンバープロパティとしてログインスタンスを持っています。それを通じて、このモジュールは、マイグレーションに関するメッセージをユーザーに示します。これらのメッセージは modinfo.php において定義されています。

Kernel handler hook

プライベートメッセージは、 Legacy 2.1 の任意の仕様です。しかし、それは、他のフィーチャーにおいてはポピュラーな仕様です。例えば、悪名高き XoopsMultiMailer は、メール、及び、メッセージを抽象化します。同じく通知機能は、プライベートメッセージを使います。これらのクラスは、メッセージを送るためにカーネルのプライベートメッセージハンドラを使います。従って、このモジュールはこのハンドラをフックしなければなりません。どうすればよいでしょうか ?

答えはデリゲートを理解することにあります。カーネルのハンドラは、フライウェイトパターンの一種である xoops_gethandler() を通じて取得されます。 xoops_gethandler() は、デリゲートイベント "Legacy.Event.GetHandler" を備えています。従って、プリロードで関数をこのイベントに加えることによってそれをフックすることが可能です。それによって、 xoops_gethandler() は、プライベートメッセージハンドラを得るためのリクエストに対して、このモジュールのアダプタクラスを返します。それは、興味深いです。kernel/privmessage.class.php を見てみてください。

Note

xoops_gethandler() は、キャッシュを持っています。だれかが preBlockFilter() の前にプライベートメッセージハンドラを得るならば、イベントは、プライベートメッセージハンドラのために、二度と呼び出されないでしょう。

プリロードをプライマリプリロードとして指定可能な状態につくっておくことはよい解決策になります。
|
When is RC released?
開発チームはRCの基準が何であるかに関して議論しています。 多くの開発者がRCバージョンに固定APIを要求するでしょう。しかし、それをするためには、多くの実例が必要です。この年末に、それらを開発するために空き時間を保つことはかなり困難でしょう。

しかしながら、私は、1つのバグと3つの設計ミスを、昨日のあの程度のサンプルモジュールを通じて発見しました。ですから、実例を開発するということは本当に重要です。 XOOPS Cube Legacy2.1には、ソフトウェアデザインの他の問題があるかもしれません…

しかし、十分時間のある人なんていません。非常に難しい問題です。
|
Sample: The Advanced Private Message
私は、このサイトの XOOPS 開発者リングの次のリンクを tohokuaiki 氏に変更しました……といいますのも、 gusagi 氏のサーバは、壊れてしまったからです。私は、彼のサーバに哀悼の意を表します。

さて、ここに Legacy 2.1 のためのサンプルモジュールがあります。「message」モジュールは、進歩したプライベートメッセージモジュールです。それは、送信ボックス、草稿ボックス、プレビューを可能にします。

あなたは、このサンプルによって次のものを学ぶでしょう :
  • どうやって Legacy 2.1 のカーネルハンドラをフックするか
  • ログと共にある Legacy 2.1 時代におけるインストールスクリプト
  • User-Control-Event の応用
  • Legacy 2.1 のための共通インタフェースとしての仮想サービス
  • cubson 0.52.3 のサンプル(あなたが cubson ユーザーであるならば)
  • そして、 Cube の換装コンセプトの一端

あなたは、このモジュールを動かすのに Cube Legacy 2.1 の最新のスナップショットを必要とします。
ダウンロードページからこのモジュールを得てください。

インストール方法

  1. あなたが pm モジュールをインストールしたならば、それをアンインストールしてください。
  2. このモジュールをインストールしてください。
  3. 現存するメッセージは、インストールスクリプトによって自動的にマイグレーションされます。
|
UTF-8 Language Manager for Legacy System (2)
昨日のテスト版 UTF-8 言語マネージャは、 global.php を UTF-8 に変換していませんでした。nobunobu さんが、パッチを私に送ってくれました。私は、 nobunobu さんのパッチをマージすることによってバージョン 0.02 をアーカイブしました。

言語マネージャが global.php を変換しなければならないので、 global.php において定義されるオリジナルの _CHARSET を使うことは、不可能です。そこで、言語マネージャは、設定ファイルの情報、または、言語マネージャクラスの組込固定情報を使うようになりました。

Verison 0.02 では、組込固定情報として日本語 ( EUC-JP ) 、及び、韓国語 ( EUC-KR ) があります。設定ファイルによってこれらの情報をオーバーライトすることが可能です。もちろん、他の言語を加えることもまた可能です。

[Module_Utf8LangMgr]
multibyte=chinese,korean,japanese
chinese=big5
korean=...
|
UTF-8 Language Manager for Legacy System (1)
私は、 Legacy System 2.1 用の汎用 UTF-8 Language Manager を開発しました。あなたはダウンロードページからこれをダウンロードできます。これは、まだテストバージョンです。そして、あなたはこのモジュールのアクションフィルタがモジュールプリロードより早く働かなくてはいけないため、特別な方法によってこれをインストールしなくてはいけません。しかし、それは、非常に容易です。

Step1... 事前条件の確認

このモジュールは、 UTF-8 エンコーダとして Utf8LangMgr_LanguageManager をあなたのサイトに提供します。しかし、このモジュールは、インストーラには何の影響も与えません。従って、あなたは、自分で UTF-8 データベーステーブルを作成しなければなりません。しかし、各モジュールの言語ファイルを変換する必要はありません。

Step2... モジュールの配置

他のモジュールと同様に、 /modules にこのモジュールのディレクトリを置いて下さい。

Step3... 設定の変更

Legacy パッケージの構成は、 /settings/site_default.ini.pnp に書かれています。あなたは、そのファイルに優先プリロードとしてこのモジュールのプリロードを指定しなければなりません。XOOPS Cube がオーバーライド設定機能を持っているので、 site_default.ini.php を直接修正する必要はありません。/settings 内で site_custom.ini.php を作成して、そして、下記のように書いてください。

<?php
/**

[Legacy.PrimaryPreloads]
SetupUtf8LangMgr=/modules/Utf8LangMgr/preload/Primary/SetupUtf8LangMgr.class.php

*/
?>

完了です。トラブル報告は xoopscube.org フォーラムのスレッドにお願いします。

覚え書き

あなたのサイトがマルチバイト言語を用いるならば、あなたは、 charcode をこの言語マネージャに通告しなければなりません。私が知っているいくらかの言語の Charcode は、このモジュールの優先プリロードに含まれます。しかし、それが自動的に解決されないならば、あなたは、 site_custom.ini.php に記述を加えなければなりません。

[Module_Utf8LangMgr]
japanese=EUC-JP
korea=...

このファイルにおける設定は、自動ソリューションより早くこの言語マネージャに適用されます。
|
Smart Update Summary (3)

Status

update() メソッドが全ての情報構造体のステータスを変更した後、smartUpdateAllOfBlocks() はこれらのステータスをチェックしながら DB を変更していきます。どのように DB が変更されるかはステータスによって決定されます。

smartUpdateBlock_kindsofstatus

Loaded

情報構造体はロードされています。そして、この情報と最新コレクションの別の情報には違いがありません。したがって、この情報に関して DB を変更する必要はありません。

Updated

情報構造体と別の情報には違いがあります。そして、この情報はもう一方の情報によって既に更新されています。従って、この情報に関するデータベースのレコードを更新する必要があります。updateBlockByInfo() はそのためによいユーティリティメソッドです。

Order Updated

情報構造体と別の情報は同じ内容です。しかし、ただオーダーのみが異なります。従って、この情報に関するレコードのオーダーフィールドのみを更新する必要があります。なお、ブロックにはオーダー情報はありません。このステータスはプリファレンスのみに適用されます。

New

現在のコレクションがある情報を持っていなかったとき、それは現在のコレクションへ追加されます。そして、その情報のステータスは 'New' に変更されます。この場合、 DB にそれを挿入する必要があります。InstallBlockByInfo() はそのために良いユーティリティメソッドです。

Deleted

この情報構造体が最新コレクションの中でみつからなかったので、この情報のステータスは'deleted' に変更されています。この場合、それを DB から削除する必要があります。 uinstallBlockByInfo() はそのために良いユーティリティメソッドです。

結論

smartUpdateAllOfBlocks() smartUpdateAllOfPreferences() は非常に便利です、なぜならそれらは私がここ最近で説明した十分なプロセスを実装しているからです。ほとんどの場合、あなたはアップデート処理をこれらのユーティリティメソッドに委ねることができるでしょう。しかし、もしあなたがあなたのフェイズド・アップグレードの中で高度なアップデートを必要とするのであれば、あなたはこれらのクラスを理解するべきです。
|
Smart Update Summary (2)
Smart update for blocks is good to understand the basic activity of these classes. smartUpdateAllOfBlocks() is in Legacy_InstallModuleUtils.

smartUpdateBlock_act01

  • Gets the current collection from DB with ModinfoX2DBReader.
  • Gets the latest collection form xoops_version with ModinfoX2FileReader.
  • Update the current collection with the latest collection.

In these process, the current collection merges the latest collection without losing values if at all possible.

Let's see BlockInfoCollection::update().

    function update(&$collection)
   
{
       
foreach (array_keys($this->mBlocks) as $idx) {
           
$t_block =& $collection->get($this->mBlocks[$idx]->mFuncNum);
           
if ($t_block == null) {
                
if (!$collection->funcExists($this->mBlocks[$idx])) {
                    
$this->mBlocks[$idx]->mStatus = LEGACY_INSTALLINFO_STATUS_DELETED;
               
} else {
                    
$this->mBlocks[$idx]->mStatus = LEGACY_INSTALLINFO_STATUS_UPDATED;
               
}
           
}
           
elseif (!$this->mBlocks[$idx]->isEqual($t_block)) {
               
$this->mBlocks[$idx]->update($t_block);
           
}

Deleted

}
       
       
foreach (array_keys($collection->mBlocks) as $idx) {
           
$func_num = $collection->mBlocks[$idx]->mFuncNum;
           
if (!isset($this->mBlocks[$func_num])) {
               
$this->add($collection->mBlocks[$idx]);
               
$this->mBlocks[$func_num]->mStatus = LEGACY_INSTALLINFO_STATUS_NEW;
           
}
       
}
   
}

BlockInfoCollection::get() is useful to check whether another collection has the same information structure as this collection. If another collection doesn't return an instance with the same key, this block has been deleted in the latest version. In this case, changes the status of the information to "deleted". Because the collection doesn't know how to delete data from a resource, it doesn't have the process to delete. There are several kinds of status.
|
Smart Update Summary (1)
Legacy_ModuleInstallUtils クラスはインストールのための静的メソッドを集めています。このユーティリティの smartUpdateAllOfBlocks() と smartUpdateAllOfPreferences() はブロックとプロパティを迅速に更新します。

この更新プロセスは XOOPS2 および XOOPS2 JP においては厳格ではありませんでした。しかし、 Legacy 2.1 はそれを厳格にしました。私はここに「賢いアップデート」の仕組みを書こうと思います。モジュール開発者はそれを学習する必要はありませんが、もしあなたがカスタム-インストーラを使おうとするのであれば、知っておいた方が良いでしょう。

ユーザーがモジュールを更新しようとするとき、モジュールは2つの情報……DB(現在)と xoops_version (最新)を持っています。アップデートとは DB の値を失う事なく DB を xoops_version で交換するプロセスです。

Smart-update は現在のモジュールのコンフィグレーションと、最新のモジュールのコンフィグレーションの差異を認識します。そのために多くのクラスが定義されています。しかし、これらは一般的なパターンですので、簡単に理解できると思います。

smart01

Legacy_BlockInfomation と Legacy_PreferenceInformation は値を保持し、値を他の構造体と比較するシンプルな構造体です。isEqual() は別の構造体と値を比較します。update() は別の構造体と値をマージします。

smart02

各情報構造体のためにコレクションクラスがあります。コレクションクラスは複数の構造体を保持し、それらを別のコレクションと比較します。 add() は指定された構造体をソートしながらコレクションリストに追加します。update() は別のコレクションと構造体を比較してマージします。

smart03

これらの情報構造体もこれらのコレクションクラスもいかなる保管資源とも結び付いていません。すなわち、これらは DB も xoops_version も参照しません。それをするのはリーダークラスです。リーダークラスは DB や xoops_version といった保管資源をロードすることでコレクションクラスのインスタンスを構築します。将来、新しいフォーマットが登場した場合は、新しいリーダークラスを追加すればよいわけです。
|