閉じる
  1. 【兎田ぺこら】「チキン冷めちゃった」とは?元ネタ・意味・その後を解説し…
  2. N64 風来のシレン2 鬼襲来!シレン城! デバッグモードのやり方・コ…
  3. SFC シャイニングスコーピオン 攻略チャートその1 ~朝日町~
  4. スーパーファミコン改造方法まとめ チートのやり方
  5. 【ドラゴンクエスト3リメイク】評価・レビュー プレイした感想【そんなに…
閉じる
閉じる
  1. HD2D ドラゴンクエスト1&2リメイク ショップアイテム変更チート
  2. 【実機レビュー】ドリル研磨機で切れ味復活!使い方とメンテナンスガイド
  3. ゆうメールが前の住所に配達されてしまった件:Amazon住所文字化けの…
  4. ドラゴンクエスト3 HD2Dリメイク 商人鑑定セリフ&アイテムコード
  5. SFC シャイニングスコーピオン レース画面の見方と各コース・セクショ…
  6. UpNoteサインインエラー「auth/firebase-app-ch…
  7. RPGあるある「ラストエリクサー症候群」とは?原因から克服法まで解説
  8. 【裏技】SFC ドラゴンクエスト6 乱数固定現象を紐解く【バグ技】
  9. スマホのスクショ直後の左下プレビューが連続撮影時に映り込んで邪魔な件
  10. カラムシの葉を叩いて楽しむ!昔懐かしい破裂音遊びの魅力と方法
閉じる

ゲーム改造攻略トピックス

SFC ミニ四駆シャイニングスコーピオンの熟練度解説まとめ

シャイニングスコーピオンの熟練度について解説します。熟練度の効果とその上げ方、どこまで上がるのかの制限及び確認方法、熟練度表などを掲載しています。

 

シャイニングスコーピオンの熟練度の意味と効果

「ミニ四駆 シャイニングスコーピオン レッツ&ゴー!!」には、主人公の経験値に相当する「熟練度」という隠しパラメーターがあります。「プレイヤー自身の経験」をゲームの中で再現したものが熟練度であり、このゲームの攻略には重要な要素となっています。

効果としては、まず熟練度が上がるにつれて「段階的にマシンのスピードがアップ」します。また、シャイニングスコーピオンの「カラーリング変化」にも関係してきます。さらには改造の幅も広がり、スーパー1シャーシにサイクロンマグナム、スーパーFMシャーシにレイスティンガーなど、「種類の違うシャーシとボディを組み合わせて使える」ようになります。

ただ1つだけ不満点がありまして、それは「熟練度が上がれば上がるほど、なぜかメンテナンスによるパーツ耐久値の回復が少なくなっていく」のです。・・・ミニ四レーサーとしての腕前が上がっているというのにどういうことなのか?

フリーバトルにも熟練度は有効で影響をもたらします。熟練度を上げて育てたマシンを他人のフリーバトルモードに反映させるためには、その都度SGJCの車検を受けて新しいパスワードを発行する必要があります。

なお、一般的に言われている「熟練度が上がると自分のマシンがコースアウトしにくくなる」という情報については、解析過程の中で私は懐疑的な見方をしています。

 

熟練度の確認方法

熟練度はマスクデータであり、プレイヤーが直接数値で熟練度を知ることはできません。

エミュレーターであればチート機能でメモリを見ると現在の熟練度がどのくらいか数値で確認することができますが、スーパーファミコン実機やレトロフリークでプレイしている場合、数値として確認する方法はないのです。

 

一応、メカニックマンの改造後のコメントで、その時点での熟練度の目安は知ることができます。

沖田カイとの勝負に勝つとレース勝利として熟練度が5ポイント、そのあとにメカニックマンによる改造によって40ポイントもらえますが、この改造直前の熟練度数値によってメカニックマンのセリフが変化します。熟練度が25ポイント未満だと「一応パワーアップしたけど・・・」、25ポイントから55ポイントで「これで君のマシンの性能は・・・」、そして56ポイント以上で「君はマシンの扱いにかなりなれているね」というメッセージ変化となっています。

 

また、他のボディが買えるようになるクリア後にしかできませんが、規格外のシャーシを付けられるかどうか確認すると目安にはなります。シャースの付け替えが自由にできれば、熟練度がかなり高い状態です。攻略本では、「各模型店に貼り出されているランキングポイント表が多少の目安になる」と書かれていますが、どのようにして目安にするのかについてはまったく説明がなく、それ以外は目安を知ることすら皆無なのです。

 

数値とメモリアドレス

メモリアドレス$7F:002Bに熟練度が格納されていて、データの値としては0xFFの状態が初期値であり0x00が最高値となっています。

(ストーリーモードで新しいセーブデータを作成し、マシン名を決定した直後、即値0xFF(255)を$7F:002Bに書き込んでいます。その後、特定の行動をすることでゲーム内で熟練度が上がりますが、データは0x00が最大なので、プログラムにおいては減算処理が実行されます。)

 

熟練度の上げ方とレベルについて

熟練度は「レースで勝利する(1位になる)」「改造をする」「メンテナンスをする」「イベント」という4つのことによって上がります。また、熟練度にはレベルもあり、熟練度ポイントが一定量を超えるとレベルアップします。レベルは1から6までの6段階で設定されていて、熟練度ポイントが200以上で最大レベルになると、シャーシとボディを自由に組み合わせることができます。

熟練度レベルが低いと、以下の画像のように異種シャーシの取り付けができず、「今のレベルでは このボディとシャーシを組み合わせることはできません!!ボディーもしくはシャーシを交換してください」と警告メッセージが出る。

 

以下は、熟練度レベルによる累計熟練度ポイントとメモリ値の対応表です。※メモリ値はゲーム内部での数値を示す。16進数と(10進数)

 

熟練度レベル
累計熟練度ポイント
メモリ値
Lv1
0〜15p
0xFF〜0xF0 (255〜240)
Lv2
16〜40p
0xEF〜0xD7 (239〜215)
Lv3
41〜76p
0xD6〜0xB3 (214〜179)
Lv4
77〜125p
0xB2〜0x82 (178〜130)
Lv5
126〜189p
0x81〜0x42 (129〜66)
Lv6
190〜255p
0x41〜0x00 (65〜0)

 

