Basic XML modding

From Arcen Wiki
Revision as of 14:20, 22 June 2020 by X4000Chris (talk | contribs)
Jump to navigation Jump to search

Brief Explanation Of XML For Non-Coders

XML (Extensible Markup Language) used to create ships, structures, tweak AI difficulty and more.

XML syntax requires all tags to be closed (unlike HTML) all tags look something like this <tagName: stuff here if need be>. with every single tag you create or 'open' it must then be closed. tags can be closed in one of two ways. either like this: <tag1 /> or like this .<tag1> </tag1>. this allows tags to be nested with tags like so:

<tag1>
    <tag2/>
<tag1>

.

There is one tag that is required in XML modding at the start yet does not follow this rule and is one of two exceptions to this rule (the other being commenting). that tag is <?xml version="1.0" encoding="utf-8"?> that tag is used to tell the XML reader (parser) that this xml version is version 1.0 and the character set used (utf-8)

The most common mistake when XML modding will probably be forgetting to close a tag somewhere in your mod and there is very little to tell you where the offending tag is. (if you are XML modding and a big error message shows up it's probably due to forgetting to close a tag). (also please note there are some weird things with mod loader currently and partial records (overwriting) through XML mods so take care when using partial records).

Where To Put Your Mod (And An Example)

for creating a new starting fleet create an XML file. the name doesn't matter just make sure it's an XML file. and put it in: AI War 2\GameData\Configuration\FleetDesignTemplate or put it in a new XML mod folder and then FleetDesignTampate like: AI War 2\XMLMods\anyNameYouWant\FleetDesignTemplate

now in your new XML file for creating a new starting fleet you need to put in these tags in this fashion

<?xml version="1.0" encoding="utf-8"?>
<root>
</root>

These two tags will always be within any XML file used for general AIW2 modding. Within tags the XML parser can read variables used for various reason. for starting fleets we'll need another tag place within the root tag. this tag will contain variables within it. the tag will follow a pattern which will be:

<fleet_design name="InternalName"
        display_name="Name on starting menu"
        description="Description within selection menu"
        design_logic="InitialPlayerFleet" weight="100" include_full_cap_of_each_type="true"
        append_each_ship_description_to_main_description="true" don't touch the last four variables variables (please). btw weight is used more for the non- initial player fleets. (it determines it's likehood to be chosen)
        > </fleet_design>

within these two tags you will put another tag (or a few). the tag will be

<ship_membership name="Entityname" ship_cap_group="Centerpiece" weight="100" min="1" max="1"/> the 'variables' are the Name (please note this is an entity name and I will tell you how to obtain this name later). the weight can be left at 100 and the min and max should be the same. ship_cap_group should be left as is and is ONLY used for the fleet centerpiece (that needs a cap of one only).

the entity name can be found within AI War 2\GameData\Configuration\GameEntity (within the XML files). open any file you want (but preferably KDL_Ships_FleetShips) for finding entities to add to the squad. the entityname 9refered to as name within the XML will be found in

<entity name="VWing" The entity name.
			visuals="assets/_finalgamemeshes/fleetships/fighter/fighterold.prefab"
			icon_name="Official/Fighter"
			voice_group="Fighter"
			category="Ship" is_strikecraft="true"
			size_scale="0.9"
			visuals_scale_multiplier="6"
			collision_priority="100"
			display_name="V-Wing"
			description="Inexpensive and short ranged, adept at shielding allies and chasing down fleeing hostiles."
			starting_mark_level="Mark1" tech_upgrades_that_benefit_me="Generalist,Light"
			cost_for_ai_to_purchase="28"
			hull_points="2700" shield_points="1300" speed="AboveAverage1"
			metal_cost="1800" energy_consumption="400"
			armor_mm="50" albedo="0.3" engine_gx="8" mass_tx="0.21"
			ship_or_structure_explosion_sfx="ShipSmall_Explosion"
			ship_or_structure_explosion_if_on_other_planet_sfx="ShipLostOnOtherPlanet_Explosion"
			exp_to_grant_on_death="20"
      priority_as_ai_target="NormalFleetship" priority_as_frd_target="NormalFleetship" priority_to_protect="Expendable"
      > </entity>

Thus the your fleet will look like this:

<fleet_design name="ClassicStartingFleet"
        display_name="Classic Fleet"
        description="This classic mix isn't good at any one particular thing, but is well-rounded against any foe.  The forcefields just make things even better."
        design_logic="InitialPlayerFleet" weight="100" include_full_cap_of_each_type="true"
        append_each_ship_description_to_main_description="true"
        >
    <ship_membership name="TransportFlagship_Starter" ship_cap_group="Centerpiece" weight="100" min="1" max="1"/>
    <ship_membership name="VWing" ship_cap_group="Strike" weight="100" min="40" max="40"/>
    <ship_membership name="FusionBomber" ship_cap_group="Strike" weight="100" min="40" max="40"/>
    <ship_membership name="ConcussionCorvette" ship_cap_group="Strike" weight="100" min="40" max="40"/>
    <ship_membership name="ForcefieldFrigate" ship_cap_group="Frigate" weight="100" min="1" max="1"/>
  </fleet_design>

yes this is a base game fleet. (each fleet_membership tag represents a single unit's cap and type for the fleet). your final file should look like this:

<?xml version="1.0" encoding="utf-8"?>
<root>
  <fleet_design name="ClassicStartingFleet"
        display_name="Classic Fleet"
        description="This classic mix isn't good at any one particular thing, but is well-rounded against any foe.  The forcefields just make things even better."
        design_logic="InitialPlayerFleet" weight="100" include_full_cap_of_each_type="true"
        append_each_ship_description_to_main_description="true"
        >
    <ship_membership name="TransportFlagship_Starter" ship_cap_group="Centerpiece" weight="100" min="1" max="1"/>
    <ship_membership name="VWing" ship_cap_group="Strike" weight="100" min="40" max="40"/>
    <ship_membership name="FusionBomber" ship_cap_group="Strike" weight="100" min="40" max="40"/>
    <ship_membership name="ConcussionCorvette" ship_cap_group="Strike" weight="100" min="40" max="40"/>
    <ship_membership name="ForcefieldFrigate" ship_cap_group="Frigate" weight="100" min="1" max="1"/>
  </fleet_design>
</root>

again please note this is a base game fleet.

Modding Existing Ships Or Similar

If you want to edit an existing ship, difficulty level, or whatever else, then you want to make a new xml file of your own inside your mod folder, matching the structure of the existing xml folder of whatever you want to mod. Note that your filename doesn't have to have any bearing on the original filename.

You now have two options on how to proceed:

Alter The Existing Item (is_partial_record)

Here's an example of how our second expansion actually "mods" the central ExternalConstants by having a file with these contents:

<?xml version="1.0" encoding="utf-8"?>
<root is_partial_record="true"
custom_int_zenithtrader_budgetpersecondforotherfactions="100"
custom_FInt_zenithtrader_aibudgetmultiplierlow="0.5"
custom_FInt_zenithtrader_aibudgetmultipliermedium="1.0"
custom_FInt_zenithtrader_aibudgetmultiplierhigh="1.3"
custom_int_zenithtrader_structurecost="270000"
custom_bool_zenithtrader_spawnonplayerhomeplanet="false"
>
</root>

Note that basically is_partial_record="true" on any xml node (ship, settings, whatever) will let you start adding either new nodes (as in this expansion example), or overwriting prior entries (change the name or difficulty of a ship, make a ship faster, etc).

Copy The Existing Item And Make Changes (copy_from)

Here's an example from within the main base game itself:

<entity name="AstroTrainTankStyleHigh" cannot_be_stacked="true"
          copy_from="AstroTrainTankStyle"
			tags="AstroTrain,AstroTrainHigh,ShowsOnNormalDisplayMode"
			hull_points="3500000" shield_points="2500000" speed="BelowAverage2"
			>
    <system name="FusionBomb" display_name="Demolisher Fusion Bomb"
				category="Weapon" firing_timing="OnlyInRange"
				damage_per_shot="15000" range="Normal5" shot_speed="Slow" rate_of_fire="High"
				shots_per_salvo="20" fires_salvos_sequentially="false"
				shot_type_data="FusionBomb"
				base_percent_damage_bypasses_personal_shields="1"
				only_targets_static_units="true"
				>
    </system>		
  </entity>

Essentially there are a lot of cases where we want to take some entity, in this case AstroTrainTankStyle, and we want to then make some changes to make a new variant (in this case called AstroTrainTankStyleHigh). In this case we added some guns, changed around hull points, shield, and speed, but otherwise left all the basic things from the underlying entity.

It's good practice to leave all of the fields in place except the ones you actually want to change, so that your variant will continue to evolve with the base unit if it gets some changes unrelated to the overrrides you have set up?

But hey, what about that "tags" field? That's being spelled out here, and identical to the original. That brings us to...

How Fields Act During copy_from Or is_partial_record