【幻想蛮怒】幻想郷を覗いてみようーwiki編集者の腹のうち
本稿はRoguelike Advent Calendar 2023の1日目の記事です。前営業日(?)はgkurakiさんによる「変幻蛮怒の更新について」です。
内容をざっくり言うと
プログラムが解らなくても、ソースコードからゲーム攻略的に欲しい情報は割と簡単に読み取れる。
なぜなら、そういうデータは、箇条書きやカンマ区切りの文字列群で書かれていて、ちょっとその読み方を覚えるだけでよいから。
職業(ユニーククラス)、敵の特別設定ドロップ、属性の効果など、割とよく追加される要素の読み方を紹介する。
これでwiki編集者(記事投稿者)が増えるとうれしい。
はじめに
筆者は幻想蛮怒wikiの主たる記事投稿・編集者です。wikiの開設以来、相当数の記事を投稿してきました。それらの記事の多くはソースコードを読んで作成しているわけですが、筆者はプログラムをやる人間ではありません。それではなぜあれだけの記事を起こせたかというと、理由は2つ。
1つは、ソースコード内に処理の内容に関する作者(みやまさ さん)のコメントが極めて丁寧に入っているため。ほぼ全ての漢字に読み仮名が振られているレベルと言っても過言ではないです。
もう1つは、プレイヤー的に欲しい情報の多くは箇条書きやカンマ区切りの文字列群で書かれていて、ちょっとその読み方を覚えるだけでよいから、です。格闘攻撃を例にすると、格闘攻撃をするという大本の処理がまずあって、個別の性能は別のところにまとめて記述してあり、そこから処理の際に必要な値を引いてくる、という構造になっています。プレイヤーが実際にほしいのは、細かい条件分岐とかの仕組みではなくて、威力や追加効果とかの数値性能の情報ではないでしょうか。
プログラムをプログラムとして文法に従って読む方法なんてものは、筆者には到底説明出来ませんが、後者のデータ群の読み方くらいならなんとか説明できます。本稿では比較的高頻度に内容が追加される要素について、その箇所の読み解き方を説明します。
準備
ソースコード
幻想蛮怒配布サイトの下部「ソースコード」からのリンクを辿ってgithubへ。top画面の中央右より「Code」>「Download ZIP」でファイル一式をダウンロードできます。解凍した中身のうち、「src」フォルダの中身が今回の対象です。どのファイルもwindows付属のメモ帳で開けますが、そのまま/それだけだとかなり読みづらいですので、以下の「あると便利なもの」も導入することをお勧めします。
あると便利なもの
テキストエディタ
メモ帳も広義ではテキストエディタですが、ここではプログラミング向けの高機能なものをいいます。プログラム言語の構文を見やすく可視化してくれるので、可読性が劇的に向上します。「テキストエディタ」でweb検索すると、お勧め紹介サイトがたくさん出てきます。どれでも大丈夫ですが、「プログラミング」とか「コーディング」みたいな言葉が併記されていたり、使用画面のスクリーンショットで文字がカラフルになっているやつだと間違いありません。ちなみに筆者は長らく「TepaEditor」を使っています。選定理由は最初に触ってしっくり来た、だけです。
grepツール
ファイルを横断して文字列を検索することができるツールです。これも「grepツール」で検索すると色々出てきます。↑のテキストエディタの中でも高機能なものには備えているものもあるようです。本稿ではこれを使うほどの読解はほぼ扱わないのですが、ある処理の中で別のファイルにある処理を行う、ということがよくありますので、そういうのを読み進める時に便利です。また、ゲーム内で気になるメッセージを見た時に、それで検索を掛けて、起こった事象の内実を読み解くようなことにも使えます。こちらは筆者は「TresGrep」を使っています。
覗いてみよう
各verの更新事項
githubの幻想蛮怒top画面の「asamayim」のリンクを踏むと、これまでの更新verが上から新しい順に並んでいます。所望のバージョン(v2.0.12とか)のリンクをたどると、内容に更新があったソースコードのファイルと、その変更箇所を確認できます。
職業(ユニーククラス)関係
以降の内容はv2.0.12のソースコードを題材にして解説します(バージョンを決めておかないと、◯行目という説明がしづらいので)。
ステータス修正など
「tables.c」の2430行目から各クラスの能力修正など一式がならんだデータ群があります。最初から戦士、メイジ、神官(巫女)・・・と一般職が続き、3195行目から宵闇の妖怪(ルーミア)、半人半霊の庭師(妖夢)・・・とユニーククラスが出てきます。ここでは5386行目の「森で垂迹した魔法地蔵」を例にとって、データの見方を説明します・・・文章にした方が見づらくなったので、図(絵)にしました。
ちなみに1556行目からは種族の能力修正など一式が似たような感じで並んでいます。データ群の冒頭のところに簡単に読み方が記載されているので、ついでに見てみてはどうでしょうか。
レベルごとの特殊能力など
「xtra1.c」の4986行目から各クラスのレベル毎に得られる特性についてのデータ群があります。最初に「case CLASS_WARRIOR」つまり「職業 戦士の場合は以下のようにする」とあり、以下「case CLASS_ARCHER」「case CLASS_PRIEST」…と続き、5149行目から「case CLASS_RUMIA」と以降ユニーククラスのデータが並びます。ちなみに上記のように「CLASS_XXXX(東方キャラ名)」以下でユニーククラスに関する個別の扱いの記述がされていることが多いので、色々自分で調べる場合は覚えておくといいと思います。ここでは5186行目の華仙を例に説明します。例によって画像にします。
特殊性格や、聖の転読のようにレベルごとに強化内容が進化していくバフの効果の内容なんかもここにこんな形で書かれています。
クエスト「古い城」の報酬
「cmd2.c」の807行目から戦士「if(p_ptr->pclass == CLASS_WARRIOR)」、騎兵「if(p_ptr->pclass == CLASS_CAVALRY)」と、「if … CLASS_XXXX」を目印にした箇条書きで記載されています。905行目以降、華仙「CLASS_KASEN」を筆頭にユニーククラスが並んでいます。912行目~933行目を例にして説明します。
実は一連の内容は、「箱を開ける」という行為の処理内容の一環として書かれており、この内容の前後には他のクエスト報酬の箱やMARIPOの箱の中身についても列記されています。なお、多分この内容については、所望のクラスのキャラを作り、ウィザードモードで「大きな葛籠=古い城の報酬箱」を生成して開けるのが早いと思います。
職業特技
「new_class_power.c」というまさにそのものと言っていい名称のファイル内に一切が記述されています。冒頭に概要的なコメントが少々あって、17行目から慧ノ子の内容の記述が始まります。各クラス毎にまず、技の名称、習得レベル、コスト、説明などがカンマ区切りでまとめられたデータ群があり、その後に各特技の個別の処理内容が書かれている、という形です。
データ群の読み方は以下の通り。ここでは1248行目からの飯綱丸のところを用いて説明します。
この一連のデータ群の下に、各特技の処理内容が記載されていますが、データ群の読み方を説明するという趣旨からは逸れるので、ここでは割愛します(正直に言うと、ボロが出るからです)。多くの場合、威力、効力、効果時間の計算式が書かれています。計算式のところでよく使われる書かれ方をいくつか紹介しておきます。
・ plev や p_ptr->lev:プレイヤーのレベル
・ chr_adj:魅力影響値
・ randint1(xxx):1~xxxの乱数。1d(xxx)と同じ
・ randint0(xxx):0~xxxの乱数。1d(xxx + 1) -1 と同じ
・DETECT_RAD_DEFAULT:感知系特技のデフォルト効果範囲、つまり30
ちなみにこの「new_class_power.c」の下の方(36062行目以降)にはEXTRAモード時のアイテムカードのデータ群があります。アイテムカードは基本的にユニーククラスの職業特技の一部を切り出して行使するものなので、このファイル内にまとまっているようです。
専用格闘パターン
「cmd1.c」の3728行目辺りから各格闘パターンへの分岐条件(変身、補助魔法、クラス、種族など)がある。wikiの「格闘」参照。その中に専用パターンテーブルの名称が指定されていて、その中身は「tables.c」の10184行目から記載されている。これもwikiの「格闘」及び「格闘パターン一覧」参照のこと。
特別なアイテムドロップ処理
「xtra2.c」にモンスターが倒された時の処理の一環として書かれています。大きく3群に分かれています。ここはモンスターの固定ドロップアイテムを参照しながら見てみるとわかりやすいと思います。
まず、2264行目から、『モルゴス』が★グロンドを落とす処理(case MON_MORGOTH )を筆頭に、「case_MON_XXXX」を区切りとした箇条書きで『混沌のサーペント』、デスソード…と2974行目まで続きます。この部分は特定モンスターによる特定アイテムドロップに相当します。
続けて、2997行目から、特定のモンスターが銃をドロップする処理が並んでいます。『清蘭』(case MON_SEIRAN)、『鈴瑚』(case MON_RINGO)が高級品確定のルナティックガンを落とす処理から、『うどんげ』、イーグルラヴィ…と同じく「case_MON_XXXX」を区切りとした箇条書きが3066行目まで続きます。この部分は銃の特別ドロップに相当します。
最後に3114行目から、特定のモンスターが特定の★を落とす処理が書かれています。ここでは各モンスターの処理の中に「chance = 50」などと書かれており、乱数0~99 < chanceなら落とす、という処理がなされます(この場合は落とす確率50%)。『オベロン』が確定で★アンバー冠か★審判の宝石を落とす処理(case MON_OBERON)から始まり、以下3495行目まで続きます。この部分は特定ユニークによる特定★ドロップに相当します。
属性
「spells1.c」にモンスターが受けた場合と、プレイヤーが受けた場合について書かれています。それぞれ「case GF_XXXX(例えば火炎属性ならGF_FIRE)」を区切りとして箇条書き的に書かれています。複雑な処理も多いので、ここでは簡単なものを例示するに留めます。
モンスターが受ける場合
2664行目から始まり、以下8975行目まで膨大な数の属性の処理内容が続きます。言うほど箇条書きかと詰められるとごめんなさいなのですが、↓のように各行に「読み仮名」を振られてみると、案外他も自分で読めそうな気がしませんか? 内容的には全耐性持ち(=はぐれメタル)、通常耐性持ち、弱点持ち、普通に効く場合、というように条件ごとに「if」で仕切られて書かれています。
プレイヤーが受ける場合
9797行目から記述が始まります。最初200行程度は烏天狗のボルト無効化のような特別な防御処理について書かれており、10050行目から属性の各論に入り、2000行あまり続きます。最初に攻撃を正しく視認していない場合のメッセージがあり、その後耐性がある場合、そうでない場合のダメージ、そして追加効果、のような流れで記載されています。
モンスターの魔法など
「mspells1.c」の2720行目から記載されています。「case xxx(xxxは内部的な番号)」で仕切られて列記されています。多くのモンスターの攻撃魔法は変愚蛮怒と共通しているので、幻想蛮怒プレイヤーにとって重要と思われる箇所をピックアップしておきます。
幻想蛮怒新規追加の魔法
6401行目から記載されています。なお、従来の内部番号を使い切ったため、新たな番号を起こしたという感じのようで、これより前のところに書かれているものもいくらかあります(コズミックホラーなど)。
「特別な行動をすることがある」の内容
4811行目から記載されています。原作ネタをモンスターの技でどう表現するか、という点でなかなかの見どころだと思いますし、今後も追加が期待されるところでもあります。
「救援召喚」の特殊処理
「救援召喚」は通常は使用者と同じシンボルのモンスターを召喚するものですが、特殊処理で特定のモンスターを呼ばせる設定が多数なされています。
5477行目から記載されています。
最初約100行は使用した時のメッセージが特別なものになるものが列記されています(例: 『アリス』が使用する場合の「『アリス』が人形達を呼び出した。」)。
その後、5561行目から個別の召喚内容が書かれています。
ここだけでは少しわからないところが残りますね。大鷲ユニークの場合の「SUMMON_EAGLES」、『マミゾウ』の場合の「MON_TANUKI」、「MON_O_TANUKI」の中身が具体的には何なのか、です(うっすらと察しはつきますが)。こういう時に、最初に紹介した「grepツール」が使えます。自分で調べて答えを見つけるのを楽しんでほしいですが、一応答えも書いておきます。前者は「monster2.c」の691行目からのデータ群の中の969行目で規定されていて、「Bシンボル 且つ 山 且つ 野外 のモンスター」となっています(結果的に、鷲、大鷲、自身より下位の大鷲ユニークが出てきます)。後者は「defines.h」内でモンスターのIDで規定されています。具体的には「No. 1228 妖怪狸」と「No. 1229 妖怪古狸」です。
もっと複雑な処理も読みたい
プログラムをプログラムとして読み進める作法を、ローグライクを題材にして解説した記事がなんとあります。今年この記事を書くために去年ひらおよぎを復刻した甲斐がありました。
こういうのを参考にしつつ、興味があるところを読んでみてください。上の「あると便利なもの」のgrep検索がスタートになることでしょう。
冒頭にも書いた通り、幻想蛮怒で新規に取り入れられた要素については、作者さんが丁寧にコメントを入れていて、その処理で意図していることや通常プレイにおける結論がほぼ確実に書かれています。また、先行の解析事例を参照しながら改めてその場所を見てみる、自分なりに読解した内容をウィザードモードで確かめてみる、などを繰り返すことで、「こう書いてあったら、こう読み解く」が蓄積されていきます。そうしたらいつしか「中国語はわからないけど、漢字の並びでなんとなく意味がわかる」的な状態になります、というかなりました。
要は(ちょっと理系要素の入った)語学の独学ということで、向き不向きは実際のところあるとは思いますが、表に出てないだけで内部的にはちょっと面白いことをやっていたり、本当はもっとスマートな方法があるだろうけど泥臭い方法しか思いつかなかったという作者さんの嘆きとか、思い切って踏み込んでみるとなかなか面白いものを見ることができますよ。
なんでこんな記事を書いた
2016年6月16日の変愚蛮怒東方勝手版@wikiの開設(ちなみに筆者は>>750です)から早7年、元号は変わり、学生は社会人になり、既に社会人だった筆者は無事おじさんになりました。このくらいの年次になると熟練度は上がってくるのですが、「自分でやったほうが早いし出来が良い」を考えなしにやると、後々になって嫌な形で跳ね返って来ることを実感させられます。いわゆる属人化はNGという話です。そういった観点で長らく関わってきた幻想蛮怒wikiを見ると、自分の所業は必ずしもよろしくないなと。筆者は(時々サボっていた事は流すとして)幻想蛮怒の毎月の更新の度に「課題図書」だと嬉々として更新内容をwikiに反映させて来ましたが、これは未来の編集者さんの芽を摘み取る行為でもあるよなと思い至りました。というわけで、未来の編集者さんの種蒔き的なことを今年はちょっとやろうかということで今回この記事をしこたま酒を飲んでから書き始めたんや書きました。
終わりに
大変な長文お疲れ様でした。これを読んで、意外と読める…?ちょっと読んでみるか、という人が一人でも生まれたら僥倖です。未来の編集者さんが生まれるきっかけになることを祈って筆を置きましょうか。やはり大勢で編集まみれになるのは最高やで。こんな編集親父とwiki遊びしないか。ああ^~早く編集まみれになろうぜ。幻想蛮怒wikiで会えるやつなら最高や。
明日2日目はgkurakiさんによる「今更、ディアボロの大冒険でレクイエムの大迷宮を素潜する」です。
あとがき(2023/12/31追記)
本稿をベースとした記事を幻想蛮怒wikiに投稿しました。これを以て、幻想蛮怒wikiの編集から引退します。理由は東方コンテンツを追いかけるモチベーションがなくなったからです。作業負荷的には大したものではないのですが、原作再現の妙味を楽しむことも重要なこの作品に対して、リスペクトのない機械的なタスク対応するのもどうかと思ったので。ということで、後は頑張れ若い人。