熟練度はどんな作業をやっても無限に増えていくわけではなく、主人公の熟練度レベルが高くなるにつれて簡単なメンテナンスや改造、弱いライバルとのレースでは熟練度を上げることができなくなる仕組みになっています。

たとえば「タイヤのよごれとり」であれば熟練度レベルが1~2の場合だけ数値がアップし、レベルが3以上になるとまったくアップしなくなるのです。数値でいうと40以下なら増えて、41以上になると増えない、といった具合です。

これはドラクエ6でいえば弱い敵ばかり倒しても職業熟練度が上がらないことと同じです。

レベルが上がるにつれて熟練度を上げるための手段が減っていくため、最終的にはS・Gシティーでの模型店レースやスーパーグレートジャパンカップレースで1位を取るしか熟練度を増やすことができなくなります。したがって、限界レベルが低い項目から達成していくことがベストです。初期マシンのセイバー600はできる限りの改造(肉抜き、カラー変更)などをしておくことをおすすめします。

なお、出荷時期のROMによって熟練度のレベル設定が異なるという説がありますが、これは考えられません。設定値の違いがあったとしても確認する手段がありませんし、結局255ポイントで熟練度はMAXなため、ボディとシャーシの付け替えが自由になれば最高レベルになっていると判断して良いでしょう。ボディとシャーシの付け替えが自由になったのを確認して、そこからSGJCで11回優勝すれば熟練度はカンストすることになります。

公式無敵ガイドのp32にミニ四ファイターの超速インフォメーションで、熟練度レベルのチェックとして「マッハダッシュと超速ギヤーを装備して自由参加レースのダッシュキングを走ってみる~」と記載されているが、ダッシュキングレースのような非常に短い距離のコースではスコーピオンの色の変化は起こりません。おそらくクリームパンコースの間違いかと思われます。ちなみに、クリームパンコースで毎回色が4段階(赤)まで変化するようなら熟練度メモリ値は0x36以下を示しています。0x36というと熟練度の最大レベル(6)を超えたところであります。ボディの付け替えができるレベルです。シャイスコの色変化についてコードレベルで解析し、色変化システムのすべてが判明しました

 

シャイニングスコーピオン 熟練度表

以下にその項目ごとにどれだけ熟練度アップするか表にしてみました。各ランクでの変動、乱数による揺らぎにも対応しています。

最終決定保存版!

シャイスコレーサーの役に立てば幸いです。 限界レベルに気を付けながら効率よく熟練度をあげよう!

表は左から限界レベル・アップ値・確率を示す。プレイヤーが限界レベルを超えている場合、その項目の内容を実行しても熟練度は上がらないので注意。

 

改造で熟練度アップ

タイヤのカット
熟練度レベル アップ値 確率分布
Lv1 +1~2 1: 33.3%
2: 66.7%
Lv2 +1~2 1: 66.7%
2: 33.3%
Lv3 +1 1: 100%
Lv4 +0 0: 100%
Lv5 +0 0: 100%
Lv6 +0 0: 100%

 

ボディ削り
熟練度レベル アップ値 確率分布
Lv1 +2 2: 100%
Lv2 +1~2 1: 33.3%
2: 66.7%
Lv3 +1~2 1: 66.7%
2: 33.3%
Lv4 +0 0: 100%
Lv5 +0 0: 100%
Lv6 +0 0: 100%

 

カラー変更
熟練度レベル アップ値 確率分布
Lv1 +1 1: 100%
Lv2 +0 0: 100%
Lv3 +0 0: 100%
Lv4 +0 0: 100%
Lv5 +0 0: 100%
Lv6 +0 0: 100%

 

コックピット部分の肉抜き
熟練度レベル アップ値 確率分布
Lv1 +5 5: 100%
Lv2 +5 5: 100%
Lv3 +4~5 4: 33.3%
5: 66.7%
Lv4 +4~5 4: 66.7%
5: 33.3%
Lv5 +0 0: 100%
Lv6 +0 0: 100%

 

フロント部分の肉抜き
熟練度レベル アップ値 確率分布
Lv1 +4 4: 100%
Lv2 +4 4: 100%
Lv3 +3~4 3: 33.3%
4: 66.7%
Lv4 +3~4 3: 66.7%
4: 33.3%
Lv5 +0 0: 100%
Lv6 +0 0: 100%

 

逆テーパード加工
熟練度レベル アップ値 確率分布
Lv1 +2~3 2: 33.3%
3: 66.7%
Lv2 +2~3 2: 66.7%
3: 33.3%
Lv3 +2 2: 100%
Lv4 +0 0: 100%
Lv5 +0 0: 100%
Lv6 +0 0: 100%

 

テーパード加工&グルービング加工
熟練度レベル アップ値 確率分布
Lv1 +3~4 3: 66.7%
4: 33.3%
Lv2 +3 3: 100%
Lv3 +2~3 2: 66.7%
3: 33.3%
Lv4 +0 0: 100%
Lv5 +0 0: 100%
Lv6 +0 0: 100%

 

メンテナンスで熟練度アップ

モーターのブレークイン
熟練度レベル アップ値 確率分布
Lv1 +2 2: 100%
Lv2 +1~2 1: 33.3%
2: 66.7%
Lv3 +1~2 1: 66.7%
2: 33.3%
Lv4 +1 1: 100%
Lv5 +0 0: 100%
Lv6 +0 0: 100%

 

フロントタイヤのよごれとり
熟練度レベル アップ値 確率分布
Lv1 +1 1: 100%
Lv2 +0~1 0: 33.3%
1: 66.7%
Lv3 +0 0: 100%
Lv4 +0 0: 100%
Lv5 +0 0: 100%
Lv6 +0 0: 100%

 

リヤータイヤのよごれとり
熟練度レベル アップ値 確率分布
Lv1 +1 1: 100%
Lv2 +0~1 0: 33.3%
1: 66.7%
Lv3 +0 0: 100%
Lv4 +0 0: 100%
Lv5 +0 0: 100%
Lv6 +0 0: 100%

 

