Skyrim Simple Slowdown

Skyrim の vanilla leveling だと、特に早い段階は level が上がりやすい。

Oblivion の時と同様にこの level up の速度を抑制する mods がいくつか出ている。これまで出ていたものは、Level Up のための XP を変更するもので、これを入れると leveling pace はゆっくりになるけれど、Game 内で全ての Skill を 100 にした時の max level が 81 から低下することになる。

これは、今まで出ていた mods は GMST の

  • fXPLevelUpBase
  • fXPLevelUpMult

の2つの値を変更しているからだ。Skyrim の leveling は基本的に

( (現在の level) * fXPLevelUpMult ) + fXPLevelUpBase

という式で求められる。したがって Level 1 から Level 2 になるためには、

(1 * fXPLevelUpMult) + fXPLevelUpBase

となり、vanilla での値 – fXPLevelUpMult =25 / fXPLevelUpBase を適用すると、Level 2 になるためには 100XP が必要ということになる。

XP は基本的に Skill rank が上昇するごとに上昇した Skill rank が XP として獲得、と言う仕組みだ。ということで Level 2 になるためには 3 つの Skill が 15 -> 17 になって、他に1つの Skill が 16 になる。あるいは 7 つの Skill が 15 -> 16 になるだけで Level が上がることになる。

この 2 つの GMST を変更すれば確かに leveling pace は遅くなるけれど、level の上限も減るので、最終的に獲得できる perk 数も減ってしまうのが難点だ。後は level が上がるのは遅くなるけれど、level scaling する敵が PC が level 10 でも skill rank 的に見れば 14 level 相当という感じになるので perk が少ないことを除けば、若干 PC 側に有利になる。この Level XP に関しては curve して上昇していくので中盤はまだいいけれど、後半になるとこの差がさらに広がって若干難易度は低下することになるだろう。

この 2 つの GMST の他にもう一つ leveling pace を変更する GMST record があって、それは fSkillUseCurve という record だ。これは直接 Level XP には影響を及ぼさないけれど、Skill rank 上昇のための Skill XP に影響を及ぼす。

この Skill XP は若干面倒くさい、というか power function になっているので rank 100 になるまでの Skill XP をしっかりと計算してから変えないと後半かなり凄まじいことになる。

ちなみに Skill XP の計算方法は

SkillModifier x (現在のskill rank ^ fSkillUseCurve) + X

となる。

fSkillModifier は GMST record に存在しているのは見つけられているんだけれど、それぞれの Skill 毎の修正値 ( SkillModifier ) と、一部の Skill では一定の定数が最後に足されている (実際は引かれているようにしか見えないけれど negative な constant なんだろう) けれど、この定数にあたるものについてはどこで設定されているのか現時点では不明だ。

ただ、それでも fSkillUseCurve の値が power function で作用するので、この数値が Skill rank の上昇しやすさに非常に大きな影響を及ぼすことは間違いないだろう。

ということで、この値を vanilla の 1.95 から変更して Skill rank の上昇速度を遅くする mod が release されていた。

- Skyrim Simple Slowdown - という mod で、Level の上限などを変えずに、Skill の上昇速度を抑制することで leveling pace を変えたい、という場合にはぴったりだろう。

私自身はこれを変更すると同時に、Sneak、Lockpicking、Pickpocket、そして Enchanting と Smithing の modifier がかなり小さな値になっているように見えるのを変更して、これらの skill の上昇速度をさらに抑制したい、というところ。

ただ、この Skill 毎の Skill XP に関わる修正値がどこにあるのかまだ探り当てていない…

Realistic Lighting / No Tint and Desaturation

Oblivion では Real Light あるいは Let There Be Darkness などを install して、暗いところは暗く、という play をしていたので、Skyrim での大きな不満は「明るすぎる」というところだったりしている。

色々その辺を改善する MOD は早い時期から色々出ているけれど、大きく 3 つの種類に分けられる。最初の一つは ENB series あるいは FXAA Injector のように post-process で変更するもの。こちらは、設定を色々変えれば比較的好みの色合いにすることが出来るけれど、あくまでも post-process なので game には一切の影響を与えない。

従って、暗くなっているように見えても、実は post-process する前は明るかったりすると、player からは暗いので影に隠れているつもりでも NPC からは丸見え、という状況になったりする。

もう一つは従来の MOD と同じように LIGH (Light) の配置を変更するもの。Oblivion の Real Light なんかは各 cell から fake light を取り除くことで洞窟の中を暗くする、という手段をとっていた。

ただし、現時点では Skyrim の MOD でこれを実現しているのは、True Darker Dungeons だけのはずだけど、今の段階では全く使えない状態だ。もちろん、これを install すれば、恐らく一番理想的な fake light の無い環境が出来上がる。

