Homeworld Remastered Collection

Homeworld Remastered Collection

Not enough ratings
日本人MOD製作者向けガイド⑤
By dengun
HWRMの日本人MOD製作者向けのガイドとなります。
ワークショップで公開中のA-test Template MODを利用していきます。
⑤ではAI関係と応用方法についてです。
   
Award
Favorite
Favorited
Unfavorite
AIフォルダ内のファイルについて
今回はAI関係について分かっている限りをざっくり説明していきます。
現在のアップデート状況ではAIフォルダの中にdefaultフォルダが存在します。
このdefaultフォルダの中にあるのがHWRMのCPUの頭脳となる基本ファイルです。
(注、A-testMODではAI関係のファイルにかなり手を加えています。
 通常の状態と違うことを覚えて置いてください。)


順に説明していきます。

classdef.lua
ユニットの分類登録ファイルです。
それぞれの役割に応じたユニットを登録します。
登録されたユニットを判断材料の基本としてAIが生産と運用を行っていきます。
現在A-testユニットはCPU設定しても活動しませんが、
それはここに未登録状態だからです。

cpubuild.lua
ここでは生産関係を調整しているファイルです。
classdef.luaなどで登録されたユニットを決められた分量で生産したり、
特別なユニットを独立して生産したりする指令を出してると思われます(スカウトなど)
このファイルの中身は他のファイルとリンクしてる部分が多く、
中身を弄ったり、リンク先のファイルを弄ったりすると、
すぐにエラーを吐く厄介なファイルでもあります。
リンク先は
scripts/races/各レース/scripts/ai_build.lua
leveldata/multiplayer/lib/いくつかのファイルなどなど

cpubuildsubsystem.lua
名前の通りサブシステム関係です。
基礎的な調整ファイルだと思われますが詳細不明。
cpubuild.luaと同じく、ファイルとリンクしてる部分があるようです。
scripts/races/各レース/scripts/ai_subsystems.lua
残念ながら自分はCPUによるサブシステムの構築に成功していません。
エラーを出さない為に空欄で対処している状況です。

cpumilitary.lua
軍事ユニットの編成に関すると思われるファイル
ユニットにはshipファイルの中で、Valueという形で数字が設定されています。
おそらく、その数字を利用してると思われますが詳細不明。
一応、コード間に解説文があるのでそれを読み解けば詳細がわかるかもしれません。

cpuresearch.lua
リサーチに関する基本ファイル。
リンク先のファイルを統括しているだけのようです。
scripts/races/各レース/scripts/ai_upgrades.lua
↑CPUによるリサーチの研究制御ファイルです。
LPF、DIOに実装しています。
リサーチのトリガーとなるのはサブシステムの「Research」モジュールかもしれない?
scripts/races/各レース/scripts/def_research.lua
↑リサーチのメニューへの実装を管理してるファイル。
LPF、DIOに実装しています。
プレイヤーが追加する物とは別にAI限定のリサーチも用意されています。

--AI behaviourなどなど
これらは別のAIファイル、及びルールと密接に関わっています。
削除すると、AI系のエラーを発生させるので注意。

cpuresource.lua
資源採掘に関する基本ファイル。
特に触れる部分は無いと思います。

default.lua
AIの総合ファイルのようです。
詳細不明。
色々リンクが繋がってるようなので何かしらのスイッチがあるかもですが、
現状で触れる部分はありません。

hw1cpuplayerlayer.lua
HW1勢力用のCPUファイル。
HW2系の勢力とは色々と違う部分があるので、
そのすり合わせをしているファイルだと思われます。
これも現状で触れる部分はありません。

