Screeps:Arena チュートリアルだけやりました(デモ版ではなくちゃんと買ったのにまだそれしかしてない)

先日早期アクセスでリリースされたこのようなゲームがあるとのことで早速飛びついた news.denfaminicogamer.jp

多少趣が違うScreeps:Worldという前作(?)があるようだけど、軽くググっただけではWorldについての日本語記事も見つけられなかったので、Arenaの方のチュートリアル完了までのことを少し日本語で書いておきます。(だいたいで書くので、正確なことはゲーム内のリファレンスとかを頑張って読んでください)

ゲーム概要

生産施設、エネルギー資源、ロボ(クリープ)なんかが配置された空間があり、

  • 生産施設はクリープを生産
  • 作業クリープはエネルギーを収穫
  • 攻撃クリープは敵が近くに居たら攻撃、射程外なら接近する

プレイヤーは上記のようなことをさせるプログラムを読み込ませて、敵プレイヤーと結果で争います。

試合の目的は、今のところ「フラグを取る」「敵の生産施設を破壊する」「点数を稼ぐ」の3種類あるようで、それぞれ入り口が別なので、目的に応じたプログラムを組むことになります。

前述の記事で「リアルタイムストラテジー」と表現されていますが、プレイヤーは「AIの行動をプログラミングしたソースコードを読み込ませる」「結果を見る」をやるだけで、リアルタイムで操作することはないです。なのでRTSではないんじゃないかなー、と。最初に記事を読んだときは「ムム!左から敵が!!戦力を左に集中!!カタカタカタカタ…ッターン!!」みたいな感じかと思ったんですけど違うようです。

※これ書いた後に一回試しに対戦してみっかと思ったんだけど、対戦相手探し中のまま何分も待たされてるので「アップロード済みのソースコード同士で非同期に対戦が開始される」わけではないっぽい

チュートリアル解説

チュートリアル2~9は画面下部の「Sample Code」にクリアに必要なコードが用意されている(1は本文中にある)ので、それをコピペすれば9まではクリアするだけならできます。

注意点としては、1面でスクリプトの置き場所が「C:\Users[username]\ScreepsArena\tutorial-loop_and_import」となっているのを、例えばDドライブなどに変更したとしても、2面を開くと一旦「C:\Users[username]\ScreepsArena\tutorial-simple_move」にデフォルトのファイルが作られるので、Dドライブに先回りしてファイルを作って「なんで動かないんだ?」となる可能性があるんじゃないかと思います(しばらくそれで悩んだ)

1.Loop and Import
メインループ

試合中、1ターンごとにメイン関数から loop() 関数を呼ばれます。この loop() の中で処理がループするわけではないので、たとえばこの関数の先頭で変数の初期化などを行う場合、毎ターンそれを実行することになるはずです。「1ターン目だけ実行したい」場合は getTicks() == 1 で判定するなどの工夫が必要になります。

また、関数の外にグローバル変数を宣言し、ターンを跨いで値を持ち越すことは可能です。

インポートの書き方

import { getTicks } from '/game/utils';

何がインポートできるかなどは後のチュートリアルでも出てくるのでとりあえずサンプルコードコピペでいいと思います。

2.Simple move
クリープやフラッグ、その他オブジェクトの取得

getObjectsByPrototype() で、オブジェクトタイプを指定することで、フィールド内のそのタイプのオブジェクトの配列が取得できます。1個の場合でもちゃんと配列になります。

味方のクリープ+敵のクリープ、味方のフラッグ+敵のフラッグなど、敵味方ごちゃまぜで取得されるので、味方のオブジェクトに絞り込みたい場合はチュートリアル3で出る方法を参照してください。

クリープの移動

creep.moveTo(target); targetのオブジェクトに向けて1歩移動します(最短経路かどうか怪しい動きをする時がある気がする)。多分座標指定とかもできると思うけど調べてないのでリファレンス見てください。

チュートリアル4で出てきますが、クリープは「MOVE」や「ATTACK」など、可能な行動を示すパーツを装備しています。この章では触れていませんが「MOVE」がないと移動できません。

3.First attack
味方クリープの抽出

var myCreep = getObjectsByPrototype(Creep).find(creep => creep.my);

まあ、 find はJSの普通の関数ですね。他の条件で絞り込みたい場合は他の条件で絞ると良いと思います。

クリープの攻撃

「ATTACK」を持っているクリープは隣接した敵を攻撃することができる

if(myCreep.attack(enemyCreep) == ERR_NOT_IN_RANGE) {
    myCreep.moveTo(enemyCreep);
}

「攻撃できたら行動終了、攻撃が届かないなら移動」という感じで、このゲーム用の書き方かなと思います。

attackとmoveを同じターンのうちに両方行っても特にエラーにはならないようです(attackを無限ループしたら勝ちじゃんと思うけど、多分1つのオブジェクトは同じ行動は1ターン1回しかできない)

4.Creeps bodies
クリープのパーツの種類

