ドリルは漢のロマンだ




広告


ソース解析


某所よりソースを入手したので、命中率やダメージ算出式を解析してみた。ソースコードのバージョンは1.31と思われる。故に最新のバージョンでの数値とは多少異なるかも知れない。

計算は、式の途中で小数点以下第二位を勝手に四捨五入してたりするので、厳密な数値ではない。random(10)という式は乱数で0〜9の数値を発生させる関数。この場合平均値は4.5。



命中判定


ソース(DamageManage.cpp)から導かれる命中率は、
命中値 
攻撃側技量+(技量*地形修正)+20
回避値
防御側技量+(技量*地形修正)+20
真の命中率=命中/回避*80

通常攻撃による状態変化は攻撃命中時に、もう一度命中判定を行う。その結果、再度命中した場合に状態変化を受ける。弱い属性が有る場合、常に命中扱いになる。

例:1
地形、双方等も山地。
グラディエイター:技量62、修正0%。命中値=62+0+20=82
バルバッタ:技量95、修正+50%。回避値=95+(95*0.5)+20=157.5
命中率=82/157.5*80=41.6%

実際の試験:60回中28回命中、46.7%。

例:2
地形、双方等も砂漠。
シルバーナイト:技量72、修正-85%。命中値=72+(72*-0.85)+20=31
ナルディア:技量103、修正+70%。回避値=103+(103*0.7)+20=195
命中率=32/195*80=12.7%

実際の試験:60回中9回命中、15%。

結果、ほぼ予測通りの結果となった。以前から命中率は同条件下では80%と言われていたが、命中、回避ともに+20の修正が付くことで、極端に技量値に差が有る場合でも、ある程度の命中率を示すようにしているようだ。+20が無い場合の例2だと、命中値11、回避値175で、命中率はわずか5%になってしまう。

スキルの効果
同技量、0%修正時のスキルの効果を計算する。スキルなしなら80%。
技量50同士の場合:攻撃側にスキル 命中率114%、防御側にスキル 56%。
技量100同士の場合:攻撃側にスキル 命中率100%、防御側にスキル 64%。
技量150同士の場合:攻撃側にスキル 命中率94%、防御側にスキル 68%。
当たり前だが、技量値の低いユニットほど恩恵を受ける。また基本技量値に差が有りすぎると、こちらにだけ高い地形修正が入っても効果は薄い。しかし相手に不利な地形修正があればなんとかなるかも。

ページトップへ戻る

ダメージ判定


ソースから導かれるダメージ値は
Attack=(攻撃力+30+random(8))*攻撃値/80
Defence=防御力+30
相手に「強い」属性が有る場合はここでDefence*2、「弱い」の場合はAttack*2。
ダメージ期待値=Attack^0.7*Attack/(Defense+10+random(10))*(20+random(5))/35
ダメージが1以下なら1、999以上なら999。吸収属性があれば、ここでマイナスに反転。

例1:グラディエイターVsバルバッタ
ランダム値の最大と最小の場合を考える。
最大期待値
Attack1=107*75/80=100.3
Defence=95+30=120
最大期待値=100.3^0.7*100.3/(120+10+0)*(20+4)/35=13.3

最小期待値
Attack1=100*75/80=93.8
Defence=95+30=120
最小期待値=93.8^0.7*93.8/(120+10+9)*(20+0)/35=9.3

またランダム値が常に平均値を示したとすれば、
平均期待値
Attack1=103.5*75/80=97
Defence=95+30=120
平均期待値=97^0.7*97/(120+10+4.5)*(20+2)/35=11.1

ダメージ期待値は9.3〜13.3。平均なら11.1。 実測値、9,11,11,10,10,11,10,10,11,11で、平均10.4。

ほぼ数式通りの結果が出た。 もしバルバッタに通常に弱い属性があれば、ダメージの平均期待値は36.2で、倍どころの話ではない。実測でもそうなる。ちなみに魔法や特殊攻撃のダメージ算出はまた別式。

アタックとシールドの効果を計算する。
攻撃力70、攻撃値75、防御力56のグラディエイター同士で殴り合った場合。
通常の予想されるダメージ 14.9
攻撃側にアタック、予想ダメージ23で1.5倍。防御側にシールド、予想ダメージ11.5で0.78倍。

