サンゴラボ

4年目ソシャゲエンジニア

Atomコードリーディング Part 1

目的

GUIアプリのアーキテクチャを学ぶ

最近、SPAやらネイティブアプリやらで、GUIアプリの作成力が求められてる気がする。なので、Atomを教材にしてGUIアプリケーションのアーキテクチャを勉強したいと思った。Atomの実装はいいものと仮定して進めてくけど、まあ大丈夫だと思ってる。昔だったらEclipseNetBeansが勉強になったのかな、とか考えてたけど、自分には辛そう。

あと、アプリケーションのソースコードだけじゃなくて、ビルドとか開発フローとかも見ておけば参考になるんじゃないかと考え中。大規模アプリだとこの辺りも重要ということで。

エッジな技術の使われ方をみる

AtomがReactやらShadow DOMやらを使ってるというのは有名だと思うけど、そういったものがどこでどう使われるのかをちゃんと見ておきたい。Atomでxx使い始めたよ~、と聞いたらすぐに追えるようにしておきたい。Atomならフロントエンドで面白そうなことはだいたい実践してきそうな感じはある。あと、使われてるライブラリとかもその都度調べたい。

自分が使ってるエディタの中身を知る

自分で使ってるエディタの中身を理解して、あわよくば自分で改造してみたい。普段WebStormを使っていたんだけど、最近のフロントエンドの流れについていくにはエディタを自分でいじるしかない、と感じたのも動機のひとつ。ライセンス料払ってるのに常にEAP版使っているのは、ちょっともどかしい。

そんな感じで端からゆっくり読んでいく。見てるソースのバージョンどんどんあがっていくと思う。とりあえずコードリーディング開始時のコミットをメモ。Atomのバージョンでいうとv0.188.0くらい。

ビルド

アプリのソースをみるだけなら、エントリーポイントから見ていけばいいんだけど、ビルド周りも見ておきたいので、ざっくり流れを追っておく。

ビルド方法

ドキュメントに載ってる。とりあえずスクリプト実行すれば、Applications以下にAtom.appができる。

git clone https://github.com/atom/atom.git
cd atom
script/build # Creates application at /Applications/Atom.app

script/build

簡単なjsスクリプトscript/bootstrapを実行して、gruntのbuildタスクを実行している。

script/bootstrapはざっと見たところnpmやapmの依存パッケージをインストールしている。

Gruntfileとしてbuild/Gruntfile.coffeeを指定している。gruntもgulpみたいにCoffeeScriptをサポートしていたんですね。

Grunt

build/Gruntfile.coffee自体にはconfig系を定義してるくらいで、個々のタスクはbuild/tasks/*-task.coffeeなどにある。もうgrunt使ってないけど、タスクの分け方は結構参考になる。

buildタスクはその名の通りbuild/tasks/build-task.coffeeにある。buildタスク自体はcompilegenerate-license:savegenerate-module-cachecompile-packages-slugタスクに依存してる(macならcopy-info-plistタスクにも依存)。

compileタスク自体はGruntfile.coffeeにある。

grunt.registerTask('compile', ['coffee', 'prebuild-less', 'cson', 'peg'])

coffeeタスクだけ確認しておく。

coffeeConfig =
  glob_to_multiple:
    expand: true
    src: [
      'src/**/*.coffee'
      'exports/**/*.coffee'
      'static/**/*.coffee'
    ]
    dest: appDir
    ext: '.js'

appDirmacだと/Applications/Atom.app/Contents/Resources/app/になる。それ以下に出力されたjsファイルが置かれる。

他にもたくさんgruntタスクがあるけど、必要になったら見る。

起動

atomコマンドのシェルスクリプト見たけど、よくわからなかった。まあ、起動はatom-shellがやってくれるはず。

ドキュメント見てたら、atom-shellのチュートリアルにメインプロセスについて書かれていた。

package.jsonmainスクリプトを実行するプロセスがメインプロセス(main process)と呼ばれるみたい。mainには./src/browser/main.jsが指定されてるので、これがエントリーポイントだと考えてよさそう。