ところが、現状では cell header を書き換えてしまうと、Radient Quest でその cell を対象にした quests が正常に実行/完了出来ない、cell 内の script が動作しないなどの問題の方が大きいので、やりたいと思う quests は全てやって、もうただ散策したい、という状況でもない限り導入するのはかなり危険だ。

そして 3 つ目は、Fallout 3 から追加された IMAD (Image Space Modifier), IMGS (Image Space), LGTM (Lighting Template) を変更して、fake light はそのままに全体的な image space を変更することで見え方を変えるものだ。

これは、NPC/PC 双方に適用されるので、Sneak などの判定の際にも Player から見て暗いところへ行けば、NPC からもその辺は暗がりで良く見えない、ということになる。

この手法を使っているのが、

の 2 つだ。他にもあるかもしれないけれど、特に今のところは確認していない。

まず No Tint and Desaturation から見ると、

屋外は全体的に Vanilla でかかっていた白のかかった IMGS が変更されていて、すこし saturate な感じになっている。

屋内は、屋内用の option も入れてみたけれどあまり暗くはならなかった。ただしこちらも Vanilla と比較すると vivid な感じだ。

次に Realisitc Lighting でほぼ同じ場所を見ると、

こちらは Vanilla と比較して色合いが変わっているわけではないけれど、sun colour あるいは light が若干より強力になっていて、同時に ambient light が弱くなることで室内、あるいは夜間などはより暗くなる、という感じだ。

純粋にどちらか、というのは多分好みの問題だろう。ENB series や、FXAA Injector で良くあげられているような vivid/bright な色合いが好みな場合は No Tint and Desaturation を使うと良いかもしれない。この手の感じの色彩の調整は基本的には American 好み、というところだ。

これに対して Realistic Lighting の方は落ち着いた感じの色合いなので、American 的な配色が余り好きではないならこちらを選んだ方がいいだろう。全体的に muted colour と表現してもいいけれど、これは Euro 市場向けというところだろうか。一般的に American はこういう感じの色合いだと too washed と表現する。個人的にはあまり vivid では無い方が好きだけれど、市場によって結構色合いの好みに差が出ちゃうのは中々不思議なところだ。

 

TESV Acceleration Layer – comparison

TESV Acceleration Layer を昨日手元で自分用に修正したあと、Skyrim Nexus にも修正版が upload されていたので昨日の夜は TESV Acceleration Layer を入れて問題の起きそうな場所を回ってみたり、radient quests を受けてみたりした。

当初の TESV Acceleration Layer だと、落石の trap を発動させても降ってこなかったりとか、分かりやすい問題が出ていたけれど、修正後は特に TESVAL のせいだ、と言い切れるような単純な問題には遭遇していない。ただし、code optimization を行うものなので、問題が全くないと断言することもできないところか。

対応としては save をこまめにとって、何か script が進行しない場面に遭遇したら TESVAL を外してやり直すというところだろう。

後は分かりやすいところで performance の比較。この位置がかなり FPS が低下するけれど、今日比較したところでは、

  • TESVAL 無し – 30 FPS
  • TESVAL 有り – 38 – 39 FPS

となっていた。この場面だけに限って言えば 30% 程度の performance improvement というところだろうか。設定は default の Ultra Preset で、shadow resolution を 8192、それに uGridsToLoad を 7 にして関連する設定を調節したくらいだ。

ただし、TESVAL は全体的な FPS を向上させるための物では無いので、適切な設定で game を起動していればあまり performance の違いを実感しないことの方が多いかもしれない。

例えば、昨日問題があるとして修正された test_bit_30 という function では TESVAL を使うと 2 op code となり、TESV.exe 本来の処理だと 4 op code となる。従って TESVAL を使うと、TESVAL で inject された functions の処理時間がそれぞれ few CPU cycle ずつ節約できると言う仕組みだ。

それぞれの場面で見れば小さな節約だけど、全体ではかなり大きな節約となって、結果として CPU が仕事をする時間が減ることになる (= 処理の高速化)。

この結果として、GPU の待ち時間が減って、結果的に FPS が向上するという仕組みになる。

なので、元々 CPU よりも GPU の方が bottleneck となっていた system では、特定の場所を除いては performance の向上を目にすることは殆ど無いだろう。あるいは CPU が bottleneck となっていたけれど GPU もそれほど能力が高くない場合、設定が高すぎたり、変に GPU の overclock をしていたりすると、結果として GPU がより忙しくなって GPU の driver が応答しなくなってしまう、などの問題が表面化することもありえるかもしれない。

TESV Acceleration Layer – cont’d