攻撃100、攻撃値80、防御100の仮想ユニットが殴り合った場合。通常のダメージ17.9。アタックがかかっていた場合、25.2で1.4倍。シールドがかかっていれば14.8で、0.83倍。攻撃150、攻撃値80、防御150の仮想ユニットが殴り合った場合。通常のダメージ22.8。アタックがかかっていた場合、29.5で1.3倍。シールドがかかっていれば19.7で、0.86倍。

見ての通り、基本攻撃力が低いユニットでのアタックの効果はめざましいものがある。だが攻撃力の高いユニットでも、相当な効果があるのもわかる。逆にシールドはさほど効果がない。また計算式をみればわかるが、攻撃値が80より高ければよりアタックの効果が出るのも分かるだろう。

ページトップへ戻る

魔法命中判定


魔法自体は絶対命中であるが、魔法による毒、石化などの状態変化は常に受けるわけではない。状態変化の発現は、魔法命中率によって導かれる。
ソース(DamageManage.cpp)から導かれる魔法命中率は、
命中値 
攻撃側魔力
回避値
防御側抵抗+(抵抗*地形修正)+20
魔法命中率=命中/回避*80
ただしソースを見る限りでは、命中判定は100-命中率<random(110)の場合、命中となっている。命中90%の場合、0〜109の乱数が10以上なら命中となる。通常攻撃、特殊技の場合Random(100)で判定しているので魔法攻撃の命中率は9.1%ほど増えていることになる。その分、防御側には+20の修正があるので、殆ど変わりなしかな?

弱い属性がある場合、命中率に関わらず常に命中扱いを受ける。命中した場合に状態変化が起こる。

魔法の命中率が「魔力」と「抵抗」で行われるのは判るが、防御側のみ地形効果も適用されることに注目。また通常攻撃と違い、攻撃側に+20のボーナスが付かない。状態変化を受けたくなければ、レジストを掛けた上で、防御修正の高い所に陣取ると良いということになる。

また吸収、強い属性が有る場合は「通常攻撃」として攻撃判定を受ける。例えばパラライズを受ける際に麻痺に強いがあれば、物理属性の魔法攻撃になるだけであり、麻痺ダメージの吸収はできない。このダメージを減らすには通常に強いや吸収が必要。(この時通常に弱い、があれば毒や麻痺にはかからなくても、倍のダメージを受けるということでもある)

ページトップへ戻る

魔法攻撃ダメージ判定


ソースから導かれるダメージ値は
Attack=((魔力*0.8+Random(8)+60)*(魔法威力+30))/40
Defence=抵抗*0.8+70
この時、相手に弱い属性が有ればAttack*2、強い属性ならばDefence*2。
ただし、MP回復、HP回復の技は常にDefenceは30で判定。
ダメージ期待値=(Attack^0.4)*(Attack/(Defense+random(10))+.6)*(30+random(5))/35
ダメージが1以下なら1に。吸収、および回復系なら±反転。

例:ゴートがバルバッタにシャイニングをかける。ゴートの魔力80、シャイニングの威力20、バルバッタの抵抗90。乱数は平均値とする。
Attack=((80*.8+3.5+60)*(20+30))/40=(127.5*50)/40=159.375
Defence=90*.8+70=142
ダメージ=(159.375^.4)*(159.375/(142+4.5)+.6)*(30+2))/35=7.62*(1.09+.6)*32/35=11.77
えらく複雑に見えるが、結果的には普通の数字が出る。実測値は12,12,11,11,11,11,12,10,11,11で、平均11.2と、式よりは少な目か。

例2。バルバッタが自分にヒールをかける。魔力70、威力50。
Attack=((70*.8+3.5+60)*(50+30))/40=(119.5*80)/40=239
Defece=回復属性なので30固定。
ダメージ期待値=(239^.4)*(239/(30+4.5)+.6)*(30+2)/35=8.94*7.53*32/35=61.55
実測でも57,57,60,64,64とほぼ同じ数字になる。ヒールの場合威力が大きいことと、Defence値が30固定と非常に低いので、ダメージ期待値もかなり大きい数字となった。

