2017年9月26日火曜日

スタンバグ

スーパーマリオワールドというゲームには様々なバグや裏技が存在します。ブロックを増殖したり、回転ブロックの塊を高速ですり抜けたり、壁の中に入ったり…無を取得というのも発見当時はSMW界隈で騒がれ、現在ではRTA技の一つとして使用されています。

この無を取得というのがスタンバグの一種だというのを、ある方に教えていただいた資料より知りました。この資料によると、全城や全ゴールで一部の方が採用しているboss kill(コース内でコクッパを召喚し、それを倒すことでクリアする)やオーブストック(沈没船のゴールアイテムをストックする)、知名度が高いものとしては、Pスイッチからプクプクを出すバグ(ヨッシーに乗った状態でPスイッチを踏み、直ぐに食べて吐く)は全てスタンバグである、とのことです。
これは知っておいたほうが良さそうだなということで、googleさんに頼りながら読んでみました。そのまま訳してるわけではないので(英語力低いし)間違っている可能性がありますがご了承を。他の記述も気になりますが、時間がかかr



==============ここから==============

「スタンしたスプライト」
スーパーマリオワールドにおいて、スプライトにはいくつかの状態が存在します。そしてそれを決める値はアドレス$7E:14C8に格納されています。具体的には以下。

$7E:14C8 : Sprite Status Table
#$00 = Free slot, non-existent sprite.
#$01 = Initial phase of sprite.
#$02 = Killed, falling off screen.
#$03 = Smushed. Rex and shell-less Koopas can be in this state.
#$04 = Killed with a spinjump.
#$05 = Burning in lava; sinking in mud.
#$06 = Turn into coin at level end.
#$07 = Stay in Yoshi's mouth.
#$08 = Normal routine.
#$09 = Stationary / Carryable.
#$0A = Kicked.
#$0B = Carried.
#$0C = Powerup from being carried past goaltape.

States 08 and above are considered alive; sprites in other states are dead and should not be interacted with.

この中で、#$0B、すなわち運ぶことが出来る状態、というのがスタンバグでは重要になります。例を上げると、緑色の甲羅と緑ハダカガメは同じスプライトですが、状態が違います。

緑色の甲羅:#$0B。スタン状態(持ち運び可能)
ハダカガメ:#$08。通常ルーチン

他にもクリボンやボム兵が当てはまります。

それ以外のスプライトの中で、鍵やPスイッチ等、マリオが常に持ち運ぶことの出来るスプライトは常にスタン状態となっており、通常のルーチンになると不安定な状態になります。

ここでもう1つ重要な概念、「スタンタイマー」を説明します。これは目的別に異なるスプライトで使用されるもので、ノコノコを踏んでハダカガメが生成される時に使われている値のため、このような名前になっているそうです。

ノコノコをジャンプで踏んだりマントで体当たりしたりすると、スタン状態になる(甲羅に変わる)だけではなく、スタンタイマーがある値に設定されます(最初のケースでは小さく、2回目のケースでは大きい)。このタイマーは1フレーム経過する毎に1ずつ減り、0になるとハダカガメが生成されます。これは通常ノコノコでのみ発生するものですが、開発者は、スプライトがスタン状態になり、スタンタイマーが0になる度に別のスプライトがそれから生成されるというコーディングをしていました。

スタンタイマーには色々な用途があります。例えば、スプライトが消滅するように踏み潰したとします。それで、もしそのアイテムがヨッシーの下に乗せられるもの、かつ踏み潰すことが出来るものであり、そのアイテムを踏むと同時に食べた時、ヨッシーはスタン状態のアイテムを吐き出すことが可能でしょう。
またその時、スタンタイマーが0以外の値にセットされ、その後毎フレームごとに減っていきます。そして値が0になると、それからスプライトが生成されます。
これにより、甲羅(赤以外)からハダカガメを無限に生成することができます。アイテムがPスイッチの場合、プクプクを生成することが出来ます(有名ですね)。

変異型:驚くべき「不安定な」スプライト。
スプライトの中にはスタン状態となることが想定されていないものもあり、そのようなスプライトはスタンルーチンが存在しません。
スプライトは、舌2枚出しバグによりスタン状態にすることが可能です。その際、以下のような手順を踏む必要があります。

 1 
舌2枚出しバグをする。

 2 
1枚目の舌で、ヨッシーが口内に保持できるスプライト(ノコノコ/甲羅、Pスイッチ、鍵、ジャンプ台等)を捕まえる。

 3 
2枚目の舌で、スタン状態にさせたいスプライトを捕まえ、ヨッシーの舌の上に乗っている間にダメージを受け、ヨッシーが飲み込まないようにする。


すると見かけ上、ヨッシーの口は膨れているが、2つ目のスプライトは飲み込まれていない、という状態になります。実際、ゲーム内ではそのように捉えられています。
たとえそのスプライトが口の中に留まることが想定されていなくても、そのスプライトはヨッシーの口から吐き出すことが出来ます。

この状態を引き起こした時スタンタイマーが0になっていなければ、SpriteKoopasSpawnテーブルがオーバーフローを起こし、何らかのスプライトが生成されます。何が生成されるかは、スタンさせたスプライトにのみ依存します。

スプライトのスタンタイマーは、様々な方法で0以外の値に設定することが出来ます。
方法の一つとして、スプライトを踏むというのがあります。後に残る塵や雲がエフェクトを表示する時間を決めるために、スタンタイマーが使用されます。
スプライトによっては、最初の生成(初期スポーン?)や、アクションを行う時等、上記とは別のことでスタンタイマーを使用します。例えば、ゴールポイント(ゴールバー)はタイマーを使用し、方向を変えるタイミングを決めます(上下反復)。

