[Guide] Creating a basic balance mod with a merge blueprint.

8

You can view this as a google document HERE

This is a start of a series about creating basic modifications in Supreme Commander. This guide was made by both biass and Dragun101, with the hopes that the community could use this knowledge to create balance mods to test their theories. Special thanks to Balthazar for his assistance.

Requisites

Wait, what is a “merge blueprint”?

Every unit in Supreme Commander has it’s stats and features controlled by a text file called a blueprint file. The file syntax for blueprints are “.bp” files.

What we’re doing here is creating a second blueprint file for the game to compare to the first one.
The game will then add your code into the original blueprint file for the unit(s) you’ve selected to change.

For example: If you make a merge blueprint that says that the Pillar tank has 9999hp; that will overwrite the original HP of the unit and thus, the Pillar tank will have 9999hp in the game.

This is the basic foundation for all of our changes in FAF. This includes the core game balance, The Equilibrium mod, and BHEDIT. There are a number of different nuances to that, but we will only go into the surface level today.

Starting off (Mod folder, mod_info.lua)

All mods (and maps!) sit inside a folder so to start a new mod, a new folder needs to be made. I’ll call my mod folder “oneNiceMod” for the purposes of the guide. But you should of course give your folder a relevant name.
If you don’t know what you’re going to do yet, you can come back to this at any time.

Inside this folder, you need to place a file called mod_info.lua
You might need to make a “new text document” and then save it as this name for it to become what you want.

This file is critical because it contains a lot of important information about your mod. Lua files can be opened with your text editor of choice - including basics like notepad - so don’t worry if it asks you for a program.

Inside this file, you need to have a couple lines of very basic code.
Balthazar has kindly provided a template for us to use here, lets go over all of these in order.

name = "My first balance mod"
uid = "4378-3q43-bia55-m0d9"
version = 1
description = "Finally gives UEF the respect they deserve."
author = "biass"
icon = "/mods/oneNiceMod/mod_icon.png"
selectable = true
enabled = true
exclusive = false
ui_only = false
conflicts = { }

Name:

The name of your mod appears in the lobby and the mod vault. You should dictate the exact name of your mod here, and not with the folder you just made earlier.

UID:

UID stands for “Unique Identifier” and will be used by the game to know what mod is what. It’s almost like a barcode for a supermarket. This can in theory be anything, but no two UID’s should be the same. Make sure you add in some stuff so it couldn’t be mistaken for another mod.

You can use https://www.uuidgenerator.net/ if you want a random one.

Version:

When you want to upload a new version to the mod vault, you should increase this number by 1. This will allow the mod vault to properly hide your old version and keep everything clean.

Description:

This text will display in the mod vault when you click on the mod, as well as show in the lobby. It’s best to properly tell other people what your mod does. As well as credit other people for their work if you need to do so.

Author:

This can be anything. You should really just add your username here.

Icon:

This is a link to the image that shows in the mod vault, if you have one to place there. I recommend you make your icon file a .png file, and place it neatly into the folder you made earlier. You don’t need to name your image file “mod_icon.png” but make sure the text path here matches the name of your folder, and the name of the image file.

Selectable and Enabled:

In order for your mod to appear in the lobby for you to use, both of these need to be set as “true”

Optional Mod_info items

If this is your first mod, you won’t need these.

Exclusive:

If you set this to true, you can only use this mod by itself. No other mods can be used if you select this one. It’s best if you just leave this as “false” unless for some reason, you 100% need this to be true. The default is “false” so you don’t need this for your first mod.

ui_only:

Setting this to “true” forces the game to ignore code that impacts the simulation of the game, making it only load code that touches upon the UI. Balance mods impact the sim, so setting this to “true” would make your mod useless. The default value is false, so you don’t actually need this.

Conflicts:

If a mod cannot be used with another mod for any reason, that is referred to as a conflict. Put the UID (See above) of the mods that you cannot use here (For example: “234-345-2345-badmod”) and separate them with a comma. When you select the mod in the lobby, it will ask you if you want to turn off the mods you put here if you have them selected. Remove the examples and leave it empty if you don’t have any conflicts. You won’t have any for your first mod, so you can remove it completely if you wish.

You can go over a more advanced explanation of the mod_info commands here:
https://github.com/FAForever/fa/blob/deploy/fafdevelop/lua/MODS.LUA
You should probably do this some other time, lets move on.

The Meat of the Mod

Blueprint files can be loaded from anywhere inside the mod, but I highly recommend you create some subfolders for organization.

Create a new folder inside your first, and call it “merge”.
You can name this whatever in reality, but “merge” is clean and descriptive of it’s content.
You can make more folders inside here that go as deep as you please, but we will make our first blueprint in this folder.

You can also name the blueprint file whatever you want, and you can edit multiple units from one file.

I’m going to make edits to one unit in this guide. That unit is the Pillar tank, and thus I will make my file “pillar.bp”
Again, you might need to make a new text document, open it, and then save it as “pillar.bp” for it to be correct.