(Attack^0.4)の部分はAttackが大きくなってもあまり影響はない、また(30+random(5))/35の部分も乱数で僅かにダメージが小さくなる程度。重要なのはATとDFの格差。特にATを算出する場合の魔法威力の値が重要だろう。

ページトップへ戻る

特殊技の命中、ダメージ判定


特殊技には、ダメージ源となる攻撃属性が攻撃力のもの、魔力のもの、無属性のものの三つがある。同時にダメージを抑える防御属性が防御力抵抗、無しの三つがある。よって9種類にわけることが出来るが、無属性攻撃や、防御属性が無しの必殺技はあまり無いようだ。

攻撃力ソース
/防御ソース ダメージ 命中 状態変化	例

攻撃*防御 攻撃/防御 技量 魔力/抵抗	弓矢などの回避可能な通常特技全般
攻撃*抵抗 攻撃/抵抗 必中 魔力/抵抗	ブレスなど。絶対命中する物理攻撃。
攻撃*無し 攻撃/ゼロ 必中 魔力/抵抗	ダメージ軽減のない必殺技等。

魔力*防御 魔力/防御 技量 魔力/抵抗	雪の結晶など。外れることもある魔法攻撃。
魔力*抵抗 魔力/抵抗 必中 魔力/抵抗	純粋魔法系特技。
魔力*無し 魔力/ゼロ 必中 魔力/抵抗	MP回復など。

無し*防御 ゼロ/防御 技量 魔力/抵抗	銃など。攻撃力に寄らない物理特技
無し*抵抗 ゼロ/抵抗 必中 魔力/抵抗	術者の魔力に寄らない魔法特技
無し*無し ゼロ/ゼロ 必中 魔力/抵抗	一桁の微回復等に。

ゼロはダメージ算出の基本数値がゼロになるだけで、ダメージ自体がゼロになるわけではない。

特殊技は状態変化判定、ダメージ判定の順に行われる。ダメージ判定が外れても、状態変化判定でヒットしていれば、ミスと出ても状態変化だけは食らうことに注意。ダメージ判定は防御属性が防御力で行われるものは、通常攻撃と同じようにお互いの技量を用いた命中判定を行う。当然ミスもある。防御属性が抵抗のもの、無しのものは自動的に命中する。

状態変化判定は、防御属性が防御力のものでも魔法攻撃に依るものと同じ判定を行う。すなわち、命中自体はお互いの技量の値で判定されるか自動命中であっても、状態変化するか否かは攻撃者の魔力と防御側の抵抗の値によって決まる。

ダメージの算出式は以下の通り。
Attack=攻撃属性が攻撃力の場合:攻撃力*0.8
    攻撃属性が魔力の場合:魔力
    攻撃属性が無しの場合:0
Attack=(Attack+random(8)+30)*技威力/100
ここで弱い属性が有る場合、Attackは二倍。
Defence=防御属性が防御力の場合:防御力
    防御属性が抵抗の場合:抵抗
    防御属性が無しの場合:0