この不具合により、非常に奇妙な結果を得ることが出来ます。最も有用なケースは次のとおりです。

1. 滑る青色のハダカガメ 
スタンさせるとコクッパが生成される。倒すとレベルが終了する(通常クリア)。

2. サンボ 
スタンさせるとゴールバーが生成される。ゴールバーを得るには、(x, y) =(0~15, 0)の位置に移動する必要がある。

3. ライタ 
スタンさせると鍵穴が生成される。しかしライタが炎を吐くとクラッシュする。

4. 横方向に泳ぐ魚、パラボム 
スタンさせるとブイブイが生成される。ブイブイがスロット7に入るとレベルが終了する。
次のRAMメモリアドレスの値―$7E:1520, $7E:1521, $7E:1522 and $7E:1523―の合計は4でなければならない。それぞれのスプライトが異なった方法でアドレスを使用する。その多くは「垂直方向」のために使用。4つの引用アドレス(4 cited addresses)はスロット4と7の間のスプライトによって使用される。

5. Diggin' Chuck(地面を掘り起こして岩を転がしてくるブル) 
スタンさせるとClappin' Chunk(手拍子ブル)を生成する。これはオーブストックバグとして知られている。ファイアマリオを使い、アイテム交換を介してブルを食べると、ストックにオーブが表示される。

他にもスタンさせると便利なスプライトがあります。

テレサはコクッパを生成。
テレサウルスは鍵穴を生成。

…ヨッシーはお化け屋敷に入れないので、実機ではこの恩恵を得ることは出来ませんが、ハックロムでは可能です。また、以下のリストにどのスプライトがどのスプライトを生成するかを載せています。例えば、Diggin 'Chuckの岩をスタンさせれば滑る青ノコノコを生成でき、更にそれをスタンさせるとコクッパを生成できます。その為、時にはダブルスタンやトリプルスタンが役に立つことがあるかもしれません。以下のpastebinにて各スプライトが何を提供するかを知ることが出来ます。

==============ここまで==============


…細かいところは違うだろうけど、だいたいこんな感じだと思います。
ざっくり書くと、スタン状態とスタンタイマーを利用すると色んなスプライトが作れるよってことです(ざっくりしすぎ)。

ROM解析に関してはさっぱりなので、根本的に説明がおかしいところがあるかもしれません。気づいた方はコメントで指摘をば。


※参考動画
ゴール錬成(サンボを使用)
http://www.nicovideo.me/watch/sm20743580
ブイブイ錬成(横方向に泳ぐ魚を使用)
http://www.nicovideo.me/watch/sm31072476
コクッパ錬成(滑る青ハダカガメを使用。boss kill)
http://www.nicovideo.me/watch/sm31992078

2017年9月15日金曜日

Autosplit Helper 関連ソフトのリンク

適宜追加していきます。

<仮想webカメラ>

・SCFF Directshow Filter 
https://github.com/Alalf/SCFF-DirectShow-Filter (GitHub) https://sites.google.com/site/scffdirectshowfilter/ (Nightly Builds)

必要なランタイム:
Microsoft .NET Framework 4 Client Profile
https://www.microsoft.com/ja-jp/download/details.aspx?id=24872

 Microsoft Visual C++ Redistributable for Visual Studio 2017 (x64 or x86) https://www.visualstudio.com/ja/downloads/ (一番下)


 ・SCFH DirectShow Filter 
http://mosax.sakura.ne.jp/yp4g/fswiki.cgi?page=SCFH+DSF


 ・NDC(XP) 
http://consolas.web.fc2.com/ndcxp/

2017年9月9日土曜日

(続)RTAで各区間の成功回数をカウントしたい

アドバイスを頂いたので、すこし挑戦してみました。

Livesplitには名前付きパイプが存在し、それを利用するとSegment nameを変更できます。"setsplitname [index] [segment name]\n"を投げれば、指定した位置のSegment nameを指定できます。

先程投稿した記事で書いたものにこれを入れると、いい感じに動いてくれました。


細かい部分の調整がまだなので外に出せるものではないですが、ちょっとだけ便利だと…思い…ます…?

RTAで各区間の成功回数をカウントしたい

とある方がLivesplitで各区間の突破率を表示していたのを見かけたのですが、どのように設定しているのか分からない(ソースコードを見る限り公式に実装はしていなさそう…?詳しい方に確認をして欲しい)。コンポーネントの自作もなんかよく分からないしそもそも何故かエラーが出てプロジェクトを開くことすらできなかったので、VB.netでそれっぽいのを作ってみました。


LivesplitのSegment nameをそのまま写し、必要な区間だけグラフに表示…という感じ。
グラフの折れ線は突破率、上の数字は突破回数、左下の数字は通し回数。
Split/Resetのホットキー入力を感知して動いているので、Livesplitの区間数と合わせる必要があるのです。Ctrl,Alt,Shiftキーの入力は非対応。GetAsyncKeyStateで受け取っているんですけど、単一キー以外の受取がよくわかんないです。

レイアウトの調整等はほとんどしていないので見栄えは悪いですが、自分で使う分にはとりあえずこれで十分かなーと。誰かプログラミングに詳しい方がいたら、こういう感じのLivesplit用コンポーネントを作って欲しいなー?多分Splits、Graphを改変すればいけそうですよ?

GCPの感情解析

かなーり前に作成したもので、自分でも存在を忘れていたので、完全に忘却しないように。 ニコ生等のコメントを対象に感情解析をかけてます。得られる情報は、そのコメントがポジティブなのかネガティブなのか、その強さ。 他のメーカーの感情解析はもっと詳細な情報を得られるものもあ...