오픈 소스 모험: 에피소드 45: BATTLETECH 게임이 데이터를 저장하는 방법

39653 단어 battletechgamedev
최근에 나는 BATTLETECH을 많이 연주하고 있습니다.

Let's say XCOM2나 Civ5와 같은 대부분의 유사한 게임에는 상당히 제한된 양의 캐릭터 클래스, 무기가 있으므로 Muton과 Sectoid, 로켓 발사기와 화염방사기 또는 Pikeman과 Catapult의 차이점을 배우기가 매우 쉽습니다. Civ5의 특수 유닛은 일반적으로 특정 보너스가 있는 기본 유닛입니다.

피규어 게임으로 시작했기 때문에 BATTLETECH에는 사소한 차이를 제외하고 너무 많은 장비가 있습니다.

103개의 기계, 172개의 무기 및 기타 많은 장비가 있습니다. 어떤 빌드가 좋고 어떤 빌드가 좋지 않은지 파악하는 것은 정말 어렵습니다.

기계와 무기가 있는 Google 스프레드시트를 본 적이 있지만 정말 만족스럽고 전체 세트가 아닌 기본 무기만 다루는 경우가 많습니다.

BATTLETECH 게임이 데이터를 저장하는 위치



Steam 버전이 있는 경우 기본적으로 게임은 C:\Program Files (x86)\Steam\steamapps\common\BATTLETECH에 설치됩니다. 잘 모르겠어

해당 폴더 내에서 BattleTech_Data\StreamingAssets\data 를 더 자세히 살펴봐야 합니다.

역사적으로 대부분의 게임은 데이터를 사용자 지정 형식으로 코딩했기 때문에 그러한 프로젝트의 첫 번째 부분은 일부 사용자 지정 파서를 작성하는 것입니다. 이러한 형식의 대부분은 상당히 단순했지만 가끔 엄청나게 복잡한 데이터 형식을 접하게 되거나 심지어 게임 데이터가 코드에 하드코딩되는 경우도 있었습니다.

그러나 우리는 미래에 살고 있으며 데이터는 대부분 JSON입니다.

관심 데이터



가장 관심 있는 데이터는 weaponmech/chassis 의 두 폴더입니다.
ammunition , ammunitionBox , 아마도 heatsinks , upgrades 등과 같은 약간의 추가 데이터를 포함하는 몇 개의 추가 폴더가 있습니다. 다행히 모두 JSON입니다.

일부 다른 데이터(루트 테이블과 같은)는 .csv에 있습니다. 지도 및 오디오 자산과 같은 일부 바이너리 데이터도 있지만 우리가 원하는 거의 모든 것은 JSON입니다.

기계 JSON 예



다음은 chassis/chassisdef_kintaro_KTO-18.json의 예입니다(가독성을 위해 자동으로 다시 포맷됨).

{
  "Description": {
    "Cost": 5200000,
    "Rarity": 3,
    "Purchasable": true,
    "Manufacturer": "",
    "Model": "",
    "UIName": "Kintaro",
    "Id": "chassisdef_kintaro_KTO-18",
    "Name": "Kintaro",
    "Details": "The Kintaro 18 is… a beast of a machine. It's fast for its size, mounts heavy armor, and can literally shred most other 'Mechs with its almost ridiculous amount of close-range weaponry. But, it runs hotter than Hell's saunas.",
    "Icon": "uixTxrIcon_kintaro"
  },
  "MovementCapDefID": "movedef_kintaro_KTO-18",
  "PathingCapDefID": "pathingdef_medium",
  "HardpointDataDefID": "hardpointdatadef_kintaro",
  "PrefabIdentifier": "chrPrfMech_kintaroBase-001",
  "PrefabBase": "kintaro",
  "Tonnage": 55,
  "InitialTonnage": 27,
  "weightClass": "MEDIUM",
  "BattleValue": 5148000,
  "Heatsinks": 0,
  "TopSpeed": 80,
  "TurnRadius": 90,
  "MaxJumpjets": 5,
  "Stability": 130,
  "StabilityDefenses": [
    0,
    0,
    0,
    0,
    0,
    0
  ],
  "SpotterDistanceMultiplier": 1,
  "VisibilityMultiplier": 1,
  "SensorRangeMultiplier": 1,
  "Signature": 0,
  "Radius": 5,
  "PunchesWithLeftArm": false,
  "MeleeDamage": 70,
  "MeleeInstability": 55,
  "MeleeToHitModifier": 0,
  "DFADamage": 70,
  "DFAToHitModifier": 0,
  "DFASelfDamage": 70,
  "DFAInstability": 70,
  "Locations": [
    {
      "Location": "Head",
      "Hardpoints": [],
      "Tonnage": 0,
      "InventorySlots": 1,
      "MaxArmor": 45,
      "MaxRearArmor": -1,
      "InternalStructure": 16
    },
    {
      "Location": "LeftArm",
      "Hardpoints": [
        {
          "WeaponMount": "Missile",
          "Omni": false
        },
        {
          "WeaponMount": "Missile",
          "Omni": false
        },
        {
          "WeaponMount": "Energy",
          "Omni": false
        }
      ],
      "Tonnage": 0,
      "InventorySlots": 8,
      "MaxArmor": 90,
      "MaxRearArmor": -1,
      "InternalStructure": 45
    },
    {
      "Location": "LeftTorso",
      "Hardpoints": [],
      "Tonnage": 0,
      "InventorySlots": 10,
      "MaxArmor": 130,
      "MaxRearArmor": 65,
      "InternalStructure": 65
    },
    {
      "Location": "CenterTorso",
      "Hardpoints": [
        {
          "WeaponMount": "Missile",
          "Omni": false
        }
      ],
      "Tonnage": 0,
      "InventorySlots": 4,
      "MaxArmor": 180,
      "MaxRearArmor": 90,
      "InternalStructure": 90
    },
    {
      "Location": "RightTorso",
      "Hardpoints": [
        {
          "WeaponMount": "Missile",
          "Omni": false
        },
        {
          "WeaponMount": "Missile",
          "Omni": false
        }
      ],
      "Tonnage": 0,
      "InventorySlots": 10,
      "MaxArmor": 130,
      "MaxRearArmor": 65,
      "InternalStructure": 65
    },
    {
      "Location": "RightArm",
      "Hardpoints": [
        {
          "WeaponMount": "Energy",
          "Omni": false
        }
      ],
      "Tonnage": 0,
      "InventorySlots": 8,
      "MaxArmor": 90,
      "MaxRearArmor": -1,
      "InternalStructure": 45
    },
    {
      "Location": "LeftLeg",
      "Hardpoints": [],
      "Tonnage": 0,
      "InventorySlots": 4,
      "MaxArmor": 130,
      "MaxRearArmor": -1,
      "InternalStructure": 65
    },
    {
      "Location": "RightLeg",
      "Hardpoints": [],
      "Tonnage": 0,
      "InventorySlots": 4,
      "MaxArmor": 130,
      "MaxRearArmor": -1,
      "InternalStructure": 65
    }
  ],
  "LOSSourcePositions": [
    {
      "x": 0,
      "y": 15,
      "z": 0
    },
    {
      "x": 3,
      "y": 15,
      "z": 0
    },
    {
      "x": -3,
      "y": 15,
      "z": 0
    }
  ],
  "LOSTargetPositions": [
    {
      "x": 0,
      "y": 15,
      "z": 0
    },
    {
      "x": 3,
      "y": 15,
      "z": 0
    },
    {
      "x": -3,
      "y": 15,
      "z": 0
    },
    {
      "x": 3,
      "y": 5,
      "z": 0
    },
    {
      "x": -3,
      "y": 5,
      "z": 0
    }
  ],
  "VariantName": "KTO-18",
  "ChassisTags": {
    "items": [],
    "tagSetSourceFile": ""
  },
  "StockRole": "Juggernaut & Close Assault",
  "YangsThoughts": "The Kintaro 18 is… a beast of a machine. It's fast for its size, mounts heavy armor, and can literally shred most other 'Mechs with its almost ridiculous amount of close-range weaponry. But, it runs hotter than Hell's saunas."
}