メインプロセスから実行されるスクリプトはウェブページを生成することによりGUIを表示できる。

atom-shellはウェブページを表示するのにChromiumを使っていて、ウェブページそれぞれにもプロセスがある。それはレンダラプロセス(renderer process)と呼ばれる。

2つのプロセスの詳細な違いは必要になったら調べる。

src/browser/main.coffee

エントリーポイント。start関数が定義されていて、それが実行される。

start関数でやってること

CoffeeScriptのキャッシュは特に追ってない。coffee-cashというものを使っていた。キャッシュディレクトリを指定して登録しておけばファイル単位でキャッシュしてくれるみたい。なんか便利そう。

コマンドライン引数のパースはsubstack氏のoptimistというライブラリでやってた。便利そうなので、コマンド作るときに使ってみたい。開発時に使えそうなコマンドオプションにdevモードがある。コマンドオプションの使い方がわからなかったら、この辺り読めばすぐわかりそう。

appモジュールというのはatom-shellアプリケーションのライフサイクルをコントロールするやつみたい。ライフサイクル系のイベントの発火もしてくれる。ここではreadyイベントはハンドラを設定してる。readyはその名の通りatom-shellの初期化が終わったところで発火する。

readyハンドラではsrc/browser/atom-applicationをrequireして、それのopenメソッドを呼んでる。いよいよ始まりといった感じがする。

app.on 'ready', ->

  # ~ 省略 ~

  if args.devMode
    AtomApplication = require path.join(args.resourcePath, 'src', 'browser', 'atom-application')
  else
    AtomApplication = require './atom-application'

  AtomApplication.open(args)
  console.log("App load time: #{Date.now() - global.shellStartTime}ms") unless args.test

最初に頑張っても続かないので、続きはあとで


参考

ソシャゲ会社に入って2年ちょっとくらいのまとめとこれから

ソシャゲ作ってる会社に新卒で入って今年で3年目になった。このブログは入社当時になんかアウトプットしなきゃと思ってつくったものなんだけど、最近はまったく書いてないし、存在すら忘れてた…

定期的にアウトプット衝動に駆られるけど、普段からやってないからなかなか書けない。今回は、そのアウトプット衝動と帰省が重なって暇だったので、なんとなく書いてみた。だから、普段mac使ってるけど、実家のWindows使って書いてる。OSはいいんだけどJISキーボードつらい、ソフトもいれたくないからMarkdownはChromeのエクステンションを使ってる。

何書くかなあ?と思ったけど、久しぶりだし、会社入ってやってきたことのまとめとか環境や思考の変化を書いておく。ソシャゲエンジニアとしてはレアケースな気がしている。

心機一転してブログとか書こうとすると、過去記事を一気に消したくなるけど、今回は残しておく。今見ると、ああ…とか思う。

概要

  • ソーシャルゲーム作ってた会社の環境は変わり続けてる(ブラウザとネイティブの話)
  • フロントエンドエンジニアである僕自身が環境の変化にどう対応していくか
  • おもしろいと思ってることがあるので、やれるうちはやる

やってきたこと流れ

1年目

研修があったので本格的に現場に入っていったのは7月くらい。ガラケースマホ向けのいわゆるソーシャルゲームを作っていて、技術的にはLAMPとHTML/CSSでオーソドックスな感じ。Flashが多用されていること以外は一昔前のwebページと大差ない。JavaScriptはほとんどなかった。

Flashアニメーションすげーとか負荷つれーとか思ってた。とあるプロジェクトでインフラはやらないけど、サーバサイドからフロントエンドまでやって、つらい運用を経験できたので結構ためになった。オーソドックスなwebだったので、聞いたことがない技術はほとんどなかった。知らなかったのはFlash合成くらいかなあ?

