こんばんは。ファガイです。
ソーシャルゲームの開発に関わってからもう8ヶ月くらい経ちます。
今回はそのソーシャルゲームの開発に関して詳しい話をします。でも分かってることだけです。今の会社でどんな感じの構成でソーシャルゲームを開発してるとか、そういうの。
開発環境とか。
基本的には、SAPによって変わりますが。
Apache or Nginx
PHP5.3~ 最近出来た会社とか新規プロジェクト系は多分PHP5.4を使ってるんだろうなとか思う
MySQL5.5とか
キャッシュとして良くMemcachedを使います。たまにredisをキャッシュとして使ってるとこもあります。
後は何やってるのかよく知りません。レプリケーションは勿論やってます。
開発ライブラリの全体像
フレームワークはCodeIgniterを使ってます。会社によってはCakePHPを採用してるところもありますね。一部ではFuelPHPを採用しているところもあるらしい。
基本的にはControllerにはBaseのコントローラが用意されていて、そちらに共通処理系は記述します。
コントローラーにはviewとの受け渡しに必要な情報を集めて、viewに渡してます。
コントローラーから直接Modelを叩くことも有りますが、一旦はlibraryを挟んで使用することが多いです。
静的データはCSV化してます。専用のロードライブラリを作ってます。
基本的に文章系はcsvに格納するか、iniで持っておく感じです。
キャッシュは良く積みます。積み過ぎないように気をつけます。
基本的には以下のような感じになります。
コントローラ→ライブラリのメソッド呼び出し→モデルのメソッド呼び出し→返ってきたデータをライブラリ内で必要な情報をくっつけたりして返す
開発中に注意してること
・PHPをそこそこ理解してる人なら分かるコードにする。
これ結構重要なんですが、最新の技術ばかり使いすぎて理解できる人が少ないと後々入ってくる人が分からない場合もあるので。
・出来るだけ分かりやすいコードを書く
まあこれは普通の話です。PHPDOCを付けるのはもう常識ですね。たまに付けない人も居るのでそういう人には付けたほうが良いです。
あとは、結構ソーシャルゲームって共通処理が多かったりする(例えばガチャとか合成とか)のでそういう時にはAbstructクラスを親に置いたりしますね。
・汎用的に使えるメソッドを用意しておく
基本的にこれはヘルパーとかの話ですが、ソーシャルゲームでは良く連想配列を扱います。ここらへんの変換系はたまに書きますね。たまにやるものだと、配列の中の1つのキーだけ取得してきたいとか。Modelのwhere_inとかに渡すときに使ったりします。
今ざくっと書いてみるけど、こういうのとかね。なんでもない普通のコード。
/**
* 配列の特定のキーだけを取得する
* @param array $data 二次元配列
* @param string $key 取得するキー
*/
function array_extract_key(&$data, &$key)
{
$ret = array();
foreach ($data as &$val)
{
$ret[] = $val[$key];
}
return $ret;
}
・inner joinは使わない、explain使ってSQLを最適化
基本、inner joinは絶対使いません。使う必要がある場合はサブクエリとかで対応します。あとはexplainコマンドを使って取得に問題が無いのかとか確認します。
ソーシャルゲームのためのMySQL入門 – Technology of DeNA
以前見て酷いと思った実装例
・セッターが必要ないのにセッターがある
これは面倒だった。
例としては(簡略化してます)
class LogicCard
{
private $user_card; // ユーザが所持しているカード
/**
* ユーザカードを取得する
* @return array
*/
public function get_user_card()
{
return $this->user_card;
}
/**
* ユーザカードをセットする
* @param int $user_id
*/
public function set_user_card($user_id)
{
$this->user_card = $this->user_card_model->get_user_card($user_id);
}
/**
* パラメータをセットする
* @param $key
* @param $value
*/
public function set_param($key, $value)
{
$this->$key = $value;
}
}
こんな感じですね。
ここで問題なのは一々セット用のメソッドを呼ぶ必要があること。途中で入ってきた人とかが面倒だなとか思ってこのLogicの中でデータをいっぺんにセットする系のメソッドを作り始められると崩壊していくことが見えてます。
因みに自分だったらこうしてる。といってもサンプルなのでこれが良いというわけでも無いです。
class LogicCard
{
/**
* ユーザカードを取得する
* @param int $user_id
* @return array
*/
public function get_user_card($user_id)
{
return $this->user_card_model->get_user_card($user_id);
}
}
はっきりいえばこれだけで良いと思う。今回、ユーザのカードを取得するという名目だったのでインスタンス内に持たせると不整合が起きないようにデータが追加されたら再度入れなおすという形をとっておかなくてはいけません。
この場合であれば、そのまま取得するようにしておけばいいでしょう。今回の例ではmodelそのまま読んじゃえば良いんじゃねってなってますけど、実際はこのデータに+してデータを付けてから返すとかあるので、このような形です。
・↑の状態に加えて、問題案と改善案は混ざったコードになっている
これ、やばいっすよ。訳がわからなくなります。ちゃんと統一しておかないと、せっかく書いてもらったコードが無駄になってしまいます。保守性的な部分としても問題案のほうは使わないほうがいいでしょう。
ほかにも色々とあったりしますがこれくらいにします。
ではではー。
コメント