보시다시피 완전한 정의는 아니며 자세한 내용은 movedef_kintaro_KTO-18hardpointdatadef_kintaro를 참조하지만 여전히 더 많은 JSON입니다.

예시 무기 JSON



다음은 무기 JSON - weapon/Weapon_SRM_SRM6_0-STOCK.json 의 예입니다.

우리가 원하는 한 가지가 부족합니다. 1톤 탄약 상자당 발사할 수 있는 횟수입니다. 그 외에는 모두 하나의 JSON에 있습니다.

{
  "Category": "Missile",
  "Type": "SRM",
  "WeaponSubType": "SRM6",
  "MinRange": 0,
  "MaxRange": 270,
  "RangeSplit": [
    180,
    180,
    270
  ],
  "ammoCategoryID": "SRM",
  "StartingAmmoCapacity": 0,
  "HeatGenerated": 12,
  "Damage": 8,
  "OverheatedDamageMultiplier": 0,
  "EvasiveDamageMultiplier": 0,
  "EvasivePipsIgnored": 0,
  "DamageVariance": 0,
  "HeatDamage": 0,
  "AccuracyModifier": 0,
  "CriticalChanceMultiplier": 1,
  "AOECapable": false,
  "IndirectFireCapable": false,
  "RefireModifier": 0,
  "ShotsWhenFired": 6,
  "ProjectilesPerShot": 1,
  "AttackRecoil": 1,
  "Instability": 3,
  "WeaponEffectID": "WeaponEffect-Weapon_SRM6",
  "Description": {
    "Cost": 90000,
    "Rarity": 0,
    "Purchasable": true,
    "Manufacturer": "TharHes",
    "Model": "Short-Range Missile Launcher",
    "UIName": "SRM6",
    "Id": "Weapon_SRM_SRM6_0-STOCK",
    "Name": "SRM6",
    "Details": "SRM6s are the largest available rack of Short-Range Missiles and pack considerable punch while also being lightweight. As for all SRMs, SRM6 shots deal above-average stability impact per hit compared to other weapons.",
    "Icon": "uixSvgIcon_weapon_Missile"
  },
  "BonusValueA": "",
  "BonusValueB": "",
  "ComponentType": "Weapon",
  "ComponentSubType": "Weapon",
  "PrefabIdentifier": "srm6",
  "BattleValue": 0,
  "InventorySize": 2,
  "Tonnage": 3,
  "AllowedLocations": "All",
  "DisallowedLocations": "All",
  "CriticalComponent": false,
  "statusEffects": [],
  "ComponentTags": {
    "items": [
      "component_type_stock",
      "range_standard"
    ],
    "tagSetSourceFile": ""
  }
}


다음에 온다



다음 몇 개의 에피소드에서는 게임 데이터를 로드하고 일부 분석을 출력하는 몇 가지 명령줄 도구를 작성합니다.

가장 먼저 탐색하고 싶은 것은 무기의 톤당 손상 순위입니다.

좋은 웹페이지 즐겨찾기