ギヤーグリスアップ
熟練度レベル アップ値 確率分布
Lv1 +1 1: 100%
Lv2 +0~1 0: 33.3%
1: 66.7%
Lv3 +0 0: 100%
Lv4 +0 0: 100%
Lv5 +0 0: 100%
Lv6 +0 0: 100%

 

ターミナルみがき
熟練度レベル アップ値 確率分布
Lv1 +1 1: 100%
Lv2 +0~1 0: 33.3%
1: 66.7%
Lv3 +0 0: 100%
Lv4 +0 0: 100%
Lv5 +0 0: 100%
Lv6 +0 0: 100%

 

イベントで熟練度アップ

※イベントでは自分のレベルに関わらず熟練度が大幅アップ!(上昇値は、何%とかではなく固定です)
※一部の情報で四駆図書館で本を読むと熟練度が上がるというものがありますが、実際には上がりません。熟練度の存在を連想させる本があるだけです。

<メカニックマンによる改造>


カイとの勝負を受けて勝った場合:40p
カイとの勝負を受けて負けた場合:20p
カイとの勝負を受けなかった場合:10p

※攻略本に誤った情報が載っており、実際にはカイ戦に負けた場合は20ポイントの熟練度上昇があり、カイとの勝負を受けなかった場合は10ポイントです。

 

<鉄心先生のクイズ>


1問正解につき10p(最高50p)

クイズの答え

  • どっちのモーターがスタートダッシュで有利かのう?
    →トルクチューン
  • どっちのギヤーがモーターの負担が少ないかのう?
    →5:1ギヤー
  • どっちのホイールが安定性が高いかのう?
    →小径ホイール
  • マシンの重心が高ければ、走行中のマシンの安定性がよくなる?
    →いいえ
  • ワンウェイホイール内蔵のギヤーにグリスアップするとスピードアップするかのう?
    →いいえ
  • シャフトの軸受けのボールベアリングにグリスアップするとどうなるかのう?
    →スピードダウンする
  • 土屋はスーパーアバンテを元にフルカウルを作った?
    →はい
  • ZMCの最後の仕上げは氷点下で凍らせなければならないかのう?
    →いいえ
  • 子供の頃、佐上模型店のコースでミニ四駆のレースをしていたのはどっちじゃ?
    →ミニ四ファイター
  • 佐上ジュンが好きなスポーツはサッカーかのう?
    →いいえ

 

レースで熟練度アップ

<制限レベル2までのレース(累計40p以下なら熟練度UP)>
朝日町 佐上カップレース:1p
朝日町 エキシビジョンレース:1p
朝日町 タイマンレース:1p
春菜ヶ丘 ダッシュキングレース:1p
春菜ヶ丘 ゲームセンター藤吉レース:1p
スプリングレース予選 予選ヒート:3p
スプリングレース予選 決勝ヒート:5p

<制限レベル3までのレース(累計76p以下なら熟練度UP)>
日光平 ミニ四グリーンカップレース:1p
スプリングレース決勝レース:5p

<制限レベル4までのレース(累計125p以下なら熟練度UP)>
空風村 ダッシュキングレース:1p
共通予選レース:1p
倉庫街 野試合バトル:5p
海浜パーク ミニ四テクニカルレース:1p
海浜パーク エキシビジョンレース:1p
サマーレース決勝レース:5p
コスモス湖 タイマンレース:1p
コスモス湖 ダッシュキングレース:1p
オータムレース決勝レース:5p

<制限レベル5までのレース(累計189p以下なら熟練度UP)>
S・Gシティー ダッシュキングレース:1p

<制限レベル6までのレース(カンストするまで熟練度UP)>
S・Gシティー ミニ四グリーンカップレース:1p
S・Gシティー ミニ四テクニカルレース:1p
スーパーグレートジャパンカップレース:5p

※公式無敵ガイドではオータムレース決勝レースの熟練度レベル制限は3となっているが、正しくは4。
※共通予選レースは大会だが1ポイントのみ。
※黒沢戦に勝つと大幅に熟練度が上がると書いているサイトがありますが、黒沢に初戦で勝利してもリベンジで勝利しても同じく1ポイントしか上昇しません。物語中盤のビークスパイダー戦であれば5ポイントもらえ、さらにイベントを合わすと計45ポイント獲得できます。

 

レースによる熟練度変動システムの処理フロー解説

このプログラムは、レース終了時に呼び出される、熟練度の成長を管理するための専用ルーチンです。

このルーチンは、単に熟練度を上げるわけではありません。「勝利したレースの難易度」と「プレイヤーの現在の熟練度」という2つの要素を比較し、格下の相手に勝っても成長はなく、同等か格上の相手に勝つことで成長するという、非常にリアルな成長システムを実装しています。

以下では、コード解析によって明らかになった処理のフローを、大きく4つのフェーズに分けて段階的に解説していきます。

 

初期化と実行条件のチェック

このフェーズでは、まず熟練度を変動させるための前提条件をチェックします。

