- Make sure that any new faction has its side-specific mix files present in the MIX folder (Sidec##.mix, SideCD##.mix and Speech##.mix; you can just copy the mix files from GDI or Nod initially)
- Make sure to list all Harvesters and MCVs after HarvesterUnit=
- Make sure all of the new faction's respective structures are specified in the [AI] section (specifically for BuildConst=, BuildPower=, BuildRefinery=, BuildBarracks=, BuildTech=, BuildWeapons=, BuildHelipad= and BuildRadar=). Be aware that you can enter multiple structures for BuildConst= now, so any new faction's Construction Yard needs to be listed there now.
- Remember to add your new faction to Sides= in GameOptions.ini in the Resources folder.
For versions older than 6.00, carry on with the tutorial below.
- - - - - - - - - -
The Dawn of the Tiberium Age has had 4 well-functioning factions with separate MCVs and Construction Yards for a good while already and the work-arounds for this implementation have also improved over the years, especially when Iran’s spawner was made available.
Considering this spawner is also included with the TS Client’s game files and not everybody knows how to make the best use of the new modding features that both the spawner and the TS client offer, I figured this tutorial would be a good start.
For this tutorial I’m going to assume that all faction-specific MCVs and Construction Yards already exist. I’ll divide this tutorial in 3 parts 2 parts, which you might not all need depending on the kind of mod you’re making.
Edit: Part 3 is no longer necessary with the latest TS client version thanks to AlexB's "Side index improvements" patch.
Part 1: Getting unique MCVs and Construction Yards to work for 2 or more factions
The first obstacle is of course the MCV. Since BaseUnit= only accepts a single entry, we’ll have to prevent it from starting altogether and instead have the MCV start as a regular starting unit.
- To do this, first open Resources\GameOptions.ini, look for [ForcedSpawnIniOptions] and add Bases=No and UnitCount=1 under it to prevent the specified BaseUnit from spawning and only having a single starting unit spawn instead. Also remove cmbUnitCount and lblUnitCount under both [GameLobby] and [SkirmishLobby] to remove the UnitCount setting from the game lobby because you're not going to want players to change this.
- Next in INI\Rules.ini, add AllowedToStartInMultiplayer=no to every single unit aside from the MCVs to make sure that the single starting unit all players start with will be an MCV.
All faction-specific MCVs of course need to have the correct owner specified and have TechLevel=1 to make sure they can start on all tech levels or alternatively TechLevel=-1 to make them unbuildable, but still allow them to spawn as starting units (you could then add a different MCV for the players to build instead).
Now to also get the AI to deploy its faction-specific MCV, there are two methods you can use:
- The most practical method is using a HEX-editor to apply a hack to game.exe, which changes the state of the AI’s starting units from Area Guard to Unload: after opening game.exe with your HEX-editor, goto offset 0x001DEE37 and replace 0A with 0F.
- If there’s a reason why you don’t want to or can’t edit the game.exe file, you can instead give the MCVs DeployToFire=yes, GuardRange=512 and Primary= with a weapon specified that has Range=512 (any kind of weapon is fine, as long as it has Range=512: you could also simply use the Deployer weapon below).
Note: only use one of these methods and never both at the same time because that can cause the AI’s MCVs to not deploy again.
Now that you’ve got the MCVs working, you’ll likely first notice that the AI players won’t build anything at all, which brings us to the second obstacle.
The second obstacle is the BuildConst= key. Just like BaseUnit=, it only accepts a single entry and the problem is that AI players won’t build anything when they don’t own the specified BuildConst structure, while human players won’t be able to build any structures that only have a single owner specified.
The fact that BuildConst= only accepts a single entry makes it impossible to specify all faction-specific Construction Yards, meaning we need a work-around for that too. This is where the spawner comes in: the spawner allows you to pre-place units and structures on maps that are owned by specific players, which means that we can just pre-place these BuildConst structures on all maps.
While we could edit all maps and manually add these structures on them, this would end up becoming quite a chore (especially if there’s a lot of existing maps that need to be edited). Fortunately the client introduces GlobalCode.ini: any code entered in it will automatically be added to multiplayer maps when the client loads them and starts the game. We'll get back to this file later.
Although it’s perfectly possible to pre-place the BuildConst structures with some code, this causes problems with the WallOwner logic of the game: if there are any pre-placed walls on a map and there’s also pre-placed structures belonging to one of the Spawn# houses, any walls near them will then automatically also be owned by one of those Spawn# houses. So to get around this we’ll instead pre-place units on the map, which will then immediately deploy into the BuildConst structures when the game starts via a deployer weapon.
First off add the code for the structure, unit and its weapon to Rules.ini (for convenience the IDs will be BUILDCONST for the structure and BLDCNSTU for the unit):
Code:
[BUILDCONST]
Image=GALITE
Name=BuildConst Structure
Strength=600
Armor=wood
TogglePower=no
Selectable=no
Immune=yes
LegalTarget=no
Insignificant=yes
BridgeRepairHut=yes
PlaceAnywhere=yes
InvisibleInGame=yes
BaseNormal=no
[BLDCNSTU]
Image=
Name=BuildConst Unit
ROT=16 ;with 0 and no Speed= value it's unable to deploy
Strength=1
Selectable=false
Insignificant=yes
Locomotor={4A582741-9839-11d1-B709-00A024DDAFD1}
DeploysInto=BUILDCONST
Secondary=Deployer
DeployToFire=yes
GuardRange=512
[Deployer]
Damage=0
Range=512
Projectile=Invisible
Warhead=Super
Image=GALITE
Name=BuildConst Structure
Strength=600
Armor=wood
TogglePower=no
Selectable=no
Immune=yes
LegalTarget=no
Insignificant=yes
BridgeRepairHut=yes
PlaceAnywhere=yes
InvisibleInGame=yes
BaseNormal=no
[BLDCNSTU]
Image=
Name=BuildConst Unit
ROT=16 ;with 0 and no Speed= value it's unable to deploy
Strength=1
Selectable=false
Insignificant=yes
Locomotor={4A582741-9839-11d1-B709-00A024DDAFD1}
DeploysInto=BUILDCONST
Secondary=Deployer
DeployToFire=yes
GuardRange=512
[Deployer]
Damage=0
Range=512
Projectile=Invisible
Warhead=Super
After doing this, search for [AI] in Rules.ini and replace BuildConst= and its entry with BuildConst=BUILDCONST, add BUILDCONST to the [BuildingTypes] list and you’re set.
Now that the code has been added to Rules.ini, you only need to make sure the BLDCNSTU unit is present on every map when the game to starts, bringing us back to the GlobalCode.ini file I mentioned earlier.
Open INI\Map Code\GlobalCode.ini (or create it first if it doesn’t exist already) and add the following code:
Code:
[Units]
FFS=Spawn1,BLDCNSTU,256,0,0,64,Unload,None,0,-1,0,-1,1,0
FFT=Spawn2,BLDCNSTU,256,1,0,64,Unload,None,0,-1,0,-1,1,0
FFU=Spawn3,BLDCNSTU,256,2,0,64,Unload,None,0,-1,0,-1,1,0
FFV=Spawn4,BLDCNSTU,256,3,0,64,Unload,None,0,-1,0,-1,1,0
FFW=Spawn5,BLDCNSTU,256,4,0,64,Unload,None,0,-1,0,-1,1,0
FFX=Spawn6,BLDCNSTU,256,5,0,64,Unload,None,0,-1,0,-1,1,0
FFY=Spawn7,BLDCNSTU,256,6,0,64,Unload,None,0,-1,0,-1,1,0
FFZ=Spawn8,BLDCNSTU,256,7,0,64,Unload,None,0,-1,0,-1,1,0
FFS=Spawn1,BLDCNSTU,256,0,0,64,Unload,None,0,-1,0,-1,1,0
FFT=Spawn2,BLDCNSTU,256,1,0,64,Unload,None,0,-1,0,-1,1,0
FFU=Spawn3,BLDCNSTU,256,2,0,64,Unload,None,0,-1,0,-1,1,0
FFV=Spawn4,BLDCNSTU,256,3,0,64,Unload,None,0,-1,0,-1,1,0
FFW=Spawn5,BLDCNSTU,256,4,0,64,Unload,None,0,-1,0,-1,1,0
FFX=Spawn6,BLDCNSTU,256,5,0,64,Unload,None,0,-1,0,-1,1,0
FFY=Spawn7,BLDCNSTU,256,6,0,64,Unload,None,0,-1,0,-1,1,0
FFZ=Spawn8,BLDCNSTU,256,7,0,64,Unload,None,0,-1,0,-1,1,0
To clarify a few things:
- The index at the beginning of the lines uses 3 letters to make sure that it always is added at the bottom of index lists so that it won’t change the indexes of other units that were pre-placed on a map and thus risk breaking the FollowsID logic for trains.
- The Deployer weapon only makes the AI’s BLDCNSTUs automatically deploy and doesn’t affect those that belong to the human players.
- All BLDCNSTUs are set to the Unload state, which causes the ones owned by human players to automatically deploy, but doesn’t affect those belonging to AI players.
This concludes the first and most important part of the tutorial. As you might have guessed, it is necessary to always play with Short Game disabled now (which can also be disabled permanently by editing Resources\GameOptions.ini), but if you want to put in the extra work it’s perfectly doable to get Short Game working again.
Part 2: Getting Short Game to work again
When the Short Game option is enabled, it makes players instantly die when they own no structures or no BaseUnit and considering that after having applied the above work-around players no longer start with a BaseUnit, they now always instantly die when the game starts.
So how do we get around this? By making players start with a BaseUnit of course.
First we’ll have to add the code for this BaseUnit in Rules.ini (for convenience the ID will be BASEUNIT):
Code:
[BASEUNIT]
Image=
Strength=1
Immune=yes
LegalTarget=no
SpeedType=Amphibious
Locomotor={4A582741-9839-11d1-B709-00A024DDAFD1}
Selectable=false
Image=
Strength=1
Immune=yes
LegalTarget=no
SpeedType=Amphibious
Locomotor={4A582741-9839-11d1-B709-00A024DDAFD1}
Selectable=false
Now open INI\Map Code\GlobalCode.ini and add the following code:
Code:
[Events]
BaseUnit=1,13,0,125
[Actions]
BaseUnit=1,32,0,0,0,0,0,0,A
[Triggers]
BaseUnit=Neutral,<none>,Destroy BaseUnit,0,1,1,1,0
[Tags]
BaseUnitTag=0,Destroy BaseUnit 1,BaseUnit
[Units]
FFK=Spawn1,BASEUNIT,256,0,2,64,Guard,BaseUnitTag,0,-1,0,-1,1,0
FFL=Spawn2,BASEUNIT,256,1,2,64,Guard,BaseUnitTag,0,-1,0,-1,1,0
FFM=Spawn3,BASEUNIT,256,2,2,64,Guard,BaseUnitTag,0,-1,0,-1,1,0
FFN=Spawn4,BASEUNIT,256,3,2,64,Guard,BaseUnitTag,0,-1,0,-1,1,0
FFO=Spawn5,BASEUNIT,256,4,2,64,Guard,BaseUnitTag,0,-1,0,-1,1,0
FFP=Spawn6,BASEUNIT,256,5,2,64,Guard,BaseUnitTag,0,-1,0,-1,1,0
FFQ=Spawn7,BASEUNIT,256,6,2,64,Guard,BaseUnitTag,0,-1,0,-1,1,0
FFR=Spawn8,BASEUNIT,256,7,2,64,Guard,BaseUnitTag,0,-1,0,-1,1,0
BaseUnit=1,13,0,125
[Actions]
BaseUnit=1,32,0,0,0,0,0,0,A
[Triggers]
BaseUnit=Neutral,<none>,Destroy BaseUnit,0,1,1,1,0
[Tags]
BaseUnitTag=0,Destroy BaseUnit 1,BaseUnit
[Units]
FFK=Spawn1,BASEUNIT,256,0,2,64,Guard,BaseUnitTag,0,-1,0,-1,1,0
FFL=Spawn2,BASEUNIT,256,1,2,64,Guard,BaseUnitTag,0,-1,0,-1,1,0
FFM=Spawn3,BASEUNIT,256,2,2,64,Guard,BaseUnitTag,0,-1,0,-1,1,0
FFN=Spawn4,BASEUNIT,256,3,2,64,Guard,BaseUnitTag,0,-1,0,-1,1,0
FFO=Spawn5,BASEUNIT,256,4,2,64,Guard,BaseUnitTag,0,-1,0,-1,1,0
FFP=Spawn6,BASEUNIT,256,5,2,64,Guard,BaseUnitTag,0,-1,0,-1,1,0
FFQ=Spawn7,BASEUNIT,256,6,2,64,Guard,BaseUnitTag,0,-1,0,-1,1,0
FFR=Spawn8,BASEUNIT,256,7,2,64,Guard,BaseUnitTag,0,-1,0,-1,1,0
Make sure that you don’t overwrite the [Units] section that you added in Part 1 of this tutorial.
You can optionally change the time before the BaseUnit disappears and Short Game is activated by editing the line under [Events] and change 125 to whatever you like (125 translates to about 2 minutes with the game speed at 60 FPS).
And that’s all it takes to get Short Game working again. First of all the code above pre-places an invulnerable BaseUnit on maps when the game starts and it has a trigger attached to it to make it automatically disappear again after about 2 minutes. This means that players have 2 minutes to deploy their MCV before Short Game activates and after those 2 minutes they’ll instantly die when they have no structures left. Keep in mind that players will also instantly die if they have no structures, but do have an MCV and there’s unfortunately no way to prevent this.
Part 3: Structure prerequisites and owners for 3+ factions
Because TS was only meant to support 2 factions, having 3 or more factions can be very problematic when it comes to prerequisites and messing with these can cause issues such as the infamous NCO (“No Construction Options”) bug, structures might not appear on the sidebar or the AI refuses to build them.
So to prevent these issues, you first need to know exactly what causes them.
- I mentioned before that structures that only have a single owner will only appear on the sidebar when a player owns the BuildConst structure: this is actually only half true. Structures with only one owner can only appear on the sidebar for the first two factions (GDI and Nod), while all other factions require structures to have 2 owners to make them appear on the sidebar.
- Structures with more than a single owner will appear on the sidebar for every single faction (regardless of which owners are specified), unless the structure’s prerequisites prevent this.
- Any structure (or unit) that’s visible on the sidebar for a faction that’s not specified as the owner will cause the NCO bug for that faction.
- The AI can’t build any structures that have the Construction Yard specified as a prerequisite.
So since structures with only a single owner only appear on the sidebar for the first two factions, there’s no way around having to specify a secondary owner (such as Civilian) for every single structure of at the very least the new factions (but you’re actually best off doing this for as many factions as possible). So in GDI’s case you’d specify Owner=GDI,Civilian for every single structure for example.
Once you’ve done this, you’ll have to prevent these structures from appearing on the sidebar of all factions by specifying the Construction Yard as a prerequisite for all of them and keep in mind that it’s only possible for two factions to share the same structure if you modify one of the prerequisite categories (such as for example PrerequisiteBarracks=) and make it include the Construction Yards of both factions.
That said however, you might not have enough prerequisite categories available for everything you want to do, because (as explained below) you’ll also need them to make the AI able to build anything. You’ll have to plan how you’re going to use the prerequisite categories very carefully and since PrerequisiteGDIFactory= and PrerequisiteNodFactory= can only be used by vehicles, you actually only have 5 of them available.
As mentioned before, the AI can’t build anything that has a Construction Yard specified as a prerequisite, but you’re still forced to do so. So to make the AI able to build these structures again, you’ll have to make use of the prerequisite categories.
First add a new structure that will serve as a dummy for the AI to use as a prerequisite instead of a Construction Yard. This structure can be anything and look like anything, so you could for example simply make it look like a power plant, make it into an upgrade for the Construction Yard or whatever else you can think of.
All factions can share the same dummy structure (if it’s not an upgrade) or they can have a unique structure, just make sure that only the AI can build it: give it TechLevel=-1. While this tech level prevents human players from building a structure (or unit), it instead allows the AI to build it on every single tech level.
Now that that’s done you’ll have to use prerequisite group for every single faction uses a Construction Yard as a prerequisite for its structures and then specify the prerequisite group instead of the Construction Yard.
For example use: PrerequisiteBarracks=GACNST,AIDUMMY1 and then specify Prerequisite=BARRACKS,GAWEAP,GARADR for GDI’s tech center.
AIDUMMY1 here is whatever structure you’re using as the dummy structure for the AI (as mentioned before, it can be whatever you want, as long as only the AI can build it). To make sure that the AI can properly use every prerequisite group, you need to make sure that the matching BuildXXX key (for PrerequisiteBarracks that’s BuildBarracks for example) includes a structure that doesn't have a prerequisite (the easiest option here is to just use the AI dummy structure, but you can for example also use a power plant).
And that that should be all. Let me know if you run into any difficulties or if I missed something.
There’s no part 4, but if you also need a method to make the AI replace its MCVs, you can use SuperJoe’s method, starting from:
SuperJoe wrote:
And as promised here are instructions on how to make AI replace lost con.yards. It's actually more effective than what the original game uses.
I believe that you do need to give the MCVs Secondary=DeployWeapon to make this work (the code for that is posted in that topic as well).