自分の知ってるwebじゃないと思いながらスマホ向けにJSいじってたのもこの時期。コピペじゃないJSを書いてるひとなんていなかったんじゃないかなあという印象がある。外を見ればクライアントサイドMV*、altJS、SPAあたりがちょこちょこ出てきてたと思う。SPAはワードとしては定着してなかった。個人的にこのあたりに一番興味をもっていて、実際に大規模なアプリ作りたかったので、勉強して社内SNSで煽ったりしてた。当然、生意気だったわけだけど、僕の話を拾ってくれる先輩方がいたので、ありがたいなと思ってた。生意気だけど、そこそこできる新卒くらいには思われていた気がする。

市場的にはブラウザが大きくてネイティブはパズドラくらいしか出てなかった。業界の雰囲気はネイティブの流れが少しあった。まあこの時期にちゃんとしたネイティブゲームを仕込んでいた会社が現在ストアでトップランカーになってるんだけど…

2年目

優秀な後輩が何人か入ってきた。みんな今では貫禄がでてきてたくましい。

自分の業務についてはあまり記憶がない。確か運用プロジェクトは抜けていた気がする。1年目の煽りが効いたのか、新規ブラウザゲームで大規模なHTML5を使って作ることになったんだけど、僕はタイミングが悪くて入れなかった。プロジェクトには入れなかったけど、個人的に勉強は続けてた。

市場はパズドラがすごい勢いだった。他には黒猫のウィズとかブレフロとかが出始めてはやり始めてた。2年目後半はすでにネイティブばっかりになってきてて、ブラウザはカードバトルとリアルタイムGvGくらいしか出てなかった。

そういった流れもあってか、業務でネイティブを触る機会がきて、Cocos2d-xでモックみたいの作ってた。何かゲームが出たわけでもなく、僕自身も何をアウトプットしたのかわからないけど、いろいろ気づきはあった。以下気づき

  • ゲームプログラミングとやらが必要になってきた
  • ネイティブつらそう、ブラウザゆるふわ
  • C++は僕には早かった

1つ目は、メインループとかシーンとかゲームプログラミングの用語がいっぱい出てきて、圧倒されたことが始まり。プログラミングを始めた頃にゲーム作ったりしてたので聞いたことがないわけではないけど、しばらくブラウザゲーム作ってたので忘れてた。ブラウザゲームはwebアプリと変わらないし、基本イベントドリブンで書けるのでメインループなかった。

2つ目は、実際に運用となるとネイティブはつらそうだなということ。主に更新性とUI関連なんだけど、ネイティブやっても結局はブラウザとHTMLみたいのが欲しくなるなと考えてた。

3つ目は、急にネイティブでモック作る仕事が来たときの話。期間と僕のスキルを考えて無理だなと思ったので、Cocos2d-xのJavaScript Binding(現在はCocos2d-JS)というのを使った。もともとCocos2d-xの組み込みスクリプトLuaとJS)の設計思想がいいなと思っていたのも選んだ理由。モックを提出した後にネタバレしたけど、バレてなかったので結構使えるなと思ったのも気づきのひとつ。C++が僕には早かったというかほとんどやっていないというのが実際のところ。モックといえど、それなりに仕様が盛り込まれてたので、ソースコードは結構増えてた。この時、このプログラミングじゃスケールしないと思ったことは1つ目の気づきと共通している。

そんな気づきがありながら、2年目の終わりの方で運用中のブラウザタイトルに戻った。このあたりで役割的にはJavaScriptを書くフロントエンドエンジニアになった。

3年目

また後輩が増えた。すごい優秀。

業界的にも会社的にもネイティブの流れが加速してる感じ。それで、2年目のときからだんだん増えてたけど、コンシューマー出身者がすごい増えてきた気がする。同時に嗅覚の鋭いwebエンジニアは他に移っていた印象がある。

ゲームプログラマとwebエンジニアは結構コンテキストが違う。今のスマホゲーム業界はそんな異なるコンテキストが入り乱れてる感じ。サーバサイドは今のとこどっちでもあまり変わらないけど。