I will now write my first few lines of code.

UnitBlueprint {
	Merge = true,
	BlueprintId = 'uel0202',

}

Make sure to remember the comma marks.

What is a Blueprint ID?

All units in supcom are identified by a code. You need this code in order to select the unit you want to edit.
There are a number of ways for you to get the code, remember how I said you needed the unitdb?
You can see the code underneath the name of the unit in the unitdb. Alternatively, you can see the code in the spawn menu ingame. It’s default binding is Alt + F2.

Reading the code is simple. Lets use the pillar code as an example.
U is for Vanilla (DLC content like the mongoose is D. FA content, including seraphim, is X)
E is for UEF (R is for Cybran, who were originally named the “Recyclers” in early development. A for Aeon, and S for Seraphim)
L for land. (A for Air, B for Building, and S for Navy)
“0” is the category. 0 means factories and factory built units, etc.
“2” is for the tech level, and
The second “02” is for the Pillar specifically.

Changing a Statistic

Now that we have everything set up, we now must figure out what we’re going to change. Each statistic can be changed by writing it’s correct syntax. Furthermore; a number of those are in certain categories, which are called “tables”.
It’s best to look up the correct names instead of trying to guess.

For example, I'm going to change the HP of our pillar to 9999.

Each individual command for changing something is referred to as a “key”.
Here are the two best ways to get that key.

  • There is an incomplete list of documentation here: https://supcom.fandom.com/wiki/Blueprint
  • Open a game, select a unit and hit the "Shows a dialog that allows you to create entities" hotkey. The default binding is Shift F6.

You need to be in windowed mode for the latter to appear.
The Shift F6 menu can also show you the unit code, and you can even just change the stats on the fly mid game too. If you change a stat, any new unit will have the changes applied. These changes of course do not save.

The key for health of a unit is in the “Defense” table. https://supcom.fandom.com/wiki/Blueprint#Defense
We need to start off by referencing that table in the code we typed earlier.

UnitBlueprint {
	Merge = true,
	BlueprintId = 'uel0202',
	Defense = {

	},
}

Make sure you’re using the correct, squiggly line brackets. You also don’t need to move everything “across”, but I personally find It’s much easier to understand if you do.