昨日見つけた TESV Acceleration Layer を入れて play してみたところ、確かに若干 performance が向上したかな、と言う感じだ。Rendering performance そのものには影響を及ぼさないけれど、TESV.exe 本体の code execution はかなり smooth になっている感じ。後は hook しながら見ていると大量のただ return 0 するだけの function calls が減っているので execution speed に関しては確かに向上していると言えるだろう。

ただ、どうも cell header を書き換えてしまったときの様な script が正常に実行されない系統の問題が目に付きやすくなった感じ。

Script が正常に実行されない、あるいは delay する問題というのは 1.3.7 からあったんだけど、この plugin を使うとより目に付く感じだ。

Plugin が行っているのは、build/compile 時に compiler に /O2 (optimize) の flag を渡して生成されるであろう “最適化” されたに違いない code と実際の memory 上に展開された code をすげ替える、というそれなりに単純な動作なのでやはり Engine 自体が compile-time optimization を実施すると挙動がおかしくなる問題があるんだろうな、と言うところだ。

恐らく最適化したときの挙動が unexpected だったので Bethesda は最適化を行わない build を release しているのだろう… 時間と労力をかけて調べれば突き止められる問題だけれど、全ての compile 済み code の white-box test を行って検証するのは、どれくらい時間がかかるか気が遠くなるような話だ。

というわけで、forum の現行 thread を見に行くと、同じような report が複数上がっている。一番再現性が高いのは、

  • 新規に game を開始
  • Hadvor か Ralof か、どちらに着いていくかの分岐で Ralof に着いて Keep に

後は装備をして、Imperial Soldier と Captain がやってくるところまで進むと、Ralof と Imperials と両者開いた gate を挟んで睨み合い状態になる。

本来ならここで Ralof が身を隠して、Imperials が Gate を開けたところで襲い掛かるという進行なんだけれど、Ralof はただ立ったまま、Imperials も Gate を開けてただ立ったままの状態になる。ここで、player が Imperials に近づくと Ralof が動き出して Imperials に襲い掛かるけれど Imperials は反撃せずにただ殺されると言う状況に。

こういう微妙な script の実行漏れ、あるいは遅延的な状況は 1.3.7 以降たまに目にしてがっくりするんだけれど、この plugin を利用した場合、この場面では常に 100% 再現可能だ。ちなみに plugin を削除すると何の問題も起きない。(Plugins folder の中で rename しても SKSE はそこに存在する DLL はどんなファイル名であろうと load するので、削除か、全く関係ないところに移動する必要がある)

というわけで、今のところそれほど performance 的には困っているわけではないので当分使わないことにしよう、というところ。

P.S.

Helgen での新規 game の問題は test_bit_30 に対する replace が問題の直接の原因のようだ。基本的には code.inc からこれを取り除いて table.inc からの参照を削除、その上で compile しなおしてみたところ正常に進行した。

ただ、他の test_bit_xx 関連の部分も微妙に replace が必要かどうか判断がつかない部分があるので、時間をかけて調べないと fix は難しい感じ :(

P.P.S.

Original author によれば setz と setnz が間違えている、と言うことなので、Pathes.replace.test_bit_30 を以下のとおり修正して compile しなおせば問題なく使える。

; v1.3.10.0: $0051E340
@@: Patches.replace.test_bit_30:
test dword [ecx+152], $20000000
 setz al
retn
.size = $ – @b

setz (set byte if zero) / setnz (set byte if not zero) を間違えると (多分 typo じゃないだろうか) 本来 1 を返すべきところで 0 を返してしまうことになる。

Fixed version available on Skyrim Nexus

 

TESV Acceleration Layer

Bethesda の forum を眺めていたら、”TESV AccelerationLayer” という title が目に付いてなんだろうと思って読んでみた。

簡単に言うと build/compile 時に code optimization がほとんど行われていないものに memory 上で patch を適用して最適化する、という plugin だ。当初は d8input.dll の置き換えとして release されたけれど、色々あって SKSE plugin として release されなおした。

確かに process hook して memory debug していたり、EXE file を disassemble して functions を探していたりすると最適化されてはいない、というのは気になっていたけれど、実際それが大きな performance hit になっているとは私自身はあまり考えていなかった。

で、実際に forum に寄せられている report によれば Markarth の極端に FPS が落ち込む辺りで 20% – 30% 程度の FPS 向上が報告されていてびっくりというところだ。

後は単純な最適化だけではなくて、floating point 周りの x87(!) code を SSE code に置き換えていたりするので、FPU 関連の処理はかなりの performance up が期待できるのではないかと思う。

Oblivion の EXE は実はそれなりに compile 時の最適化が適用されているように見えるので、多分 Fallout – Fallout NV そして Skyrim へと engine を改良していく過程で compiler の bug に遭遇して最適化を外すと動作するという状態になったのかなというところだ。