プログラミング・動画編集 備忘録

プログラミングや動画編集についての備忘録です

The Elder Scrolls: Arena の日本語化 - 5(NPCの仕組み1)

前回

フォント修正をさらに突き詰めてみたが、やはり下手にいじると認識精度は落ちる。
さらにMSゴシックに近くなるようにフォント修正して、そのMSゴシックで使う文字だけのTesseractのトレーニングデータを作ってみたが、まったくだめだった。
rrryutaro.hatenablog.com

今回

PCOTだけでも十分やっていけいそうで、+αでテキストデータとれるものはそこからテキストを取得して翻訳していくため、実際にゲームをプレイしながらやっていくことにした。
とりあえず最初のダンジョンをクリアして最初の街に着いたので、まずはその辺にいるNPCとの会話の仕組みを確認する。
プレイの内容などはこちら。
rrryutaro.hatenablog.com

NPCのメニュー

NPCをクリックすると次のメニューが表示される。
f:id:rrryutaro:20220306214917p:plain

Who are you?

NPCが何者なのかを確認するのだが、この部分はTEMPLATE.DAT#0100に登録されているテキストの内にどれかがランダムで選ばれる模様。
1つ分のテキストの終わりは&で示していて、%の後に続くのが置き換え用の指定だろう。

(以下、実際には1行空白行を挟んでいるがここでは空白行を削除している)

#0100
Greetings, I am %n, a %oc. I %doc.&
They call me %n the %oc. I %doc.&
I am called %n, the %ct %oc. You know, I %doc.&
You can call me %n. I am a %oc, you know, I %doc.&
You can call me %n. I am a %oc. I %doc.&
We haven't met, have we? I'm %n, the %oc. I %doc.&
Good day, %ra. My name is %n the %ct %oc. I %doc.&
I am named %n. I'm a %oc and I %doc.&
Greetings, %ra. I'm %n, a typical %oc, and I %doc.&
My name is %n, the %oc. I %doc.&
指定子 意味
%n NPCの名前
%oc TEMPLATE.DAT#0262で定義されている職業
%doc NPCそれぞれの台詞など


例えば、次のパターンが選ばれた場合。
They call me %n the %oc. I %doc.

次のように置き変わる。


They call me Chrystona Hawkfield the mason. I think I have a chance to work on the Lord's palace.

私は石工クリストナ・ホークフィールドと呼ばれています。主の宮殿で働くチャンスがあると思う

%docはさらに固有で色々とあると思われる。このケースではTEMPLATE.DAT#0310部分が使われている模様。

#0310
have been repairing some stonework at the %tem temple all day&
think I have a chance to work on the %t's palace&
basically do general repair work on stone all around the city&

さらに詳しい仕組みについて

OpenTESArena について

NPCの仕組みについて調べるにあたって、UESP (The Unofficial Elder Scrolls Pages) のArena:Arenaのページを見ていたら、OpenTESArena というものの存在を知る。
github.com


This open-source project aims to be a modern engine re-implementation for the 1994 video game The Elder Scrolls: Arena by Bethesda Softworks. It is written in C++17 and uses SDL2, WildMIDI for music, and OpenAL Soft for sound and mixing. There is support for Windows, Linux, and macOS.

このオープンソースプロジェクトは、1994年のビデオゲームThe Elder Scrolls」の現代的なエンジンの再実装を目的としています。Arena (Bethesda Softworks) の現代的なエンジンの再実装を目指します。C++17で書かれ、SDL2、音楽にはWildMIDI、サウンドとミキシングにはOpenAL Softを使用しています。WindowsLinuxmacOSのサポートがあります。

ただまだ実際にしっかりプレイできるまでにはないっていない様だが、コードを読むことで仕組みなどが把握できそう。

NPCデータの保存内容

OpenTESArenaの ArenaTypes.h にて SAVEENGN.xx ファイルの構造が記載されているのでそこで把握できる。
NPCのデータは1人分が次のように定義されている。

		struct NPCSprite
		{
			static constexpr size_t SIZE = 28;

			uint16_t x, z, y;
			uint16_t pDynamicLight; // void* in original.
			uint16_t speed, angle;
			uint8_t flat, frame, param1;
			uint16_t flags;
			uint8_t param2;
			uint16_t data, param3, unknown1, unknown2, param4;

			void init(const uint8_t *data);
		};

NPC 1人は28バイトのデータで、15人分の配列となっているもよう。
このためおそらく、待ちなどに存在できるNPCは最大で15人になるのかと思われる。
なお、書き込まれるデータは暗号化される。
UESPのArenaのTechnical Referenceのページを確認するとどういった手法なのかは把握できるが、NPCについての解説は無いので、各NPCのデータがどのように格納されるのかなどは、OpenTESArenaのコードを確認するなりして解析する必要がありそう。

NPCの名前

OpenTESArenaに TextAssetLibrary::generateNpcNameというのがあるので、この辺のコードを読めば把握できそうではあるが、詳しくは見ていない。
わかっている点としては、NAMECHNK.DATに次のようにデータが保存されている。
なお以下のデータは一部抜粋で、NULL部分は|に置き換えて、その他表示できない制御コードも削除している状態のもの。