A-test勢力をAIに登録してみる
さて上でも触れましたが、
現在A-test勢力はAIに未登録状態なので稼動しません。
classdef.lua
を編集してみましょう。
A-test用のユニットを指定された場所に挿入してください。
ユニットの登録が完了してAIが動作するようになります。
現在、ユニットの総数が足りなくて重複させますが、とりあえずは良いです。
aitrace("CPU: CLASSDEF LOADED") squadclass = {} squadclass[eMotherShip] = { AAA_MOTHERSHIP, } squadclass[eCollector] = { AAA_RESOURCECOLLECTOR, } squadclass[eScout] = { AAA_SCOUT, AAA_PROBE, } squadclass[eRefinery] = { AAA_RESOURCECONTROLLER, } squadclass[eBuilder] = { AAA_MOTHERSHIP, AAA_CARRIER, AAA_SHIPYARD, } squadclass[eDropOff] = { AAA_MOTHERSHIP, AAA_CARRIER, AAA_SHIPYARD, AAA_RESOURCECONTROLLER, } squadclass[eSalvageDropOff] = { AAA_MOTHERSHIP, AAA_CARRIER, AAA_SHIPYARD, } squadclass[eFighter] = { AAA_INTERCEPTOR, AAA_ATTACKBOMBER, } squadclass[eCorvette] = { AAA_INTERCEPTOR, AAA_ATTACKBOMBER, AAA_DESTROYER, } squadclass[eFrigate] = { AAA_DESTROYER, } squadclass[eCapture] = { } squadclass[eShield] = { } squadclass[ePlatform] = { } squadclass[eAntiFighter] = { AAA_INTERCEPTOR, } squadclass[eAntiCorvette] = { AAA_INTERCEPTOR, } squadclass[eAntiFrigate] = { AAA_ATTACKBOMBER, AAA_DESTROYER, AAA_BATTLECRUISER, } squadclass[eCapital] = { AAA_DESTROYER, AAA_BATTLECRUISER, } squadclass[eNonThreat] = { AAA_RESOURCECOLLECTOR, AAA_RESOURCECONTROLLER, AAA_MOTHERSHIP, AAA_CARRIER, AAA_SHIPYARD, AAA_SCOUT, AAA_PROBE, } squadclass[eHyperspaceGate] = { } squadclass[eSubSystemAttackers] = { AAA_ATTACKBOMBER, } squadclass[eNonCriticalSubSys] = { } squadclass[eGoodRepairAttackers] = { AAA_INTERCEPTOR, AAA_DESTROYER, AAA_BATTLECRUISER, } eUselessShips = eMaxCount eBattleCruiser = eMaxCount + 1 sg_maxClasses = eBattleCruiser+1 squadclass[ eUselessShips ] = { squadclass[eBattleCruiser] = { AAA_BATTLECRUISER, } function FastAddToClass( tbl, classid ) for a,b in tbl do AddToClass( b, classid ) end end function ClassInitialize() for i=0, sg_maxClasses do if (squadclass) then
FastAddToClass( squadclass, i )
end
end
AddClassName( eMotherShip, "Motherships")
AddClassName( eCollector, "Collectors")
AddClassName( eDropOff, "DropOffs")
AddClassName( eFighter, "Fighters")
AddClassName( eFrigate, "Frigates")
AddClassName( eCorvette, "Corvettes")
AddClassName( eCapital, "Capital")
AddClassName( eAntiFighter, "AntiFighter")
AddClassName( eAntiCorvette, "AntiCorvette")
AddClassName( eAntiFrigate, "AntiFrigate")
AddClassName( ePlatform, "Platform")
AddClassName( eRefinery, "Refinery")
AddClassName( eHyperspaceGate, "HypGates")
AddClassName( eShield, "Shields")
AddClassName( eCapture, "Capture")
AddClassName( eSubSystemAttackers, "SubSysKillas")
AddClassName( eBattleCruiser, "BattleCruiser")
end

エラーを修正しましょう
classdef.luaの登録によってAIは動作するようになりました。
しかし、自分の設定ミスによりエラーが発生します。

本来はアップデートで直すべき箇所ですが、
丁度良い機会なのでエラーを修正してみましょう。

AIはプログラムに従って指定されたデストロイヤーを生産しようとするのですが、
肝心のデストロイヤーとのリンクが上手くいっていません。
今回はこれを修正してみましょう。

scripts/races/aaa/scripts/ai_build.lua
を開いてください。

aitrace("LOADING HIIGARAN BUILD INFO") kCollector = AAA_RESOURCECOLLECTOR kRefinery = AAA_RESOURCECONTROLLER kScout = AAA_SCOUT kInterceptor = AAA_INTERCEPTOR kBomber = AAA_ATTACKBOMBER kCarrier = AAA_CARRIER kShipYard = AAA_SHIPYARD kDestroyer = AAA_DESTROYERTA kBattleCruiser = AAA_BATTLECRUISER function DetermineDemandWithNoCounterInfo_aaa() if (sg_randFavorShipType < 25) then ShipDemandAddByClass( eFighter, 1 ) elseif (sg_randFavorShipType < 65) then ShipDemandAddByClass( eCorvette, 1 ) else ShipDemandAddByClass( eFrigate, 1 ) end end function DetermineSpecialDemand_aaa() local numShipyards = NumSquadrons( kShipYard ) + NumSquadronsQ( kShipYard ) if (numShipyards == 0 and UnderAttackThreat() < -75) then local bcDemand = ShipDemandGet( kBattleCruiser ) if (bcDemand >= 0.5) then ShipDemandAdd( kShipYard, bcDemand-0.5 ) end end if (s_militaryStrength > 25*sg_moreEnemies) then ShipDemandAddByClass( ePlatform, -2 ) end end Proc_DetermineDemandWithNoCounterInfo = DetermineDemandWithNoCounterInfo_aaa Proc_DetermineSpecialDemand = DetermineSpecialDemand_aaa

さて、デストロイヤーの項目ですが、
AAA_DESTROYERTA
は名前が間違っています。
これではエラーが発生するはずですね。
修正しましょう。

× kDestroyer = AAA_DESTROYERTA 〇 kDestroyer = AAA_DESTROYER

これでエラーは解消されるはずです。

startingfleetsフォルダを編集しよう
AIが起動するようになりましたが、
スタート時にマザーシップ1隻でだらだらします。
startingfleetsフォルダを編集してスタート時のユニットを増やしましょう。
scripts/startingfleets/aaa00.lua
を開いてください。
PersistantData = { StrikeGroups = {}, Squadrons = { { type = "aaa_mothership", subsystems = {}, shiphold = {}, name = "", size = 1, number = 1, }, }, Research = {}, }

{}で囲まれた部分を1ブロック扱いで良いです。
これをコピーして他のユニットに適応させます。

PersistantData = { StrikeGroups = {}, Squadrons = { { type = "aaa_mothership", subsystems = {}, shiphold = {}, name = "", size = 1, number = 1, }, { type = "aaa_resourcecollector", subsystems = {}, shiphold = {}, name = "", size = 1, number = 8, }, { type = "aaa_carrier", subsystems = {}, shiphold = {}, name = "", size = 1, number = 1, }, }, Research = {}, }
これでキャリアー1隻とリソースコレクター8機が最初から登場します。


↑ユニットの種類不足で完璧ではありませんが、AIが動作すれば成功です。