プログラムは、CPUの状態を保存して演算を16ビットモードに切り替える初期化を行った後、最初に現在のゲームモードを確認します。フリーバトルフラグ($0F95)を参照し、もしフリーバトルモードであった場合は、即座に処理を終了します。フリーバトルでの勝利は熟練度に影響しないですからね。続いて、プレイヤーの最終順位をレース結果データ($7EB0E2)から読み込み、1位(#$0001)であるかを判定します。ここでもし1位でなければ、同様に処理を終了します。

つまり、「ストーリーモードのレースで、かつプレイヤーが1位で優勝した」という条件を満たした場合にのみ、後続の熟練度計算処理へと進むことになります。

 

プレイヤーの「現在の熟練度ランク」の判定

フェーズ1で実行条件をクリアした後、プログラムは「プレイヤー自身の腕前」をシステム的に評価するプロセスに入ります。このフェーズでは、プレイヤーの現在の熟練度を元に、内部的な「熟練度ランク」を判定・決定します。

熟練度スコアへの変換

まず、セーブデータ上の熟練度管理アドレス($7F:002B)から、現在の熟練度(0~255)を読み込みます。
シャイスコでは、熟練度は「0」が最高(MAX)で、「255($FF)」が初期状態という、いわゆる「減算式」で管理されています。しかし、ランク判定を行う上では「値が大きいほど熟練している」形式の方が扱いやすいため、プログラムは以下の計算を行って値を反転させます。

熟練度スコア = 255 ($FF) – 現在の熟練度

この計算(LDA #$00FF → SEC → SBC)により、初期状態ならスコアは「0」、熟練度MAXならスコアは「255」となり、直感的な「熟練度スコア(累計熟練度)」として扱えるようになります。

 

閾値テーブルによるランク判定ループ

次に、算出した熟練度スコアを元に、プレイヤーがどのランク帯に属しているかを判定します。
ここでプログラムは、ROM上に格納されている「熟練度ランク・閾値テーブル」)を参照します。このテーブルには、以下の7つの閾値が順に格納されています。

閾値データ(16進数): 0F, 28, 4C, 7D, BD, FF, FF
閾値データ(10進数): 15, 40, 76, 125, 189, 255, 255

この10進数の数値に見覚えがある方もいるかもしれません。そう、これらは本記事や公式ガイドブック等に記載されている「熟練度レベル」の境界値と完全に同じです。プログラム内部の数値が、そのまま攻略本のデータ通りに実装されていることが確認できました。

そしてプログラムは LDY #$0000 でインデックス(カウンタ)を初期化し、テーブルの先頭から順に値を読み込んで、プレイヤーの熟練度スコアと比較するループ処理を実行します。

 

ループ処理のロジック

LDA [$53],Y ; テーブルから閾値を読み込む
AND #$00FF ; 下位バイトのみ抽出
INY ; インデックス+1(次の準備&仮ランク)
CMP $23 ; 「閾値」と「プレイヤーのスコア」を比較
BEQ Label_End ; もし「閾値 = スコア」なら、ランク確定。ループ終了。
BCC Label_Loop ; もし「閾値 < スコア」なら、まだ上のランクがある。ループ継続。
; もし「閾値 > スコア」なら、この閾値を超えられない。ループ終了(そのまま下へ)。
Label_End:
DEY ; インクリメントしすぎた分を戻す。これが最終的なランク(0~5)。
STY $25 ; 確定したランクを保存。

 

このループは、「テーブルの値(閾値)≧ 熟練度スコア」 という条件が満たされるまで、Yレジスタをインクリメントしながら続きます。つまり、「あなたのスコアが、テーブルのどの閾値に初めて収まるか」を探しているのです。

 

<最後の閾値「$FF」が持つ重要な役割>
テーブルの末尾に設定されている $FF (255) という値には、プログラムの安定性を保証する極めて重要な役割があります。

もし、この $FF が存在せず、テーブルが BD (189) で終わっていたと仮定しましょう。その場合、プレイヤーが熟練度MAX(スコア255)の状態でこの判定を行うとどうなるでしょうか。

スコア255は BD よりも大きいため、ループ条件を満たせず、プログラムはテーブルの範囲外にある無関係なメモリ領域まで読み進んでしまいます。これは深刻なバグや暴走を引き起こす原因となります。

末尾に $FF を配置することで、たとえプレイヤーが最高スコア(255)を持っていたとしても、必ずこの地点で条件が一致し、ループが安全に停止することが保証されます。

すなわち、この $FF は、どんな入力値に対してもシステムを正常に動作させるための、完璧な「番兵(Guard Value)」として機能しているのです。

なお、末尾にFFがもうひとつあることについては後程解説しますね。

 

ランクの確定と保存

ループを抜けた時点で、Yレジスタを1つデクリメントした後の値(0~5)が、そのままプレイヤーの「現在の熟練度ランク」となります。そしてこの値を、後続の計算で使用するためにワーク変数へ格納。

 

<熟練度のレベルとランク判定の対応表>

熟練度レベル「1」 ランク判定「0」
熟練度レベル「2」 ランク判定「1」
熟練度レベル「3」 ランク判定「2」
熟練度レベル「4」 ランク判定「3」
熟練度レベル「5」 ランク判定「4」
熟練度レベル「6」 ランク判定「5」

 

熟練度の変動量の決定

このフェーズが、本ルーチンの核心部です。ここでは、勝利した「レースの難易度」と、先ほど判定した「プレイヤーのランク」を組み合わせ、最終的にどれだけ熟練度が成長するか(=数値が減少するか)を算出します。

レース別データの特定

まず、今回勝利したレースのID($0FA7、範囲は$01~$45)を読み込みます。
このIDを元に、ROM上に格納されている「レース別・熟練度変動量テーブル」を参照し、そのレースに対応するデータブロック(21バイト)の開始アドレスを計算してポインタに設定します。

 

乱数による揺らぎの生成

次に、0~2の3範囲を取ってから乱数生成ルーチンを呼び出し、乱数を取得します。

乱数により、同じランクで同じレースに勝ったとしても、毎回まったく同じ成長量になるわけではなく、結果にわずかな「揺らぎ」が生まれるよう調整されています。

 

最終的な変動量の算出

続いて、以下の計算式でテーブル参照用のインデックスを生成します。

インデックス = (熟練度ランク × 3) + 乱数結果(0~2)

このインデックス(Yレジスタ)を使って、特定したレースのデータブロックから実際の「熟練度変動量」を読み出し、ワーク変数に格納します。

ランク番号を3倍にする理由は、1つの熟練度ランクに対して、3バイト分のデータ(3つの乱数パターン)が割り当てられているからです。

もしも、データが1ランクにつき1つしかなければ、3倍する必要はありません。仮に、1ランクにつき5つものデータがあれば、5倍にする必要があります。今回は「乱数が3パターンある」ため、3倍しているわけです。

ここで重要なのが、「簡単なレースのデータブロックでは、高ランク部分の変動値が『0』に設定されている」という点です。

熟練度が高いプレイヤー(高ランク)が簡単なレースのテーブルを参照すると、計算結果として「0」が読み出され、「格下のレースに勝っても成長しない」というリアルな仕様が実現されているのです。

それでは実例として、「レースID:18 スプリングレース予選 決勝レース」に設定されている熟練度変動量テーブルの中身を見てみましょう。

 

<レース別熟練度変動テーブルの実例と意味をなさない乱数>

以下が、「スプリングレース予選 決勝ヒート」における熟練度変動量テーブルの中身(21バイト)です。

05 05 05 (ランク0用)
05 05 05 (ランク1用)
00 00 00 (ランク2用)
00 00 00 (ランク3用)
00 00 00 (ランク4用)
00 00 00 (ランク5用)
00 00 00 (ランク6用)

このデータを見ると、熟練度ランク0と1では「5」の熟練度が獲得でき、ランク2以上になると獲得量は「0」になることが分かります。
これ自体は「格下レースでは成長しない」という仕様通りですが……このデータを見て、何か奇妙なところにお気付きになりませんか?

答えに気付いた方は非常に鋭いです。

そう、各ランクごとに用意された3つの数値が、すべて同じ値(例: 05 05 05)になっているのです。

 

フェーズ3の解説で、「(熟練度ランク × 3) + 乱数(0~2)」という計算式を使い、乱数によって成長量に揺らぎを持たせていると説明しました。
しかし、テーブルの値がすべて同じであれば、この計算は何の意味も持ちません。

  • 乱数が 0 の場合 → 05 が選ばれる
  • 乱数が 1 の場合 → 05 が選ばれる
  • 乱数が 2 の場合 → 05 が選ばれる

このように、どんな乱数が生成されても結果は常に同じ「5」です。これでは、わざわざCPUサイクルを消費して乱数生成を行っている意味がありません。
さらに驚くべきことに、この現象はこのレースだけでなく、全てのレースのテーブルデータにおいて確認されました。どのレースでも「01 01 01」や「03 03 03」のように、同一の値が並べられているのです。

 

では、なぜこのような無駄な処理が実装されているのでしょうか。最も有力な説は、「開発途中の仕様変更による名残」です。

開発初期段階では、「熟練度の成長に『揺らぎ』を持たせよう」と考えていたと推測されます。
テーブルには [01, 02, 03] のような異なる値を設定し、「今回は運良く3も成長した!」「今回は運悪く1しか成長しなかった…」といったランダム性を楽しませる予定だったのでしょう。そのために、わざわざ「×3」のテーブル構造と乱数生成プログラムを実装しました。

しかし、開発終盤のバランス調整段階で方針が変わった可能性があります。
「成長量は固定値の方がプレイヤーが計画を立てやすい」「運が悪いプレイヤーが損をしすぎるのは良くない」といったフィードバックがデバッガーやテストプレイにてあったのかもしれません。

その結果、ランダム性を排除することになりましたが、既に完成しているプログラム(乱数生成や計算ロジック)を修正するのは、新たなバグを生むリスクがあります。
そこで、プログラムコードには手を加えず、参照するテーブルデータの方を全て同じ値(01 01 01)に書き換えることで、実質的にランダム性を無効化したのではないでしょうか。

 

最終的な熟練度の更新とセーブデータへの書き込み

最終フェーズでは、ここまで計算してきた「変動量」をプレイヤーの現在の熟練度に反映させ、セーブデータ領域に書き込みます。

熟練度の減算更新

まず、セーブデータから現在の熟練度($7F:002B)を再度読み込みます。
そして、この値からフェーズ3で決定した「変動量」を減算。

繰り返しになりますが、このゲームでは熟練度の値が小さいほど「腕前が高い」という設計になっています。そのため、数値を減らすことこそが、プレイヤーにとっての「成長」を意味します。

 

限界値のチェック(クランプ処理)

減算の結果、値がマイナスになっていないか(0を下回っていないか)を BPL 命令でチェックします。
もし計算結果が負の値になった場合は、熟練度が最高値を超えたことを意味するため、値を強制的に 0(最高ランク) に丸め込みます(クランプ処理)。これにより、データの整合性が保たれます。

 

セーブデータへの書き戻しと終了

最後に、更新された新しい熟練度の値を、元のセーブデータ領域($7F:002B)に書き戻します。これで次回のレースからは、成長した新しい熟練度が参照されるようになります。

全ての処理を終えると、スタックからプロセッサの状態フラグを復元し(PLP)、RTS 命令でサブルーチンを終了します。これで、「1位勝利時の熟練度上昇処理」は完了です。

この一連のプログラムにより、「自分の腕前に見合った挑戦的なレースで勝利することでのみ、効率的に成長できる」という、非常にリアルでやりがいのあるゲームバランスが実現されているのです。

 

<技術メモ:BPL命令によるアンダーフロー検知の仕組み>

プログラムでは、熟練度の減算結果が0を下回ったかどうかを BPL 命令で判定しています。しかし、熟練度は「符号なし整数(Unsigned Integer)」として扱われているはずです。なぜ、符号付き判定命令である BPL(Branch on PLus:プラスなら分岐)でアンダーフローを検知できるのでしょうか。

その理由は、CPUにおける「Nフラグ(ネガティブフラグ)」の動作原理と、2の補数表現の性質にあります。CPUのNフラグは、演算結果が「符号付き」か「符号なし」かに関わらず、純粋に結果の最上位ビット(MSB: Most Significant Bit)が「1」であればセットされるという単純なルールで動作します。

熟練度(0~255と仮定)から値を引いて0を下回った場合、コンピュータの世界では「アンダーフロー」が発生し、値が最大値側へラップアラウンドします。
(例:0 – 1 = 255 (1111 1111))

このとき、2の補数表現においては、0を下回ってラップアラウンドした値はMSBが必ず「1」になります。
人間がこれを「符号なし整数の最大値(255)」と解釈しようが、「符号付き整数の負の値(-1)」と解釈しようが、ハードウェアレベルでのビットパターンは同じであり、MSBが「1」であるためNフラグも「1」になります。

つまり、データの意味としては「符号なし」で扱いつつも、アンダーフロー検知の手段として、結果のビットパターン(MSB)を直接参照する BPL 命令を活用しているのです。

 

改造とメンテナンスによる熟練度変動システムの処理フロー解説

このプログラムは、改造メニューやメンテナンスメニューにおいて、プレイヤーがパーツの「改造」や「メンテナンス」を成功させた際に呼び出される、熟練度の上昇を計算・実行するルーチンです。

ご存知の通り、シャイスコではレース勝利時だけでなく、改造やメンテナンスを行った際にも主人公の熟練度が成長します。このルーチンの構造は、レース勝利時の熟練度計算システムとほぼ同一のコードを流用しており、効率的なデータ駆動設計の好例と言えますね。

改造時とメンテナンス時でそれぞれプログラムアドレスや参照するデータテーブルは異なりますが、処理の流れ自体は全く同じです。そのため、本項ではこれらを統合して簡潔に解説します。

 

熟練度ランク判定

レース時のと完全に共通のロジックです。プレイヤーの現在の熟練度を、内部的な「ランク」に分類します。

  1. セーブデータから現在の熟練度(0~255、0が最高)を読み込みます。
  2. 255 – 現在の熟練度 の計算を行い、「熟練度スコア」(値が大きいほど熟練)に変換し、ワーク変数に格納します。
  3. ROM上の「熟練度ランク・閾値テーブル」(0F, 28, 4C, 7D, BD, FF)と、プレイヤーの熟練度スコアを比較するループを実行。
  4. ループを抜けた時点でのYレジスタの値(0~5)が、プレイヤーの「現在の熟練度ランク」として、ワーク変数に保存されます。

 

変動量の決定

「どの改造およびメンテナンスを行ったか」と「プレイヤーのランク」を基に、具体的な変動量を算出します。

  1. 親ルーチン(改造メニュー制御・メンテナンスメニュー制御)から、「実行された項目ID」がワーク変数に渡されています。これをロードします。
  2. その項目IDをインデックスとして、ROM上の「改造別・熟練度上昇量テーブル群・インデックス」「メンテナンス別・熟練度上昇量テーブル群・インデックス」を参照します。その項目に対応する、さらに詳細なテーブルのアドレスを計算し、ポインタに設定します。
  3. 0~2の範囲で乱数を生成。
  4. (熟練度ランク * 3) + 乱数結果 という計算を行い、最終的なテーブル参照用のインデックスをYレジスタに生成します。
  5. 確定したインデックスYを使い、テーブルから具体的な「熟練度変動量」を読み出し、ワーク変数に格納します。

 

<改造項目ID・メンテナンス項目ID一覧>

改造項目ID
01:タイヤのカット
02:ボディ削り
03:カラー変更
04:コックピット部分の肉抜き
05:フロント部分の肉抜き
06:(未使用?)
07:逆テーパード加工
08:テーパード加工/グルービング加工

メンテナンス項目ID
01:モーターのブレークイン
02:フロントタイヤのよごれとり
03:リヤータイヤのよごれとり
04:ギヤーのグリスアップ
05:ターミナルみがき

 

<改造/メンテナンス別変動テーブルの実例>

ここで、メンテナンス項目の一例として「モーターのブレークイン」を行った際の熟練度変動量テーブルを見てみましょう。

02 02 02 (ランク0用)
01 02 02 (ランク1用)
01 01 02 (ランク2用)
01 01 01 (ランク3用)
00 00 00 (ランク4用)
00 00 00 (ランク5用)
00 00 00 (ランク6用)

なるほど…。
このテーブルデータからは、以下の特徴が見て取れますね。

低ランク(ランク0~3)のうちは、ブレークインを行うことで熟練度が「1~2」上昇します。しかし、ランクが上がるにつれて上昇量は徐々に減少し、ランク4以上になると「0」になります。つまり、ある程度熟練したプレイヤーは、ブレークイン作業ではもう成長できない仕様になっています。

ここで注目すべきは、同じランク内でも数値にばらつきがある点です。
例えばランク1の行を見ると 01 02 02 となっています。これは、乱数によって結果が変化することを意味します。

運が悪ければ(乱数0)→ 上昇量 1
運が良ければ(乱数1, 2)→ 上昇量 2

先ほどのレース熟練度テーブルでは全ての値が同じで乱数が機能していませんでしたが、こちらのメンテナンステーブルでは、設計通り乱数による「揺らぎ」が正常に機能していることが確認できました。

 

最終更新

ここも、レースの時と完全に共通です。

  1. セーブデータから、現在の熟練度を読み込みます。
  2. 読み込んだ熟練度から、決定した「変動量」を減算します。
  3. 減算の結果、値が0を下回っていないかチェックします。
  4. もしMSBが1になった場合は、値を0(最高ランク)に丸め込みます。
  5. 計算後の新しい熟練度を、セーブデータに直接書き戻して、処理を完了。

 

コラム:謎の21バイトデータブロックと幻の「7段階レベル」

これまでの解説で、熟練度変動テーブルには「1つの内容につき21バイトのデータブロック」が割り当てられていることを説明しました。

ここで、勘の鋭い方はある疑問を抱いたのではないでしょうか。

「プログラムのロジック上は6段階(ランク0~5)しか判定していないのに、なぜデータテーブルは7段階分(21バイト)も用意されているのか?」

 

全くそのとおりです。

計算式 (熟練度ランク × 3) + 乱数 に従えば、6段階のランクには 6 × 3 = 18バイト あれば十分なはずです。しかし、実際のROMには3バイト余分な「21バイト」が確保されています。このズレは一体何なのでしょうか。

 

この謎を解く鍵は、ランク判定に使われる「閾値テーブル」に隠されていました。

「0F, 28, 4C, 7D, BD, FF, FF」

ここには7つの値が並んでおり、末尾には FF が2つ続いています。

私は当初、これを $FFFF という2バイトの終端マーカーだと考えていました。($FFFFや$8000はよく使われるので)

しかし、実際のループ処理プログラムは最初に現れる FF を見つけた時点で処理を終了しており、最後の FF にアクセスすることはありません。

つまり、これは意図的な2バイト終端ではなく、「本来別の値が入っていた場所が、後の調整で FF に置き換えられた」、すなわち「使用されなくなったデータが FF で埋められて残っている」と考えるのが自然です。

 

ここで、「21バイト」という数字に戻りましょう。

もし、開発当初の構想では「熟練度ランクは7段階(0~6)だった」と仮定すると、全ての辻褄が合います。

データブロックのサイズ:
7段階(ランク)× 3バイト(乱数用)= 21バイト
現在のテーブルサイズと完全に一致します。

閾値テーブルの個数:
0F, 28, 4C, 7D, BD, (ランク6用の閾値?), FF
このように7つの値が用意されていたとすれば、データの個数とも一致します。

このことから、「開発中には7段階のランクシステムが想定されており、それが終盤で6段階に縮小された」という仮説が成り立ちます。

 

この仮説に基づき、当時の開発現場で何が起きたのか、シナリオを再構成してみましょう。

ゲーム設計段階では、熟練度は「レベル1~7」の7段階構成でした。これに合わせて、21バイト構成の変動量テーブルが作成されました。

しかし、テストプレイの過程で「7段階は細かすぎる」「最高ランクへの到達が難しすぎる」といった問題が浮上したのでしょう。そこで、ランクを1つ減らして6段階(0~5)に変更することが決定。

プログラマーは閾値テーブルを修正し、6つ目の値を FF (上限ガード)に変更しました。これにより、ランク判定処理は正しく6段階(0~5)で終了するようになりました。

しかし、既に作成済みだった膨大な「熟練度変動量テーブル(21バイト/レコード)」を、全て18バイトに切り詰める修正は見送られました。データの配置変更(アドレスシフト)は、新たなバグを生むリスクが高いからです。

プログラム側が「ランク6」を返すことはもう絶対にないため、各レコードの最後の3バイトは永遠に参照されない「未使用データ」として、ROMの中にそのまま残されることになったのです。

 

 

<決定的な証拠:当時の攻略情報誌>

実は、今回の解析で浮かび上がった「熟練度レベル7段階説」を裏付ける決定的な証拠が、ゲームの外、当時の攻略情報の中にも存在していました。
それが、アスキー(現KADOKAWA)発行の「ファミ通の公式無敵ガイド」と、1997年2月1日発行『ファミ通ブロス』1997年2月号別冊付録「ミニ四駆 シャイニングスコーピオン レッツ&ゴー!!  爆走大攻略」です。

 

まず、「公式無敵ガイド」の56ページには、「熟練度は一定量たまるとレベルアップする。レベルは1~7までの7段階で設定されている」との記載があります。ここには具体的な数値までは書かれていません。

 

しかし、「爆走大攻略」の巻末にあるデータページには、はっきりと「レベル1からレベル7」までの7段階で、以下のように熟練度の範囲を示す数値表が掲載されています。

『爆走大攻略』記載データ
熟練度レベル 経験値(誤)
レベル1 0~66
レベル2 67~80
レベル3 81~130
レベル4 131~179
レベル5 180~215
レベル6 216~240
レベル7 241~255

ところが、この「爆走大攻略」の表を、実際のゲームプログラム(解析結果)と照らし合わせると、明らかな矛盾が見つかります。

  • ゲーム内では熟練度数値が「低いほど高レベル(0が最高)」であるが、攻略本では「高いほど高レベル(255が最高)」として扱われている。熟練度スコアとして考えても値が合わない。
  • 実際のプログラム上の分岐点と、攻略本に記載された境界値が「1」ずれている。
  • 実際のプログラムではレベルは6段階(ランク0~5)までしか機能していないが、攻略本には7段階目が存在するものとして書かれている。

この2冊の共通点は、どちらも「ファミ通」編集部によるものであることです。

「公式無敵ガイド」には、他の攻略本には載っていない詳細なパーツデータなども掲載されていることから、編集部はメーカーから直接、内部資料の提供を受けていた可能性が高いと言えます。
おそらく、編集部が受け取った資料の中に、開発途中の「7段階仕様」のデータが含まれていたのでしょう。そして、製品版で仕様が「6段階」に変更されたことや、熟練度数値の大小の意味(0が最高か、255が最高か)についての確認が不十分なまま、冊子化されてしまったものと推測されます。結果として、ゲーム発売後の攻略本に、開発中の「幻の仕様」がそのまま掲載されるという事態が起きてしまったのです。

一方で、小学館(コロコロコミック)発行の「公式ガイドブック」6ページにも熟練度の記述がありますが、こちらは製品版の仕様通り「6段階」となっており、データの記載も正確です。
私が所有しているのは両誌とも初版であり、改訂版の有無は確認できていませんが、少なくとも発売当時の情報において、ファミ通系の攻略本は開発中のデータを、小学館の攻略本は製品版の仕様を元にしていたことが伺えます。

 

 

<消えた閾値の正体>
ゲーム内のプログラムは熟練度を「6段階」で判定しているのに対し、当時の攻略冊子『爆走大攻略』には「7段階」のデータが記載されている。さらに、このデータはレベルの順序が逆転しているだけでなく、境界値も微妙にズレています。
この矛盾を解き明かす鍵は、ROM内のデータテーブル末尾にある「FFFF」という値と、攻略本に残された「81」という数字にありました。

まず、現在の熟練度ランク判定テーブルは以下のようになっています。

0F, 28, 4C, 7D, BD, FF, FF

これは明らかに6つの区切り(ランク0~5)を示しています。しかし、先ほどのコラム「謎の21バイトデータブロック」で触れた通り、参照される変動量データテーブルには、なぜか「7段階分(21バイト)」の枠が用意されています。
つまり、「本来ならもう1つ、ランク(閾値)が存在したはず」なのです。

では、消えた7つ目の閾値は、この数列のどこにあったのでしょうか?

攻略冊子のデータを、ゲーム内の計算式(255 – 熟練度)に合わせて変換し、境界値の「1」のズレを補正していくと、驚くべき事実が浮かび上がります。
攻略冊子が「レベル3」と「レベル2」の境界としている「81」という数字。これをゲーム内の熟練度スコアに換算すると 174 ($AE) となります。

一方、実際のROMテーブルにある閾値 $7D (125) と $BD (189) の間を見てください。ここには数値的に大きな開きがあり、ぽっかりと空白が空いています。
もし、ここに $AF (175) という閾値が存在していたらどうでしょうか?

0F, 28, 4C, 7D, [AF] , BD, FF

こうすれば、データテーブルのサイズ(7段階)とも完全に一致します。

さらに、攻略本に記されていた「81~130」という謎の区間も、$7D(125) ~ $AF(175) という範囲として、ピタリと説明がつくのです。

以上のことから、開発終盤の段階で削除され、FF に置き換えられることで消滅した「閾値」の正体は、5番目の位置にあった「 $AF (175) 」である可能性が極めて高い。

かつて存在したはずの境界線は、仕様変更の波に消えましたが、その痕跡は今も攻略本の片隅とROMデータの隙間に、ひっそりと残されていました。

 

マシンの速度は熟練度に応じて変化

速度の変化は段階的に行われ、以下は熟練度ごとのマシン速度の変化段階とメモリ値の対応表です。※メモリ値はゲーム内部での数値を示す。16進数と(10進数)

マシンの速度レベル
累計熟練度ポイント
メモリ値
Lv1 (最遅)
0
0xFF (255)
Lv2
1〜14p
0xFE〜0xF1 (254〜241)
Lv3
15〜39p
0xF0〜0xD8 (240〜216)
Lv4
40〜75p
0xD7〜0xB4 (215〜180)
Lv5
76〜124p
0xB3〜0x83 (179〜131)
Lv6
125〜127p
0x82〜0x80 (130〜128)
Lv7
128〜188p
0x7F〜0x43 (127〜67)
Lv8 (最速)
189〜255p
0x42〜0x00 (66〜0)

 

ちなみに、S.G.J.C(スーパーグレートジャパンカップ)で優勝するための熟練度についてですが、乱数やスタートダッシュの僅かな遅れを考慮した上でも安定して勝つために必要な熟練度を検証してみたところ

1コース: 0x82 (累計熟練度が125以上)
2コース: 0x82 (累計熟練度が125以上)
3コース: 0xB3 (累計熟練度76以上)
4コース: 0x82 (累計熟練度が125以上)
5コース: 0x82 (累計熟練度が125以上)

という結果になりました。

攻略推奨セッティングの状態にセッティングして、タイヤバグは使用していません。周回のないSGJCコースでは、距離の短い3コースが最も有利で、少ない熟練度でも優勝することができます。

 

主人公以外の熟練度

実は主人公以外にも熟練度は設定されています。ただし、キャラ自体に熟練度があるということではなく、レースの出走マシンのステータスに熟練度が設定されているわけです。

以下は各レースでの主要マシンの熟練度値のリストです。
※イベントレース、主要レースのみ掲載
※モブマシンは省略

<朝日町 エキシビジョンレース>
サイクロンマグナム 0x3C
ハリケーンソニック 0x3C

<朝日町タイマンレース>
ブラックセイバー 0xFF

<ゲームセンター藤吉レース>
スピンコブラ 0x81

<スプリングレース予選 決勝ヒート>
スピンコブラ 0xFF
ブラックセイバー 0xFF

<日光平 ミニ四グリーンカップレース>
サイクロンマグナム 0x41
ハリケーンソニック 0x41

<スプリングレース決勝>
スピンコブラ 0x81
サイクロンマグナム 0x41
ハリケーンソニック 0x41
ブラックセイバー 0xB2

<野試合バトル>
ビークスパイダー 0xB2

<海浜パーク エキシビジョンレース>
サイクロンマグナム 0x81
ハリケーンソニック 0x81
トライダガーZMC 0x81

<サマーレース決勝>
トライダガーZMC 0x81
サイクロンマグナム 0x81
ブロッケンギガント 0x81
ハリケーンソニック 0x81

<タイマンレース>
ビークスパイダー 0x41
ブロッケンギガント 0x81
スピンコブラ 0x41
トライダガーZMC 0x81
レイスティンガー 0x81

<共通予選レース>
ブロッケンギガント 0xFF
ブロッケンギガント 0x82
ブロッケンギガント 0x81
ビークスパイダー 0x6E

<オータムレース決勝>
サイクロンマグナム 0x81
ハリケーンソニック 0x81
レイスティンガー 0x81
ブロッケンギガント 0x81

<スーパーグレートジャパンカップレース>
サイクロンマグナム 0x41
ハリケーンソニック 0x41
トライダガーZMC 0x41
レイスティンガー 0x41

関連記事

  1. 自転車保険 家族で入ればオトク

  2. 八方位・二十四方位の意味とパワー

  3. 【2014年モデル】 オルベアのロードバイクの種類とまとめ一覧

  4. 【2014年モデル】 サーベロのロードバイクの種類とまとめ一覧

  5. ロードバイクはお金のかかる趣味なのか

  6. 【2014年モデル】 デダチャイストラーダのロードバイクの種類と…

おすすめ記事

  1. 【兎田ぺこら】「チキン冷めちゃった」とは?元ネタ・意味・その後を解説しよう【冷めチキ】
  2. 【ドラゴンクエスト3リメイク】評価・レビュー プレイした感想【そんなにひどいか?】
  3. SFC シャイニングスコーピオン 攻略チャートその1 ~朝日町~
  4. N64 風来のシレン2 鬼襲来!シレン城! デバッグモードのやり方・コツ
  5. スーパーファミコン改造方法まとめ チートのやり方

新着記事

  1. Steam版『ドラゴンクエスト1&2 HD-2Dリメイク』において、ショップの売り物を自由に変更でき…
  2. 業務でもDIYでも金属加工に欠かせないドリル。しかし、使っているうちに切れ味が落ちたり、時には先端が…
  3. Amazonマーケットプレイスで購入した中古本を、旧住所の設定のまま注文してしまいました。しかも配送…
ページ上部へ戻る