まあ名前を見ればわかると思いますが、以下の種類のパーツがあり、装備しているパーツに応じた行動が可能です。 - MOVE:移動ができる - ATTACK:隣接したクリープを攻撃できる - RANGED_ATTACK:3マス離れたクリープを攻撃できる - HEAL:自分自身か他のクリープを回復できる - WORK:エネルギー源からの収穫、建設、建築物の解体 ができる - CARRY:運搬ができる(エネルギーの収穫をさせたい場合、WORK+CARRYにしないと多分持てない) - TOUGH : HPが多い

たとえばチュートリアル3では「MOVE」「ATTACK」を持ったクリープが用意されていました。

これらは敵の攻撃などで個別に破壊されることがあります。「MOVE」だけ破壊されると固定砲台のような状態でその場に残りますし、「ATTACK」だけ破壊されると移動だけできる状態で生き残ります。どの順で攻撃・破壊されるかは調べてないです。

5.Store and transfer
タワー

エネルギーが10あると攻撃できる。チュートリアルでの出番がこれだけだったから調べてない。他はリファレンス参照

エネルギーの受け渡し
  • transfer:クリープから他のものに運搬中のエネルギーを渡す。CARRYを持つクリープ同士での受け渡しも可能
  • withdraw: 他のものからエネルギーを取得する。リファレンスを見るとクリープからも取れそうなんだけどうまくいかなかった。
6.Terrain
地形

超えられないブロックがあるので、 findClosestByPath() を使うことで「到達可能な最短経路があるオブジェクト」を見つけることができる。 findClosestByRange() だと「到達不可能でも最も距離が近いオブジェクト」を見つける。

7.Spawn Creeps
クリープの生産

スポーンが設置されている場合、スポーンに指示することでクリープが生産できる。

前述のクリープのパーツを複数指定(同じ属性を複数指定することも可能っぽい)して生産できる。パーツごとに必要なエネルギー量が違う。

1つのスポーンで1ターンのうちに1体しかクリープを生産できない(2体生産しようとすると1体目もうまく生産されず詰むと思う)ことと、生産されたクリープはそのターン中は何もできないことに注意。

8.Harvest energy
エネルギーの収穫

WORKとCARRYを持ったクリープは、harvest() でエネルギー源からエネルギーを収穫して保持することができる。

9.Construction
建築

WORKを持ったクリープはタワーを建築できる(エネルギーが要るので実質的にはCARRYも必要)。

createConstructionSite() で建築場所を設置して build() で建築。 createConstructionSite() したターンは build() できないかも(未確認)

10.Final test
  • クリープの生産
  • エネルギーの収穫と運搬
  • 敵の攻撃

と、チュートリアルでやったことを組み合わせることになる。 開始時点では、敵は壁に囲まれたエリアにいて攻撃できないが、壁を破壊して出てきてくれるので、その後で倒せばOK。 (こちらも壁の破壊に協力すれば早く出てきてくれると思うが、壁の攻撃の指定などが面倒で試してない)

ボンバザルを1~130面の通しでクリアした

Nintendo Switch Online でボンバザルが遊べるようになっていたので、1~130面を通しでクリアしました。

f:id:annnnnnna:20210803214253p:plain
ボンバザル130面リザルト

馴れ初め

ボンバザルは、スーファミ本体と一緒にマリオワールドとF-ZEROと同時に入手したので「当時」も遊んでいる。
なので、100面までにクリア不能面があるというキャンペーンも知ってたし、100面までのパスワードの紙もある状態でプレイした。

当時はたしか11歳くらいだったので、100面までのパスワードが付属してたのも「ラッキー」くらいの感じで、今でこそ「バグをごまかすため」という噂があるけどそういうネガティブな感情はなかった。
で、当時自力でクリアできたのがせいぜい40~50面くらいだったかな?そこから先はパスワード使って飛び飛びでプレイしてクリアできたりできなかったりで、「80面こそがクリア不能である」と判断することはできなかった。
あと、攻略本も持っていた。確かそれには120面くらいのパスワードが載ってたような記憶があるけど、130面のパスワードが「DEMO」なので、知ってる4文字の英単語を適当に入れて最終面が遊べてしまったので、そこだけは頑張ってクリアしてエンディングは見たことがあった。
という感じ

あらためてプレイしての総評

このゲームは初見殺しが多すぎて、普通にプレイしてたらメチャクチャ腹が立つ。ワープ先は乗ってみるまで不明(まあ、ワープ要素あるゲームってだいたいそんなもんだけど)で、ワープ先が地雷ということもしばしば。スイッチの動作も動かしてみるまで不明で、足元に地雷が現れて自爆するだけの罠スイッチすらある。
滑る床の先が穴なのはよくあることで、スタートボタンで参照できるちょっと広めのマップも全然広範囲を見せてくれないので、結局は滑ってみるまで先がどうなってるかわからないことも多い。
ということで、パズルゲーとしてはかなり「どうなんだ、これ」という感じではあるんだけど、Switchで遊べるFC,SFCのゲームは「いつでもセーブ」「巻き戻し」ができるようになっているので、この機能があれば理不尽な初見殺しと対等に戦えるようになったと感じた。
「Switchで遊ぶなら、65点くらいのパズルゲーム」と言えるかなという感想。実機でやるのはおすすめしない。

