働クリッカーという JS を学べるゲームを作りました。
どんなゲームなの?
働クリッカーは、身も蓋もない言い方をすればクッキークリッカーがつまんなくなったやつです。
画面左側の『働く』ボタンを連打してお金をためて、資格やプログラミングスキルを買って一働きの単価を上げ、アフィリエイトや土地、株を買って不労所得(働くを押さなくても入ってくる金)を増やしていくというゲームなのですが、このゲームの肝はそこではなく、どれだけ高速にゲームクリア実績や全実績解除を達成できるか、というプログラミングによる攻略が本質的な所です。
俺が、俺達が TAS さんだ
Tool Asisted Speedrun(or Superplay) という、ツールによる補助を受けたスーパープレイの動画は、多分見たことがあると思います。あれはエミュレーターそのものにそういう機能があったりするんですが、このゲーム、働クリッカーの場合は、ゲームそのものにツール機能が組み込まれています。というか普通に js でゲームの挙動を操作出来ます。
技術的な話を先んじて少ししてしまうと、働クリッカーは Electron 製なので普通に Node.js も動くし、Node.js 組み込みの vm モジュールも動くし、特に何も考える必要なく、ゲーム上に js の実行環境を用意してあげられるというわけです。
制作に至るまでの流れ
- PHH の体験授業せねば
- 体験授業で js 書いて欲しいよなー。まぁ手軽だし Chrome の Developer Tools で js 体験でええやろ
- よくよく考えたらあんな謎画面をいきなり初学者に見せたら心折りにいってるパワハラ教師やんけ
- とはいえ、用意された素材を組み合わせてゲームができたねーみたいなのは、逆に気持ち悪い……
- 昔ゲームで何が楽しかったかな……
- バグ……チート……
- そうだ、チート前提のゲームつくろう!
という流れで『js でチートするゲーム』という何がどうゲームなのかわからないけどとにかくゲームって言いはったらゲームみたいなゲームを作ることになりました。
製作期間は v1.0.0 までに大体3日ほど。 v.1.1.0 までにブラッシュアップするのに+2日ほどと、案外お手軽にできています。 Electron は js と HTML5 でアプリケーションを書いたことがって、かつ Node.js を触ったことがあればさほど難しくはないです。欲を言えば Chrome Extension を書いたことがあるとなおわかりやすいと思います。
最初にとりあえず動いた時は音も出ないし実績もない、みたいな感じだったんですが、 @sifue からフィードバックを受けて改良。音も出るし実績も取れる、とだいぶゲームらしくなりました。
なぜ、 Developer Tools がダメで、働クリッカーなのか
よくよく考えたらあんな謎画面をいきなり初学者に見せたら心折りにいってるパワハラ教師やんけ
先に言わせて。世の中で使われてる Developer Tools を使ったプログラミング教育に文句はない!!!
ただ、僕の生徒たちって高校生で……体験授業を受ける時点では中学三年生なのです。中学三年生って、多分人生で一番英語が嫌いになる時期なんじゃないかなと思っていて、中学校から始まった英語教育で躓く子や、ついてはいけてるけど丸暗記で、見覚えのない単語を怖がる子がたくさんいるだろうな、と。
もちろん、プログラミングなんで英単語を打ち込んでもらうことにはなるんだけど、知らない英単語がたくさんならんだ画面がいきなりばっと出てきたら、頭より心で『あっ、自分はプログラミングできない!』って思っちゃわないかと、それが心配で、結局 Developer Tools は使えませんでした。
ゲームのサイトとか、ちょっといかがわしいサイトとか、そういう場所へ行くもんだと意気込んで知らない英語の画面を見るのと、さっきまで普通に日本語喋ってた先生に突然わけわからない英語の画面を見せられるのでは、ショックの度合いが違うんじゃないかと思ったのも理由です。
あと、 Developer Tools ってあまりにもなにもかもできすぎるのよね。
そういう時、何が問題かって言うと、クラスに出来る子(少しプログラミングかじったことがある)がいると、自分の腕前を自慢したくなって教えてないとんでもないことをやってしまう。なんか経験ないですか。僕、情報の授業の時に先生が生徒のマシンをのぞき見できるデーモンを kill した覚えありますよ。そういうことやっちゃうんじゃないかと。
でも、それを怒ったり、やめなさいって叱るのは、なんかちょっと違うというか、僕自身がその叱り方に納得できなかったんですね。こういうのを『浮きこぼれ』って言ったりするんですが、そういう『浮きこぼれ』た子の上限を頭ごなしに抑える方式でいいのか、と。
実際、働クリッカーを触った体験授業の生徒にも、JS をかじったことのある子が二人ぐらいいて、一人はとにかく function
で処理をカプセル化したりして Speedrun をやってる、というような状況でした。そういう、ある程度此方側が想定した範囲で腕をふるってもらう分には全然オッケーだから、実際に授業中に『説明聞かなくてもいいから、とにかくいけるとこまで早くしてみてね。あとで僕と勝負しよう』と言って自由にさせていました。
ところが、もう一人の js 出来る子のエディタ覗きこんだら getElementByTagName(...)
とか書き始めてるじゃないですか。これはもうゲームぶっ壊す気まんまんだな、と。いや、マジで js 実行環境を sandbox 化しておいてよかった。
でも、それを止めるのももったいない。ていうか多分その子は体験授業でやってるようなクリック自動化くらいならすぐおいつけるだろうし、ということで、その子についても止めませんでした。ただ『もしそのハックが成功したら教えて』とは言いましたが。
僕が想定しうる限り『特に大変なことは出来ないだろう』と組んだ sandbox を突破してゲームをぶっ壊せたら、それこそめちゃめちゃすごいことですよね。その瞬間に『この子のハックが成功したら、この後話す内容を変更して、XSS とか CSRF の紹介と、なぜやっちゃいけないかの話も含めてしよう』って心に決めたもん。残念ながら、彼は間に合わなかったけど。
とはいえ、そういう浮きこぼれた子の集まりが、多分現代のプログラマ、エンジニア達なわけでして、そんな集団の一員である僕が率先して彼らを裏切ってはいかんだろう、ということでフルスクラッチでゲームを書いたのでした。
エモは求めてないから実装の話しようぜ
そうだね。
働クリッカーは大きく分けて3つに分割されます。
- Electron そのもの(Node.js)
- ゲーム本体 + js 実行 sandbox(Chromium in Electron)
- コードエディタ + コンソール(Chromium in Electron)
Electron そのものは特に大したことはしていません。大雑把に言うと、やってることは Electron 的な制御(アプリ終了とか Chromium のウィンドウ作るとか)と、コードエディタからゲーム本体へのコードの送信、ゲーム本体からコンソールへの出力の送信くらいです。
ゲーム本体も、特にめだって何かというのはなくて、 Vue.js を使って実装されたすごく単純な作りのゲームです。 MVVM にしたから画面の再描画タイミングとか考えなくて良くなったのは助かった。変に Canvas で実装したりしたらもっと大変だったと思う。
js 実行 sandbox は、 Node.js 標準モジュールの vm
を使っています。 timeout
が設定できるので、無限ループも安心……なはず。
コードエディタは CodeMirror という js 製のリッチエディタを使いました。ここもオプションいじったくらいで特に何もしてないところ。
という感じで、真剣に解説しようにもすでにある部品をくっつけただけの簡素な作りなので、技術的に目を見張る点は全然ない、というのがオチです。
SE ならしてるのも普通に <audio>
で鳴らしてるだけだから、特に頑張ってないしなぁ……
Electron を採用したのは、体験授業当日の実行環境が Windows になるか Mac になるかわからなかったので、とりあえずどっちでも耐えうるようにということで、クロスプラットフォームななにがしかが必要だっただけで、それ以上の理由はありませんが、結果的に vm
が使えてありがたかったり、 CodeMirror のおかげでエディタもリッチになったりといいことづくめだったので、人間最初の直感には従うべきですね。
で、働クリッカー公開します
とまあ、長い前置きになりましたが、働クリッカーを一般公開して、みんなに遊んでもらうよ!といったところすんなり通ったので、ドワンゴさんとバンタンさんの方角に向かって拝みつつ、みんなに遊んでもらえるように公開します。
ダウンロードはこちらから。
僕の全実績解除までの最速タイムが大体 0.8 秒なので、このスコアを超えるコードを書き上げた人は僕に教えてください。