ホーム › MOD制作情報 › 旧式ミューテータの移植
第05章

旧式ミューテータの移植

KroggyComm 1.1をアーカイブからパッケージへ。TA: Mutationのルールファイルはsmで残すか、Luaで書き直す。

この章はdocs/mutators/authoring.mdとdocs/mutators/oamut-standard.mdの要約です。

元のアーカイブ

ImmermanのKroggyComm 1.1は、}{KroggyComm11.tamと}{KroggyComm11.ccxとして配布されました。.tamはTA: Mutationの記録で、名前、作者をクレジットするテキスト、互換性コードTACCとUHが入っています。.ccxには、クロゴスのモデル、2回格納された1つのコマンダースクリプト(ARM用とCORE用)、2体のコマンダーのユニットファイル、スクリプトのソース、残骸が入っています。この章ではアーカイブの中身を貼り付けず、仕上げたパッケージが何を残し、それぞれがどこへ移ったかを示します。

インポートから始める

oa-tool mutator importは.tamを読み、隣にある.ccxを見つけます。出力先は、.tamのあるフォルダー以外にしてください。警告は、手を入れるべき点を示します。タグは既定値のまま、TACCはta-3.1cになり、UHには対応するMODがありません。

$ oa-tool mutator import 'originals/}{KroggyComm11.tam' --out imports
imported kroggycomm-1-1 from originals/}{KroggyComm11.tam: 0 rule files, 1 archives
  tags default to gameplay
  TACC maps to ta-3.1c; Core Contingency's units are only there when it is on
  UH is not mapped to a mod

インポートは.ccx全体をfiles/kroggycomm-1-1.ccxに残し、書き出すスクリプトはそのフォルダーを追加するだけです。マニフェストには、バージョン1.0、gameplayタグ、works-withのta-3.1c、filesレイヤー、legacyの記録が入ります。このフォルダーでも遊べますが、これはパッケージの出発点であって、完成したミューテータではありません。

インポート · mutator.lua
-- Made by oa-tool mutator import from the TA: Mutation mutator "KroggyComm 1.1".
-- Its rule file is in rules/ and its archives in files/; files OA protects are left out.
function mutate(ctx)
  return {
    files = { add = { "files" } },
  }
end

モデルとスクリプトはfiles/へ

仕上げたパッケージは、ゲームがアーカイブから読むものだけを残します。files/の下にある3つのパスで、それぞれゲームが探す場所に置かれています。

files/objects3d/KROGCOM.3doモデル。.ccxのobjects3d/KROGCOM.3doからfiles/scripts/armcom.cobARMのスクリプト。scripts/armcom.cobからfiles/scripts/corcom.cobCOREのスクリプト。ARMと同じ中身で、アーカイブにはscripts/Corcom.cobとして格納

2つのユニットファイルも同梱しません。そのフィールドは後述のルールになります。アーカイブにある残り2つも外しています。scripts/KroggyCom.bosはスクリプトのソースで、ゲームは読みません。features/corpses/Corkrog_dead.tdfはCore Contingencyの残骸で、変更されていません。

FBIの変更はルールへ

クロゴスのユニットフィールドは、仕上げたmutator.luaのルールになります。両方のコマンダーが、オブジェクトKROGCOM、武器CORKROG_FIRE、CORKROG_ROCKET、CORKROG_HEAD、コスト、占有範囲、移動性能を受け取ります。クロークと攻撃対象外のフィールドを削除するのは、このデザインの一部です。HealTime、OvrAdjust、DefaultMissionTypeは3.1cの値のままです。2001年のユニットファイルはこれらのフィールドができる前のものなので、フィールドがないことはクロゴスのデザインによるものではありません。ARMのサウンドカテゴリーはKROGOTHになります。COREはCORE_COMのままなので、スクリプトはnilを渡し、soundcategoryを設定しません。この3つの武器がなければ、unitsフックが対戦を拒否します。

エントリスクリプト · mutator.lua
-- HealTime, OvrAdjust, DefaultMissionType and the localized names stay.
-- The 2001 unit files predate those 3.1c fields, so their absence is not the Krogoth's design.
local function krogoth_changes(sound)
  local changes = {
    acceleration = set(0.09),
    badtargetcategory = remove(),
    brakerate = set(0.19),
    buildcostenergy = set(116664),
    buildcostmetal = set(29489),
    builddistance = set(120),
    buildtime = set(382193),
    cantbetransported = set(1),
    cloakcost = remove(),
    cloakcostmoving = remove(),
    corpse = set("corkrog_dead"),
    downloadable = set(1),
    energymake = set(32),
    energyuse = set(7),
    explodeas = set("NUCLEAR_MISSILE"),
    footprintx = set(3),
    footprintz = set(3),
    maxdamage = set(29918),
    maxslope = set(17),
    maxvelocity = set(1),
    maxwaterdepth = set(12),
    mincloakdistance = remove(),
    movementclass = set("TANKDH3"),
    noautofire = set(0),
    objectname = set("KROGCOM"),
    onoffable = set(1),
    selfdestructas = set("NUCLEAR_MISSILE"),
    sightdistance = set(255),
    turnrate = set(960),
    weapon1 = set("CORKROG_FIRE"),
    weapon2 = set("CORKROG_ROCKET"),
    weapon3 = set("CORKROG_HEAD"),
    wpri_badtargetcategory = remove(),
  }
  if sound ~= nil then
    changes.soundcategory = set(sound)
  end
  return changes
end

function mutate(ctx)
  return {
    files = { add = { "files" } },
    rules = {
      named("ARMCOM"):change(krogoth_changes("KROGOTH")),
      named("CORCOM"):change(krogoth_changes(nil)),
    },
    units = function(units, ctx)
      local weapons = ctx.weapons
      if weapons["CORKROG_FIRE"] == nil or weapons["CORKROG_ROCKET"] == nil or weapons["CORKROG_HEAD"] == nil then
        ctx.incompatible("KroggyComm needs Core Contingency's Krogoth weapons")
      end
    end,
  }
end

legacyブロックとクレジット

legacyは元のミューテータを示します。インポートが書いた記録をそのまま残してください。名前KroggyComm 1.1、プレフィックス}{、互換性TACCとUH、ファイル}{KroggyComm11.tamと}{KroggyComm11.ccxです。作者はImmermanのままにし、説明には置き換える元のミューテータとその作者を書きます。これがクレジットです。残りは手を入れます。バージョン1、タグcommandersとnew-units、works-withは星印にしてどのMODとベースゲームにも合うようにし、ファイル、ルール、フックのためにレイヤーfilesとunitsを指定します。conflicts-withには、同じコマンダーのフィールドを書き換えるか同じスクリプトを同梱するanni-comm、special-tech-comm、commander-blast、tribe-commanderを挙げます。下のマニフェストがファイル全体です。

マニフェスト · oamut.yaml
oamut: 1
id: "kroggy-comm"
name: "Krogoth Commander"
version: "1"
author:
  name: "Immerman"
description: "Use an amphibious Krogoth as a commander. Turn it off to disable the radar, the sonar and the head laser in exchange for 7 energy. The D-gun aims the head laser. Arm and Core are both named because one script is shipped for each commander. This package replaces KroggyComm 1.1 by Immerman. The model and the scripts stay as files, and the Krogoth's stats are rules, including the cloak and bad-target removals that belong to that design. Heal time, the override adjust, the default mission and the localized names stay, because the 2001 unit files left them out. It needs Core Contingency's Krogoth weapons."
tags: ["commanders", "new-units"]
works-with: ["*"]
requires:
  engine: ">= 0.8.5"
conflicts-with: ["anni-comm", "special-tech-comm", "commander-blast", "tribe-commander"]
layers: ["files", "units"]
legacy:
  - name: "KroggyComm 1.1"
    prefix: "}{"
    compatibility: ["TACC", "UH"]
    files: ["}{KroggyComm11.tam", "}{KroggyComm11.ccx"]

確認と、インポートとの差分

フォルダーの外でpackを実行すると、kroggy-comm-1.oamutができます。oa-tool mutator checkはそのファイルを読みます。このパッケージでは、最後の行はresult: okです。差分は、仕上げたフォルダーとインポートkroggycomm-1-1を比べます。commandersのビルドフォルダーから、そのファミリーの許可ファイルを付けて実行したもので、DIRはゲームフォルダーを表します。許可ファイルには、残ってもよい差分を書きます。

$ oa-tool mutator pack kroggy-comm
$ oa-tool mutator check kroggy-comm-1.oamut
$ oa-tool mutator diff --game-dir DIR --mutator ./kroggy-comm --versus ./_imports/kroggycomm-1-1 --allow _verify/kroggy-comm.allowed

その許可ファイルを使うと、比較は0で終了します。#で始まるヘッダー行の後に、下の行を出力します。差分0、許可7、未使用の許可0です。7行の内容は、右側のインポートが両方のコマンダーでdefaultmissiontype、healtime、ovradjustを落とし、scripts/kroggycom.bosを足していることです。仕上げたパッケージはこの3つのフィールドを残し、.bosは同梱しません。この実行のゲームフォルダーにはクロゴスの3つの武器がそろっていたので、unitsフックはパッケージを拒否しませんでした。

allowed right only field units/armcom.fbi [unitinfo] defaultmissiontype: Standby -> (absent)
allowed right only field units/armcom.fbi [unitinfo] healtime: 27 -> (absent)
allowed right only field units/armcom.fbi [unitinfo] ovradjust: 1 -> (absent)
allowed right only field units/corcom.fbi [unitinfo] defaultmissiontype: Standby -> (absent)
allowed right only field units/corcom.fbi [unitinfo] healtime: 27 -> (absent)
allowed right only field units/corcom.fbi [unitinfo] ovradjust: 1 -> (absent)
allowed right only file added scripts/kroggycom.bos aef95595e9dc1a1e543cf87c954c0b19e6523a227e89c4abaa40e6d264043889
mutator diff: 0 differences, 7 allowed, 0 unused allowances

TA: Mutationのルールファイル

仕上げたパッケージは.smファイルを同梱しません。oa-tool mutator importは元のルールファイルを残し、プランからsmで指定します。KirkのHide Damageが短い例です。インポートはrules/hide-damage.smと、rulesの項目がsm "rules/hide-damage.sm"であるmutator.luaを書きます。下の.smがそのファイルで、改行コードもそのままです。

インポート · mutator.lua
-- Made by oa-tool mutator import from the TA: Mutation mutator "Hide Damage".
-- Its rule file is in rules/ and its archives in files/; files OA protects are left out.
function mutate(ctx)
  return {
    rules = { sm "rules/hide-damage.sm" },
  }
end
ルールファイル · rules/hide-damage.sm
[*all*]
{
HideDamage=1;
}

同じルールをLuaで書くとall():change { hidedamage = set(1) }です。[*all*]とHideDamage=1はこうなります。仕上げたパッケージが同梱するのはこのスクリプトで、.smではありません。legacyの記録には今も{}HideDamage.tamと{}HideDamage.smが書かれ、作者はKirkのままです。

エントリスクリプト · mutator.lua
function mutate(ctx)
  return {
    rules = {
      all():change { hidedamage = set(1) },
    },
  }
end
マニフェスト · oamut.yaml
oamut: 1
id: "hide-damage"
name: "Hide Damage"
version: "1"
author:
  name: "Kirk"
description: "Opponents cannot see how much health a unit has left.\n\nKirk's Hide Damage sets that flag on every unit.\n\nThis package keeps the flag."
tags: ["gameplay"]
works-with: ["*"]
requires:
  engine: ">= 0.8.5"
layers: ["units"]
legacy:
  - name: "Hide Damage"
    prefix: "{}"
    compatibility: ["*"]
    files: ["{}HideDamage.tam", "{}HideDamage.sm"]

コマンドはoa-tool mutator import INPUT... --out DIRです。必要に応じて--id、--version、--tag、--works-with、--pack、--forceを加えます。.smはrules/の下にコピーされ、プランからsmで指定されます。インポートはパッケージの出発点です。公開する前に、バリエーションはオプションにまとめ、ルールファイルはLuaの書き方に直すかsmで指定したまま残し、ファイルはモデルやスクリプトが必要とするものだけにしてください。