クリア不能面について

普通のゲームで遭遇できない進行不能バグがあっても「バグがあってダメ」とは言わないじゃん(たとえば仮に「ドラクエ3でレベル1の勇者一人でバラモスを倒すとハマる」みたいなバグがあったとしても、到底再現できないわけで、許されると思う)。
ボンバザルにとっての「80面」って「まともにやったら到達するのは難しい」ので、この「クリア不能」というバグに困らせられたプレイヤーって当時いたのかな?と思うんだよね。
だから、自力で80面に到達してないプレイヤーがこの点をあげつらって「だからクソゲー」って言うのは甘えだと思うんだよ。順番にプレイして80面で詰まった人だけが正当に怒る権利を有してるんじゃないかなと。
まあ実際はタイルに乗りっぱなしでいることで足元をスピナータイルに変化させることで「確率で」クリアできるようになるので、こうやって通しでクリアできたわけですが。

オタクなのでアバターを作りました

オタクなので、自分の代わりに表示するかわいいアバターは常にほしいわけですよ。
各種SNSのアイコンに表示するキャラが版権キャラでもまあ別にそんなに怒られはしない世の中ですけど、でも、人のキャラ使って「これが私です」とは言えないわけじゃないですか。
流行り始めてもう3年以上経つけど、VTuber云々の影響ももちろんある。自分の動きに連動するアバターは私の目にはとても良いものに見えます。

玄土ふたえ

オリキャラ」とか大層な言い方するつもりはないんだけど、「いい名前思いついた!!!」ってTwitterアカウント作ってあんまり運用してないキャラが1人います。
twitter.com
これは、俺がマジで1日中下着の広告を見まくっているので、その活動だけを分離するために作ったものになります。
見た目については自分のフェチ記号(ぱっつん、おかっぱ、メガネ、泣きぼくろ、そばかす、日焼け跡、ジャージ、地味な見た目の割に下着が派手(原則非表示だけどちゃんと描いてある))をとにかく盛ったので、見た目の好き度は本当に高いんだけど「自分がなりたいキャラ」ではなく「自分が見ていたいキャラ」なので、自分が被るアバターとしてはなんかしっくりこなかった。

不届もも

結構やっつけで作ってあんまり気持ちが入ってないんだけど、スマホゲーで表示されるクソみたいな広告を見るのも好きなので、そっちの活動をこっちに集約しています。
twitter.com
名前については、あの手の広告でなぜか定型句としてよく添付されている「I can't reach pink color」というフレーズが由来です。
ピンクってのはおそらく高難易度ステージを指してるんだろうけど、ピンクに到達するのがどのくらいムズいのか知らねんだわ。

わたしです

どっちも「広告を見る活動の分離」のために作った存在なので、自分のメインの体がほしいなーと思って何回も描いたり消したりしてたんですが、まあこんなところかなという一旦のゴールにしたので、はい。

f:id:annnnnnna:20210221212910p:plain
me

で、Live2Dで動きを付けるにあたって、2人同時に動くようにした。といっても操作する人間は1人なので、瞬き以外は左右対称に動くことしかできないんだけど

f:id:annnnnnna:20210221213338p:plain
anna_futae

たとえばティンクルスタースプライツだったらマッキー&ペンテル、プチカラットだったらパール&デール、キカイオーだったらツインザムVみたいな、2キャラ出てくる系のキャラを好んで使っていたり、PORTAL2のco-opを1人でコントロ―ラー2つ使ってクリアしたりした(これはいつか動画撮りたい)ので、「見た目を1つに決められないなら、2人になればいいじゃん」ってことでこうなりました。
(ちなみに、スマブラのポポ&ナナはなんか操作ムズすぎてダメだった。前述したのは「2キャラ出てくるけど実質1キャラ」だけど、ポポ&ナナは実質1キャラとは言い難くてムズい)

声の問題

これでVTuber的なことやるかどうかはともかく、ボイチェン使っても声がなんかあんまり納得できなくなってしまった。
というのも、2019年の秋頃に近所でやってた工事の粉塵を思いっきり吸い込みまくって一時期喉から出血しまくってたせいで「ボイチェンでいい感じに変換できる声の出し方」が全然できなくなってしまった。普通に歌うのも無理っぽくなってしまった。
で、思いついた解決策がこれ

f:id:annnnnnna:20210221214249p:plain
kuroko

パペットマペットみたいな形式なら素の声でも問題ないね


その他やりたいこと

腕を体の後ろに回してるポーズしかないので「これだから手が描けないやつは」って思うと思うんですけど、まあそれはそうなんですけど、「きせかえシールブック」みたいなのを作りたいので、腕にポーズ付けるのは服のオプションなんですよ。
服はジャージ1種類しかないのに下着だけメチャクチャ種類数が多いきせかえシールブックを作りてえんだ、俺は。