Defence=Defence+30
ここで、強い属性があった場合、Defenceは3倍。
ダメージ期待値=Attack^0.7*(Attack/(Defense+10+random(10)+0.5)*(20+random(5))/35
通常攻撃のダメージ算出式と微妙に違う。

実験。ホルスがRムクガイアにラングラントゥー。実測ではダメージは51〜65。randomは平均値とする。
ラングラントゥーは威力90、神聖属性、攻撃力/防御力属性、双方ランクDで、ホルスの攻撃力は130、Rムクガイアの防御力130、神聖に弱い。
Att=((130*.8)+30+3.5)*90/100=123.75
Def=130。弱い属性なのでAtt=att*2=247.5
ダメージ=(247.5^0.7)*(247.5/(160+10+4.5)+0.5)*(20+2)/35=47.37*((247.5/174.5)+0.5)*22/35=57.1
実測通りの値と言って良いだろう。またBasicで簡単なプログラムを組み、乱数を発生させて100回の統計を取ったが最低50、最高67ほどで、これも実測値とほぼ一致する。

実はソースを見るとちょっと信じられないことだが、if (SpecialNo==15 && TNo2==14) Attack/=2;という一文がある。15番目に設定されている特殊技で、14番目に設定されている相手を攻撃した場合、攻撃力は半減という式だが、シナリオによって特殊技もユニットも違うのだから明らかに汎用性に欠ける。デフォに当てはめると光竜剣でRムクガイアに攻撃した場合と思われる。実際に試験した所、攻撃力が半減ということはなかった。ゴートでやってるときにRムクガイアが生まれたら、大人しく殺されてホルスに引き継がせろ、というあとあと氏からの陰謀かも。このソースでは、ソース中にムクガイアの復活、ホルスへの引継の文章が入っているので(既存のシナリオではMasterDataの中の文章が使われる)、おそらくソースが古いもののせいだろう。

ページトップへ戻る

状態変化、および復帰


「強い」および「吸収」の耐性が有る場合は、状態変化を受けることは決してない。また吸収、強い属性が有る場合は「通常攻撃」として攻撃判定を受ける。例えば毒ブレスは毒に強いがあれば、通常攻撃ブレスとしてダメージを受ける。ここでさらに通常に強いがあれば、ダメージを減らすことが可能。

状態変化の復帰確率は、ソース(battle.cpp)によれば、ターン開始時に判定して

  • 麻痺:20%
  • 眠り:33%。眠りは攻撃を受けた場合にも覚醒する確率が33%。
  • 幻想:20%
ページトップへ戻る

経験値の取得


経験値の取得は、ソース(battle.cppおよびDamagemanage.cpp)によれば、

  • 待機時
     取得経験値量=random(5)
  • 魔法、戦闘などを行った場合
     取得経験値量=10+random(5)
  • 敵を殺したとき
     取得経験値量=(敵固有経験値+10)*25/(自固有経験値+20) + 10+random(5)
ここに固有経験値による修正が入る。
実取得経験=取得経験値量*200/(100+固有経験値)
1以下なら1に、100以上なら100に。よって、ランクチェンジはどう頑張っても1回。

例1:ソーサラーでMP回復しまくる。固有経験値はソーサラー:30。
ランダム値は平均の2とする。 取得経験量=10+2
取得経験値=12*200/(100+30)=18.5
最小値は15.4、最大値は21.5。実測値では17.2程度で、いまいち正解でもなかった。待機時の予測値は3、実測値もほぼ同じ。
ドルス、固有経験値357の場合、exp=12*200/(100+357)=5.3。最小4.4、最大6.1。実測値は5.25。固有経験値の多いユニットのほうが、乱数によるぶれは少なくなる。

例2:ソーサラーでバルバッタ(固有経験値500)を殺す。
取得経験値量=(500+10)*25/(30+20)+12=267
固有経験値の修正 実取得経験値=267*200/(100+30)=411
ただし、100以上は100なので、実取得経験は100。

ページトップへ戻る

CPUマスターの雇用に対するゲームレベルの影響


ゲームレベルが上がると、敵マスターの戦力の補充が実際の軍資金を越えてなされているのに気が付くはず。あの異常とも思える戦力補充を見れば、実際の雇用費より相当安く雇用しているのだろうと予想は付く。実際にソースを見ると、実にレベル5では1/4の費用で雇用されていることが分かった。

ソース、SCM.CPPより
int RateData[]={50,60,100,180,270,400};
int Rate=RateData[Game->Data.Level];
int Ley=Kuni->St[Kuni->No].Ley*Rate/100;
ゲームレベルごとに50〜400という数値が割り当てられている。レベルは1〜5までなので、50〜270か、60〜400の部分がつかわれてるはず。デフォルトのレベルが2なので、LV2で100%になるとすれば、60〜400の部分と思われる。変数的にも配列変数は0からが普通だしな。

んで雇用の前に一時的に軍資金を増減させている、。レベル1だと元の60%に減少、レベル2なら変わらず、レベル3で1.8倍、レベル4で2.7倍、レベル5なら実に4倍になる。そして雇用。ここのソースが複雑なのだが、とりあえず周辺国の戦力値以上になるように雇用してるようだ。

で、実際に雇用して、この増額された軍資金から雇用費を払ったあとに
Kuni->St[Kuni->No].Ley=(short)(Ley*100/Rate);
今度は逆に計算することで、軍資金を元の値に戻してる。

この処理は、高レベルではCPUマスターは実際より安く雇用している、だけに止まらず、軍資金を越える雇用費のユニットも雇えることを意味している。例えばレベル5の場合、
CPU側は実際の軍資金の4倍までの雇用費のユニットを雇える。かつ、支払うコストは1/4で済む。
ということになる。実際ゲームレベル5でベリアル(雇用費300)を雇用できるようにしてみたところ、明らかに軍資金が足りてない(100程度)にもかかわらずベリアルを雇用した。レベル1では逆に軍資金の60%までのユニットしか雇用しないわけだが、あまり使われるレベルでも無いので、特に考慮する必要もないか。

ソースの通りならば、スクリプトでCPU側の軍資金の最大値を制限することでゲームレベルにより雇用するユニットを変えることが出来ると思われる。例えばCPUマスターの召集には下位から最上位まで最初から指定しておいて、軍資金の最大値を100までにすれば、レベル5なら雇用費400の最上級ユニットを雇用する。しかしレベル3なら雇用費180までのユニットしか雇用しない、とかね。雇用されたユニットに、同能力の別ユニットを安めで雇用できるようにしておけば量産もオーケーかな?

ページトップへ戻る

CPUマスターの雇用と攻撃型、魔法型ユニット


CPUの雇用ルーチンは不可解な部分も多かったのだが、解析できた範囲で述べてみる。data.cpp及びscm.cppより。

まずCPUはそのエリアのユニットの特徴を計算して、攻撃型か魔法型、どちらの特徴が強いかを調べる。攻撃型傾向ならば魔法型ユニットを雇用しようとし、魔法型傾向ならば攻撃型ユニットを優先雇用することでバランスよい戦力を目指す。
攻撃傾向=全ユニットのHP+攻撃力
魔法傾向=全ユニットのMP*2 + 魔力*3/2
その上で
攻撃傾向*5 < 魔法傾向*3 ならば、魔法戦力が多すぎるので、攻撃職を優先する
魔法傾向*5 < 攻撃傾向*3 ならば、攻撃戦力が多すぎるので、魔法職を優先する
どちらにも当てはまらない場合、特に優先する雇用は無しとなる。

例としてHP100、MP100、攻撃100、魔力100のユニット20体なら、
攻撃傾向=(100+100)*20=4000
魔法傾向=(200+150)*20=7000
攻撃傾向 4000*5=20000 <  魔法傾向 7000*3=21000 が成立するので、魔法職が多い=攻撃職を求める
この式に従うと多くのシナリオではMPが高い上位職が増える後半では魔法傾向が高めに出るはずで、雇用は攻撃職を求めることが多くなりそうだ。

CPUが雇用に使う金額は、隣接敵エリアの有無で判断される。
隣接敵エリアが無い場合、Leyが20以下 または 20%の確率で雇用しない。雇用上限はLeyの20%。
隣接敵エリアがある場合、Leyが40以下 または 10%の確率で雇用しない。雇用上限はLeyの50%。
ここでいうLeyは前述のゲームレベル補正で増大した軍資金を差す。(この項目は曖昧である)

CPUの雇用対象となるのは、
まず雇用しようとするユニットの持つ雇用8種。モンスターユニットはユニット雇用しない。
ここで エリア雇用6種が、それぞれ確率50%で対象に追加される。(エリア雇用は最大6種までか?)
さらに 確率 20%でマスター雇用8種が追加される。
ユニット雇用8種+それぞれ50%の確率でエリア雇用最大6種+20%の確率でマスター雇用8種。

同一ターン内では、この雇用対象は固定される。エリア雇用が時々偏るのは、確率50%で、雇用対象に加えるかどうかのせいらしい。CPUのこの雇用対象の中でもっともコストの高い者を雇用する。ここでいうコストは費用の数値に、さらに優先などの傾向で修正したものである。
コスト=費用 

CPUは同族ユニットの雇用を優先する。同族以外のユニットへの優先度を下げるという処理が行われている。
雇用しようとするユニットが異種族の場合、
同族ユニットが10%以下なら、コスト=コスト/5 
同族ユニットが30%以下なら、コスト=コスト/3 
同族ユニットがそれ以上でも コスト=コスト/2 
コストが低くなると言うことは、優先度が下がるということである。

まず雇用しようとするユニットが攻撃型か魔法型かを分類する。
攻撃傾向=HP+攻撃 
魔法傾向=MP+魔力 
高い方がそのユニットの職傾向となる。同じ値なら攻撃職。エリアで求める傾向とやや変数の使い方が異なる点に注意。
次にエリアの傾向による優先度の修正が入る。
攻撃職優先 の場合 攻撃職の場合 コスト=コスト*2
          魔法職の場合 コスト=コスト/2
魔法職優先 の場合 攻撃職の場合 コスト=コスト/2
          魔法職の場合 コスト=コスト*2
優先なし の場合 コストに修正はなし
すなわちエリア傾向に則したユニットは優先度が高く、その逆なら低くなる。

雇用対象になってるユニット全てについて、これだけの処理を加えた上で、最も高いコストの者を雇用する。同一コストのユニットが有った場合、後から処理したユニットが50%の確率で候補ユニットに置き換わる。(同コストのユニットがA、B、C、Dと並んだ場合、Aが12.5%、Bが12.5%、Cが25%、Dが50%となる。)雇用時に払う費用は、修正後のコストの値ではなく、初期費用の値である。ユニットを一体雇用する度に、エリアの傾向などは算出し直す。

まとめると以下の通り

  • 雇用対象はユニット雇用、エリア雇用(それぞれ確率50%)、マスター雇用(確率20%)
  • CPUは攻撃と魔法のバランスの取れた雇用を目指す。
  • エリアごとに攻撃傾向か魔法傾向を調べる。雇用対象のユニットごとに攻撃職か魔法職か調べる。
  • 傾向に則したユニットはコスト*2と雇用されやすい。反したユニットはコスト/2と雇用されにくい。
  • CPUは同族雇用を優先する。
  • 同族以外のユニットはコスト/2、同族ユニットが30%以下の場合コストが1/3〜1/5になる。
  • 修正後のコストの値の最も高い者を雇用する。雇用費は初期雇用の値である。

雇用の際には経験値や魔法レベルの値は一切考慮されない。ユニット傾向は単純にHPやMPの値で算出するため、特技のためにMPを高く設定したユニットは魔法職と見なされる場合がある。エリア傾向を算出する際も同じ事が言える。

またゲームスタート時の自動初期配置はこのルールで雇用されず、別の方法で配置される。後述。

ページトップへ戻る

初期配置


初期配置のためには、まずエリア毎に雇用費が貰える。data.cppより。
プレイヤーのエリア 320 + Rnd(80) すなわち320〜399
敵マスターのエリア 350 + Rnd(50) すなわち350〜399
本拠地 +150
隣接エリアが全て味方のエリア -250
まとめると、本拠地 約510、それ以外 約360、安全なエリア 約110 と言った程度。中立エリアはゲームレベルとエリアごとの中立戦力補正が入るため、不明

次にこの雇用費でユニットを雇用する。初期配置では雇用するユニットはマスターの持っている雇用のみ。そして長らくどういう順番で雇用するのか不明だったが、ようやく解析した。非常に分かりにくいので箇条書きで書く。

  • まずマスターの持つ雇用最大8種を、費用順に並べ直す。使うのは費用のみ、経験値は見ない。
  • 費用順に、A、B、C・・とする。費用が同じ場合はエディタでのキャラ順が早いほうが上。
  • 第一雇用フェイズではABC..の優先順で雇用。
  • 第二雇用フェイズではBCD..の優先順で雇用。
  • 第三雇用フェイズではCDE..の優先順で雇用。
  • 以後、第一フェイズに戻る。
  • すなわち、A、B、C、A、B、C..と雇用費がある限り三番目までのユニットを優先的に雇用する。
  • ただし、費用が残り雇用費の66%以上の時は雇用しない。次の雇用対象を雇用。
  • これを19ユニットになるまで繰り返す。20ユニット目は雇用しないので必ず一人分空く。
非常に分かりにくいのだが、費用上位の3種類のユニットを優先的に雇用。残り雇用費が少なくなってきたらあまり高いユニットを雇用せずに、安いユニットを雇用する。まとめると
  • 初期配置は費用の高い順に上位3種までを優先して雇う。
  • 残り雇用費の66%を越える高いユニットは雇用しない。
マスターに雇用を持たせる場合、上位三種以外は金がなくなってからではないと雇用しない。三番目と同じ費用のユニットを入れても、優先されるのはエディタで早い順。この時4番目のユニットはどんな場合でも雇用されないことに注意。なぜなら同じ費用なら常に3番目が優先されるから。このことを踏まえて費用を設定しておかないと、なかなか思うように雇用しないということになる。

これをデフォシナのゴートに当てはめると、初期雇用費500、雇用はグラディエーター:65、ソーサラー:30、プリースト:25の順。グラ、ソサ、プリ、グラ、ソサ、プリ、グラ、ソサ、プリ、グラ、ソサ、プリと雇った時点で、残り費用55。グラ優先フェイズだがグラは金がない、次に優先されるのはソサ。ソサの30 < 36 (55*.66) なのでソサ雇用。残り雇用費25。ソサ優先フェイズだが ソサの 30 > 16.5 (25*.66)、プリの25 > 16.5 共に予算オーバー。プリの次に優先されるファイターも費用20 でだめ。なので費用12のマジシャンを雇用。残り雇用費は13。66%は8.5なので、かろうじてソルジャー雇って終わり。

すると、グラ*4、ソサ*5、プリ*4、マジ、ソルという雇用になる。初期雇用費には幅があるので、ソサ*4にファイターとかいう場合もある。しかしファイターと同じ費用のアーチャーは初期雇用されることは決して無い。


ページトップへ戻る

素早さと、ユニットの行動順序、行動回数


ファーレントゥーガにおいて、素早さはHPや攻撃、防御以上に重要な数値だ。より速く行動し、より速く攻撃し、より速く回復する。相手の二倍行動できるなら、それ以外の数値が1/2でも、互角に戦えるといって良い(反撃を食らう戦士系は例外だが・・)。経験則として、素早さ60あれば一ターンにほぼ一回行動できることは知られていたが、ソースの該当部分を解析してより正確な行動までの演算ルーチンを見てみた。

ソース、Battle.cppより該当箇所を見てみるとターンごとに、5回のループを行い、その途中で素早さの数値を行動値に足していき、行動値が一定以上になればユニットに行動させていることがわかった。ざっと流れをまとめると以下の通り。

  • 全ユニットを対象に行動値が500以上なら500を引いて、ユニットの行動に移る。
  • ループの数値を増やし、一定以上ならばループを終わらせターンエンド。
  • 全ユニットを対象に行動値に素早さ*0.8+50+Randum(10)を足す。
  • ループの頭に。

小難しいが、分かりやすく書くと一回のターンで6回行動する機会、5回行動値を増やす機会がある。行動値が500以上あれば行動できる。行動したかどうかと関係なく、行動値が素早さ*0.8+50+乱数分(0〜9)増える。素早さ60あれば、48+50+乱数でだいたい103増える計算になる。すなわち5回行動値を増やすと、ほぼ500に達する。素早さ60で一ターンに一回行動という経験則は確かに正しいものだったと言えるだろう。

行動の順番は、攻撃側が戦争時に「ユニットを連れて行った順」防御側は戦闘に参加できるユニットを選ぶことは出来ないので普通に並んでいる「戦力順」ということになる。配置した順、ではないので注意。攻撃側、攻撃側の呼んだエレメント最大5体、防御側、防御側のエレメント、の順で行動を行う。行動を行う、というより行動できるかどうかの判定を行う、が正しいか。

さらに最初のターンだけ6回行動値を増やせる。これはおそらく最初のターンぐらい足が遅めのユニットでも行動が回ってくるように、という救済措置と思われる。(またはプログラムのミスかも)

また最初のターンだけ6回行動値を増やせので、素早さ145あれば確実に二回行動出来る((145*.8+50)*6=996)。また素早さ188あれば、5回の増加で1000増えるので((188*0.8+50)*5=1002)、ほとんどのターンで2回行動できる。250あれば確実に二回、時に3回行動が可能と言える。

行動値の増加は素早さの8割に、50という固定値、些少な乱数が加わるため、素早さが極めて低いユニットにもある程度行動の機会が与えられることがわかる。例えば素早さゼロのユニットでも2ターンに一度(0+50*10=500)は確実に動ける。乱数のおかげで、同じ素早さのユニットでも順番に差が出ることがある。(片方がわずかに行動値500に届かなかった場合など)

単純に素早さ順の行動ではなく、微妙な揺らぎが出ることで戦術の偶然性を増していて、非常に面白い処理だと思う。またユニットを「連れて行く順」も非常に大事。最初の移動と強化の時なんかはね。

素早さと20ターンでの行動回数及び一ターン辺りの行動回数概算値(100回ループでの平均値)

素早さ 総回数一ターン辺り 素早さ 総回数一ターン辺り 素早さ 総回数一ターン辺り 素早さ 総回数一ターン辺り
011.10.56 10027.21.36 20043.42.17 30059.62.98
511.90.60 10528.11.40 20544.22.21 30560.43.02
1012.70.64 11028.81.44 21045.02.25 31061.23.06
1513.60.68 11529.71.48 21545.82.29 315623.1
2014.30.72 12030.51.52 22046.72.33 32062.83.14
2515.20.76 12531.31.56 22547.52.37 32563.63.18
3015.90.80 13032.11.60 23048.32.41 33064.43.22
3516.80.84 13532.91.64 23549.12.45 33565.23.26
4017.50.88 14033.71.68 24049.92.50
4518.40.92 14534.51.72 24550.72.54
5019.20.96 15035.31.76 25051.52.58
55201.00 15536.21.80 25552.32.62
6020.81.04 16036.91.85 26053.12.66
6521.61.08 16537.81.89 26553.92.70
7022.41.12 17038.61.93 27054.72.74
7523.21.16 17539.41.97 27555.62.78
8024.11.20 18040.12.01 28056.42.82
8524.81.24 18541.12.05 28557.22.86
9025.61.28 19041.72.09 29058.02.90
9526.51.32 19542.72.13 29558.82.94

正確な計測の結果、速度ゼロでも11回行動、速度55でちょうど20回行動、速度180で毎ターンほぼ確実に二回行動と計測された。

例えば、20ターンのスパンで見たときスピードの魔法で素早さ60のユニットの素早さが20増えるなら、20.8回から24.1回と約3回行動が増える。自前でスピードしたならスピード一回分の行動を引いて、2回分お得!

デフレシナリオで、素早さ40でスピードの増加値10の場合、1.7回しか増加せず、自前でスピードをすると0.7回しか増えない。20ターンで0.7回なら掛けないほうがマシだろう。

ページトップへ戻る

mirror氏によるソース解析


FTEの作者、mirror氏からソースコードを解析したものを頂いた。ダメージ算出などの特定の部分だけでなく、ソース全体に対するもの。Force値の計算や種族相性による雇用確率などは参考になる。9KBほどのテキストファイルだが、ここに載せると長いので読みたい方はご自由にダウンロードしていただきたい。

srcResult.txt

この解析の中で、ユーザーにも有用と思われる情報。

  • 訓練によるExpの増加率 :8 - ランク + random(12 - Lv * 2)
  • 人材捜索の発生率 1 / 12 で、この確率をクリアしたら人材全てからランダムで一人を選択。
     この選択した人材が放浪していたら雇用チャンスとなる。これをエリアの人数分繰り返す。つまり、人材捜索する人数も重要だが放浪している人材数 / 全人材の数 もとても重要になる。
  • 街・道・城壁 開発や建設に携わるキャラ一人につき街 24 道路 40 城壁 96 を追加。
    100超えで1アップ。余りは保留となる。さらに城壁は自動で1ターンに8 * 人数分増える。
    20人で開発を行う場合、街は480/100で、一ターンだけなら4アップ。10ターンなら4800/100で48アップする。同様に20人で開発なら道路は8、城壁は19.2増える。
  • 種族との相性:雇用できる確率 a * 25 / 75。aは 0~3 の値。
    人間なら同種族の人間は100%、相性の近いアイスマン、エルフは66.6..%、ゴブリン、ドワーフは33.3..%、それ以外の種族は雇用不可能、ということになる。

  • ページトップへ戻る