Theod|And|Bed|Per|Rod|Gond|Edw|Mord|Agr|Trist|Dun|Alab|Uth|F|
ore|ynak|ywyr|yval|yrick|oryan|ard|yn|yctor|ane|istair|astyr|istyr|D|
Morg|Gwyn|El|Ys|Elyz|Vyct|Lys|Vann|Chryst|Evel|Carol|Barb|Bellad|B|
anna|yvyra|ayne|olda|abyth|ausa|orya|yssa|yrrya|yn|yna|ara|ona|M|
Hawk|Wood|Yeom|Hearth|King|Green|Gaer|Master|Moor|Copper|Bucking|Ash|Wick|D|
wing|house|sly|croft|sley|hart|field|ston|ing|smith|ham|ton|ford|3B|Ba|Br|Bl|B|C|Cr|Ca|C|Ch|D|D|Dh|F|F|Fl|Fh|Fr|G|Gl|Gr|Gh|K|Kl|Kr|Kh|L|Lh|M|Ma|Mh|M|N|Nh|R|Ra|Rh|Rl|S|Sa|Sl|St|Sh|Shr|T|T|Tl|Th|V|Vl|V|
|a|e|i|o|u|!|b|c|d|h|j|k|l|m|n|p|r|s|t|v|z|G|an|en|in|on|un|e|am|em|im|om|um|t|ke|'kern|rn|er|ar|ir|ur|te|ta|ten||i|-i|-si|ti|ki|ka|-e|7|
Er|Kj|Torb|Fenr|Moj|Ingm|Asg|Al|Bj|Sor|Har|Jurg|Ulr|4|
ik|eld|en|is|ens|ar|er|arik|orn|arke|ald|an|arne|;|
Hell|Jyt|Kirst|Ull|An|Bet|Han|Morg|Dor|Met|Ell|Sill|Ing|e|te|en|a|ne|ina|ia|7|
Er|Kj|Torb|Fenr|Moj|Ingm|Asg|Al|Bj|Sor|Har|Jurg|Ulr|4|

NPCの名前は、種族での名前の傾向などから、この中からランダムで組み合わせて生成されていると考えられる。
例えば Chrystona Hawkfieldというブレトンの名前のChrystona部分はChrystonaを合わせたもので、Hawkfield部分はHawkfieldを合わせたものとなっている事になる。
そしてNPCの名前はNPCSprite構造体のuint16_t data部分で管理されている。
これは実際に、ゲームのデータを書き換えて確認した。


変更前
f:id:rrryutaro:20220313183514p:plain
f:id:rrryutaro:20220313184035p:plain

変更後
f:id:rrryutaro:20220313184117p:plain
f:id:rrryutaro:20220313184340p:plain

なお、NPCは会話前と会話後で内容が変わるが、この話したかどうかのフラグもこのuint16_t dataの内の次の部分にフラグとして持っていると思われる。
f:id:rrryutaro:20220313185030p:plain

また、性別についてはuint8_t param2で管理されていると思われる。


女性
f:id:rrryutaro:20220313184117p:plain
f:id:rrryutaro:20220313185750p:plain

男性
f:id:rrryutaro:20220313185331p:plain
f:id:rrryutaro:20220313185521p:plain

この部分(0xA5F0xA7A)では女性か男性は878Aとなっているが、例えば次のNPCの番地の0xA7B0xA96では暗号化のため異なる値となる。

%oc のNPCの職業一覧

TEMPLATE.DAT#0262をそのままDeepL翻訳したもの。

# 英語 日本語
1 scribe 代書屋
2 servant 下男
3 musician 楽家
4 merchant 商人
5 Druid ドルイド
6 Monk 僧侶
7 Priest プリースト
8 Ranger レンジャー
9 bodyguard ボディーガード
10 Mage 魔道士
11 thug チンピラ
12 bum クズ
13 Thief シーフ
14 Assassin アサシン
15 Rogue ローグ
16 Bard 吟遊詩人
17 historian 歴史家
18 gardener 庭師
19 animal handler 動物取扱業者
20 warlock ワーロック
21 hunter 狩人
22 politician 政治家
23 publican 風俗嬢
24 bartender バーテンダー
25 vintner 酒造家
26 cook 料理人
27 armorist 甲冑師
28 artist アーティスト
29 farmer 農家
30 fisher フィッシャー
31 jeweler 宝石商
32 tanner タンナー
33 carpenter 大工
34 navigator 航海士
35 sailor 船員
36 shipwright 船大工
37 tailor テーラー
38 trapper トラッパー
39 valet 従者
40 alchemist 錬金術
41 blacksmith 鍛冶屋
42 sage 賢者
43 steward スチュワード
44 aristocrat 貴族
45 Mystic 神秘主義
46 guildmaster ギルドマスター
47 apprentice 見習い
48 mason 石工
49 falconer 鷹匠
50 innkeeper 宿屋
51 baker パン屋
52 butcher 肉屋
53 barber 理容師
54 bootmaker ブーツメーカー
55 grocer 食料品店
56 tinker 鋳物屋
57 banker 銀行員
58 moneylender 金貸し
59 goldsmith 金細工職人
60 silversmith 銀細工師
61 weaver 織物
62 glassblower ガラス吹き
63 joiner 建具職人
64 scholar 学者
65 interpreter インタープリタ
66 apocathary アポカタリ
67 physician 医師
68 clerk 事務員
69 mercenary 傭兵
70 gaoler 牢屋
71 astrologist 占星術
72 herald ヘラルド
73 crier 泣き虫
74 poet 詩人
75 actor 俳優
76 playwright 脚本家
77 laborer 労務
78 fieldhand フィールドハンド
79 inquisitor 調査官
80 toll collector 料金徴収員
81 Oracle 神託
82 sculptor 彫刻家
83 ebonysmith エボニースミス
84 mathematician 数学者
85 Exorcist エクソシスト
86 dancer 舞踏家
87 tracker トラッカー
88 herbalist ハーバリスト
89 student 学生
90 philosopher 哲学者
91 crusader クルーセーダー
92 pilgrim 巡礼者
93 shepherd 羊飼い
94 squire 従者
95 cobbler コブラ
96 peddler 行商人
97 miller 粉屋
98 nomad 遊牧民
99 tavernkeeper 居酒屋の店主
100 idiot バカ