The key for the health of the unit is MaxHealth. We also want to use Health, so the pillar does not spawn with less HP than the new maximum. (That we're setting with MaxHealth)

We will add these two keys inside the Defense table we just wrote, along with the required value.

UnitBlueprint {
	Merge = true,
	BlueprintId = 'uel0202',
	Defense = {
		Health = 9999,
		MaxHealth = 9999,
	},
}

That's one change down. I’m going to make another. Let's change the rate of fire of the pillar’s gun to fire at 600 shots a minute.
Weapons can fire once per “tick” and the game runs at 10 ticks a second. That’s 10 shots a second.

Weapons in FAF are complex, and thus use more complicated code.
We can see that the “RateOfFire” key we need to write is in the “Weapon” table. Let's add them both in now.

UnitBlueprint {
	Merge = true,
	BlueprintId = 'uel0202',
	Defense = {
		Health = 9999,
		MaxHealth = 9999,
	},
	Weapon = {
		[1] = {
		RateOfFire = 10,
		},
	},
}

We want to change the statistics for the pillar’s first weapon. It’s also the only weapon, but we still need to mention that. That's why the weapon section requires more brackets and etc, than the health. If the vehicle has 2 weapons you would just make another item. Like the following:

Weapon = {
	[1] = {
	   RateOfFire = 5,
	},
	[2] = {
	   RateOfFire = 2,
	},
},

Make sure that the closing bracket for your tables is followed by a comma.

Doing something like this is referred to as an Array, which typically starts at 0 in most other programming languages. We need to list our weapons inside an array, and have done so for our examples. Let's move on for now.

With our simple block of code, the pillar now has 9999 health, and fires it’s gun at 600 shots per minute. Finally, let's add a new description to the unit. This key does not need a table.

UnitBlueprint {
	Merge = true,
	BlueprintId = 'uel0202',
	Description = 'Finally faf is balanced',
	Defense = {
		Health = 9999,
		MaxHealth = 9999,
	},
	Weapon = {
		[1] = {
		RateOfFire = 10,
		},
	},
}

I've put this in before the tables because it looks neat. Typically, and outside of the first couple of lines; tables and keys are organised in alphabetical order. It helps a lot when your blueprint files are 100 lines long.

The description should probably be something along the lines of “Modified Heavy Tank” so it makes more sense in game. This is just an example of what a key looks like without needing to be inside of a table.

Testing a mod

You don’t need to upload a mod to the faf vault in order to test to see if your mod works, and to be honest. Most people would rather the vault not be spammed with single stat changes.

Please see: https://forum.faforever.com/topic/671/how-to-test-a-mod-offline-locally

With any luck, your mod should now be able to work ingame. If not, you might need to go back and check to see if everything is written properly. Check your upper/lower case, and your commas/apostrophes. Feel free to look at other mods for comparison if you need, but don’t steal their work!

alt text

Eat your heart out, balance team.

0

"R is for Cybran, who were originally named the 'Reclaimers' in early development."

Actually, the faction was known as "Recyclers"

This is very good info, I learned a little. I knew most of this already just by peeping other people's mods and copying the way they did things. It's definitely nice to have a formal explanation here. I never did figure folders out. It turns out, from reading this, that they just don't matter.

UPDATE: I am informed that folders don't matter for blueprint files, but they can matter for other things that you might put in a mod, like functions.

0

@arma473 said in [Guide] Creating a basic balance mod with a merge blueprint.:

Actually, the faction was known as "Recyclers"

Fixed, thanks!

0

Any idea how to use the unit's current stats in a formula? For instance, if I want to double the Pillar's rate of fire, I'd want to write something like

Weapon = {
    [1] = {
        RateOfFire = RateOfFire * 2,
    }
}

Of course, I've tested it written like that but it doesn't seem to work. Would it even be possible?

0

Blueprints are loaded and registered BEFORE the game begins - so there is no functionality for modifying them once the game has begun.

1

@old_junk

Here is some code that copies some of the existing code for the pillar, and adds a multiplier to the rate of fire. This will double the rate of fire

UnitBlueprint {
	Merge = true,
	BlueprintId="uel0202", # Pillar Heavy Tank

	Weapon = {
		{
			RateOfFire = 0.8 * 2, # add x2 multiplier
		}
	}
}

(fun fact: the pillar's real ROF is not actually 0.8, it's actually 0.833333/second, and if you double it, it will not be 1.6, it will be 1.66666667/second. This is because of how the engine works, namely it converts "shots/second" into "ticks/shot" and this "ticks/shot" figure must be an integer. In-game, when a unit fires, it must wait at least that many ticks before it can fire again. The game converts the 0.8 figure into "12 ticks between shots")

I think this is what you are looking for, an easier way to modify vanilla values without doing lots of math. This makes it easy to make adjustments to your mod, in relation to vanilla values, because all you have to do is tweak your multiplier. You don't have to keep track of what the original version was and do a bunch of math every time you want to make a slight adjustment.

If that's not what you're looking for, then it sounds like what you want is a mod that doubles the pillar's rate of fire "no matter what" mods are active. That would be something different. What I mean is:

If you use the above mod, the pillar's rate of fire is changed to 1.6 (effective: 1.66667).

If you use BOTH the above mod, and also Biass' mod in this thread (bumping pillar ROF to 10, which means 1 tick/shot) then what is the pillar's new rate of fire? It depends which mod is last in the load order. If my mod is last, then the pillar's ROF is 1.66667. If Biass' mod is last, then the pillar's ROF is 10.

IF you want to make a mod that doubles the pillars ROF "no matter what" (meaning: if your mod is on AND biass' mod is also on, pillars would shoot 20 times per second) then you would need to code that differently. You couldn't accomplish that with a blueprint mod, because your blueprint mod would just overwrite someone else's mod, instead of doubling the rate of fire in their mod.

You would probably need to edit Lua code somewhere else in the system. For example, if there was a routine for "units_shoot()" maybe you could edit that to add code "if(the firing unit is a pillar) then (double the rate of fire) otherwise (normal rate of fire)" and the game would always run that code every time any unit was shooting, and it would always double the ROF for pillars.

This seems like a very silly idea, rewriting code at the heart of the game engine so you could disrupt the balance choices that other people made when they created their own mods, just so you could have a mod that arbitrarily doubles some value. So I think what you want is what I'm suggesting above . . .

(fun fact: you can't increase the pillar's rate of fire past "10" because that is the maximum rate of fire, 1 tick/shot.)

0

@Sprouto No.

@arma473 Exactly, I want to have my mod load last, and modify the value produced from the vanilla settings and any previous mods. For instance, suppose I want to make a mod that slows all units' rate of fire and doubles their damage. And I want to use current FAF balancing, including patches, without having to update my mod each time FAF releases a new balance patch.

On further research, I found a dev tip in mohodata/lua/mods.lua, to the effect that you can change blueprints after they've all been loaded:

"Finally, a mod can define a ModBlueprints() function which manipulates the original_blueprints table in arbitrary ways. [How/when exactly is this done?]"

I'll try that and report on the outcome, but I was wondering if anyone knows a simpler and/or better way.

3

This is not a QnA Thread, please make a new thread for asking questions or join the discord.

0

There is a mod called : SafeReload v2.0 that allows to change blueprints after they've all been loaded.

0

@arma473 Thank you for the detailed reply. But, I have to say, you remind me, in a nice way of my now deceased in-law brother who was a software engineer. He worked developing firmware (occasionally using an assembly language based compiler).

He almost always made me regret asking him for a simple yes or no binary answer to one question. His answers usually end up very detailed and he got upset if he thinks I was interrupting him. Lol (I'm a former-programmer-got-promoted-to- management type).