僕自身はブラウザタイトルにいるけど、ガッツリ運用に入っているわけではない。いろいろ実験できるような環境にいるので、何かしらアウトプットして貢献しようとしてるのが最近の動き。簡単に言うとブラウザでもちゃんとしたゲームを作れるようにしたいということ。ブラウザというプラットフォームを使ってゲーム作り(設計からプログラミング)を学びたいと言ったほうがしっくりくる。ブラウザゲームも求められるレベルが上がって、遊びの要素が増えてくると思うので、今のうちやっておきたい。まあ市場に投資をしても仕方がないとなったら引き上げだけど、まだちょっとはやれそう。

こんなこと言ってるとブラウザでネイティブに勝ちたい奴、みたいに思われるかもだけど、ちょっと違う。ブラウザでもネイティブでもやることは本質的に一緒だと思っていて、僕自身が付け入る隙がありそうだからブラウザでやってみる感じ。まあ、それブラウザでよくね?というネイティブゲームがいっぱいあるから、そういうのはブラウザで作ろうよと提案していきたいとは思う。

今必要なこと

ゲームの作り方

上で書いたけど、これは主に設計やプログラミングの話。こういうのは、スクールガールストライカーズの 内製クライアントエンジンみたいにあるとこにはあるんだけど、民主化はされてない。僕が必要としているのはエンジンの設計みたいな低レイヤーのとこではなく、もっと高いレイヤーのとこなんだけど、まだ見つからない。Cocos2d-x入門・Unity入門という本があるとしたら、それらには書いてないようなあたり。Game Programming Gemsに全部書いてあるから読めば?、というのではなくてもうちょっとカジュアルに取り入れたい。このあたりはオープンなweb業界とは違うとこだなと感じてる。

ちなみにスクストの資料に書いてあることはコンシューマー出身なら当たり前のことなんだそうな。当たり前のことをちゃんとやってる感じらしい(ゲームプログラマー怖い

web技術との融合

とりあえずはブラウザ向けに作っていくので、単純にゲームプログラミングをやってれば済むというわけではない。最終的にHTML/CSS/JavaScriptにどうやって落とし込んでいくのかを考える必要がある。このあたりは流れが速いので追っていくのがすごくたいへん。最近だとビルドツールが熱い。サーバも同様にちゃんとする必要がある。

残念なこと

  • ゲームコーディング・コンプリートが欲しかったんだけど、地元の本屋には売ってなかった
  • いきなり長文書いたのでブログが続かないかもしれない

jQueryプラグインの作り方メモ

jQueryプラグインを作るときにいろいろつまずいたのでメモを残す。
一応ひな形みたいなのがあるらしいけど、プラグインによって全然書き方が違うから、どれが正しいのかわからん。

プラグインのひな形

jQuery プラグインの定義パターンについて調べてみた - Cyokodog :: Diary
このまとめはかなり参考になりました。自分が採用したのは2.7の書き方です。javascriptっぽいし、インスタンスでパラメータを保持できるとこがいいですね。実際のソースコードとしては、リンク先の例にあげられているjQuery Calendarがわかり易かった。初期化、オプションの渡し方、メソッド定義など、とても勉強になると思います。

右も左もわからない場合は、以下の記事も読む。
WIZARD-CODE ウィザード・コードのブログ | WIZ-CODE.blog

thisについて

jQueryのプラグインをつくってみよう - 馬鹿と天才は紙一重
javascript使いこなすにはthisの理解が不可欠だと再認識しました。jQueryプラグインを作るときもとても重要。
参考記事はthis以外にも重要なことが書いてあるので、プラグイン作るときは読むといいかも。dataメソッドは結構使えます。

extend

jQuery.extend マニアックス - てっく煮ブログ
extendメソッドよく使うので一読。オプションをセットするときに使う。

イベント関連

iPhone/Android/PC 対応。jQuery で書くタッチイベント (フェンリル | デベロッパーズブログ)
web帳 | スマートフォン JavaScript タッチ、フリックイベント実装
作ってるプラグインがスマホ用なので、タッチ系のイベントを勉強する必要がありました。
AndroidiPhoneで挙動が変わるのでよくわからんw