Guide to adding new content to CDDA for first time modders

Adding new vehicle parts

New vehicle parts can be added in JSON. Most interactions between vehicle parts and the rest of the game unfortunately have to be hardcoded, but there’s still a fair bit you can do only in JSON.

Vehicle parts are stored in data/json/vehicle_parts.json and data/json/vehicleparts/ . Please try to put new things in the appropriate file inside of data/json/vehicleparts/ instead of the generic file at data/json/vehicle_parts.json.
Vehicle parts are mostly documented in the general JSON document at
https://github.com/CleverRaven/Cataclysm-DDA/blob/master/doc/JSON_FLAGS.md.

A vehicle part JSON looks like this:

  {
    "type": "vehicle_part",
    "id": "folding_seat",
    "name": "foldable seat",
    "symbol": "#",
    "color": "red",
    "broken_symbol": "*",
    "broken_color": "red",
    "damage_modifier": 10,
    "durability": 20,
    "description": "A crude seat, too uncomfortable to sleep in.",
    "item": "sheet",
    "folded_volume": 10,
    "location": "anywhere",
    "requirements": {
      "install": { "time": 20000, "skills": [ [ "mechanics", 2 ] ], "qualities": [ { "id": "WRENCH", "level": 2 } ] },
      "repair": { "skills": [ [ "mechanics", 2 ] ], "time": 2000, "using": [ [ "welding_standard", 5 ] ] },
      "removal": { "skills": [ [ "mechanics", 2 ] ], "qualities": [ { "id": "WRENCH", "level": 2 } ] }
    },
    "flags": [ "SEAT", "BOARDABLE", "FOLDABLE" ],
    "breaks_into": [ { "item": "rag", "count": [ 1, 6 ] } ]
  }

Some key bits:

  • "type" must be “vehicle_part”
  • "id" must be unique among all vehicle parts, but a vehicle_part and an item can share the same "id".
  • "item" is the part that is required to install the vehicle_part. Vehicle parts inherit their weight and storage capacity from their item.
  • "flags" are special keywords that tell the vehicle code how to interact with an item. They are generally documented in https://github.com/CleverRaven/Cataclysm-DDA/blob/master/doc/JSON_FLAGS.md.
  • "location" controls where the vehicle part can be installed. No vehicle can have two items in the same location of the same tile, unless the location is “ANYWHERE”. Valid locations include:
    • “under” - wheels and things under the chassis
    • “structure” - the frame of the vehicle
    • “center” - on top of the fame, used for major items like seats, welding rigs, windshields, and aisles
    • “engine_block”, “fuel_source” - beneath the center item, used for engines and fuel storage respectively
    • “on_ceiling” - hanging from the vehicle’s roof
    • “on_roof” - on the vehicle’s roof, used for turrets and solar panels
    • “armor” - on the vehicle’s outer frame, protecting other components

Spawning vehicle parts

vehicle_parts only exist while they’re on a vehicle. If you want to a add a vehicle_part to the game and have it spawn, you need to either add it to a vehicle that spawns, or add the vehicle_part’s "item" to an item_group.

Engines and fuel

You can add entirely new engines that consume arbitrary solid or liquid fuels. If you want to add a super-engine that consumes water, you can do that.

Fuels are items, and have JSON that looks like this:

  {
    "id": "chem_ethanol",
    "type": "AMMO",
    "name": "ethanol",
    "name_plural": "ethanol",
    "description": "Extremely pure alcohol suitable for use as a component in chemical reactions.  You could also water it down and drink it, or use it as fuel in alcohol-burning stoves.",
    "weight": 1,
    "volume": "200ml",
    "count": 250,
    "stack_size": 200,
    "category": "chems",
    "phase": "liquid",
    "symbol": "~",
    "color": "white",
    "ammo_type": "conc_alcohol",
    "fuel": {
      "energy": 15.6,
      "explosion_data": { "chance_hot": 5, "chance_cold": 10, "factor": 0.2, "fiery": true, "size_factor": 0.1 }
    }
  }

The important bit here is the "fuel" object at the end, and the really important bit is the "energy" value, which is the energy in MJ/L that the fuel provides. For real world fuels, you can look that number up on wikipedia; for imaginary fuels, just know that gasoline has an energy around 35.

Engines look (more or less, the in game engines use a lot of copy-from to simplify) like this:

{
    "id": "engine_steam_makeshift",
    "type": "vehicle_part",
    "location": "engine_block",
    "symbol": "*",
    "color": "light_red",
    "broken_color": "red",
    "damage_modifier": 80,
    "item": "steam_watts_small",
    "difficulty": 4,
    "durability": 200,
    "fuel_type": "coal_lump",
    "fuel_options": [ "coal_lump", "charcoal" ],
    "cold_affects_start": true,
    "backfire_threshold": 0.25,
    "backfire_freq": 20,
    "noise_factor": 15,
    "damaged_power_factor": 0.25,
    "m2c": 65,
    "epower": 0,
    "power": 55950,
    "energy_consumption": 150000,
    "flags": [ "ENGINE", "TOOL_WRENCH", "E_COMBUSTION", "E_ALTERNATOR", "E_HIGHER_SKILL", "E_HEATER" ],
    "description": "A closed cycle, external combustion steam engine.  Burns coal or charcoal from a bunker in the vehicle to produce steam."
  },

relevant bits:

  • "flags" must include “ENGINE”, and if you can power an alternator off this engine, “E_ALTERNATOR”.
  • "m2c" is the ratio of the engine’s safe power to the engine’s maximum power - the higher this value, the faster the vehicle’s safe velocity
  • "epower" is how much electrical power in watts it takes to operate the engine. This represents spark plugs in most combustion engines. It should be a negative value, because a positive value means the engine generates electrical power independent of an alternator.
  • "power" is how much motive power in watts the engine produces at maximum output. 1 HP = 746 watts, so this is an 80 HP engine.
  • "energy_consumption" is how much fuel the engine consumes at maximum power, again measured in watts. Each turn an engine is operating, it consumes energy_consumption * 1 second * strain joules of energy, where strain is current acceleration / maximum acceleration (plus some idle consumption to power any alternators). Every liter of fuel provides its "energy" * 1,000,000 joules of energy, so energy_consumption * strain / 1000 / energy is the number of liquid fuel charges consumed each turn.
    Energy_consumption should be a number that is larger than power, because that’s how real life physics works.
  • "fuel_type" and "fuel_opts" - the "id" of the engine’s preferred fuel type, and a list of "id"s of any alternate fuel types. So this steam engine prefers coal but can burn charcoal.
2 Likes