Tips on changing existing gameplay
Posted: Tue Feb 09, 2016 5:45 pm
There seems to be good progress being made with adding new stuff to the game, like flags, tattoos, etc, but a recurring question I'm seeing is "how do I change XXX in the game?", which is a different sort of question.
In the old EU/EW days, we'd simply hack into the hex and make the change directly to the XComGame.upk. However, given how amazingly popular (/s) that was, I don't think we'll be going to that as the default method for XCOM 2. ^_^
I'll list below the tools I've found for changing existing gameplay, in rough order of increasing complexity. As others get found/added, I'll try and keep the list updated.
----------------------
1) Configuration files
Config files are those files that end in *.ini. If the thing you want to change has a configuration variable that controls it, you're in luck! These are the easiest things of all to change.
To change your own game, you can directly edit the "Default" version of the config file in the XComGame/Config/ folder, but be warned that updates from Firaxis may well overwrite your changes.
To make a mod that applies config changes, create a mod with the SDK, and create a new file in the Config folder, named the same as the file you want to change, but with the "Default" prefix changed to "XCom", then use this info (https://udn.epicgames.com/Three/ConfigurationFiles.html) to control adding and removing lines during merge with the Default version.
--------------------
2) Kismet files
If the thing you want to change is handled in Kismet (e.g. Mission timers), then you can find the appropriate *.umap file with the Kismet, make your changes, then add the modified version to your mod project's Content folder, and the mod version will override the one in the game.
Pretty simple, but not quite as easy as config files
---------------
3) Class overrides
If you've gotten down here, the easy times are over. This requires some programming abilities.
XCOM 2 allows overriding classes when they are created at run-time using new or Spawn. (New is for things derived from Object, Spawn for things derived from Actor). This leaves out a few things, such as archetypes and game states, so it won't work for everything.
To override a class, add the following to an XComEngine.ini config file in your mod:The mod class needs to extend the original base game class, using standard OOP inheritence techniques.
I've listed this at #3 in difficulty, since it's not too hard, but it's not good for mod compatibility, since only one mod can overwrite a particular class. Since the overrides are in a dynamic array, I'm supposing that it's the first one in the array that the native override code handles, so it's whatever mod that gets loaded first that succeeds at the class override.
------------------
4) UIScreenListener
Despite the name UIScreenListeners can be used for more than just making UI changes. UIScreenListener is a class implemented by Firaxis, which you can create a child class of. The UIScreenListener gets assigned a UIScreen in default properties that determines when the listener is called. If you leave that at none, it will be invoked for every UIScreen.
A good example of how to use this is the base game UIStrategyScreenListener. As in that example, you can simply drop some code into the OnInit() event and it will run at least once, and in fact will run whenever a new UIScreen is created, so it's a bit like polling, but controlled by the rate of user UI navigation.
------------------
5) X2EventManager events
Next up is using an event that's already triggered. EventIDs are names, and events are triggered with code that looks like :
`X2EVENTMRG.TriggerEvent('UnitMoveFinished', UnitState, UnitState, NewGameState);
The primary restriction here is that if the function you want to hook into doesn't have a TriggerEvent, there's not much you can do about that. We're limited by the number of TriggerEvent calls added to the base game code.
The other tricky bit here is that you have to have something already created to listen to the event. I generally use either a class override or a UIScreenListener to initially instance a game state, but this can also be put into template delegate code (effects, abilities, etc). Once you have that, you can register to listen to the event with code like :
You'll going to want to have your EventListener handler in a gamestate. Gamestates are automatically serialized/deserialized when saving/loading, and as a bonus any registered events are also handled.
-------------------------
6) Total Replacement
This is the end of the line. You couldn't do anything else, so now you have to compile the entire XComGame.upk and replace the whole thing.
If you start a DefaultMod, all of the XComGame class files get copied into your mod, so you can just edit them there. When you build, you'll get a new XComGame.u. Unfortunately, that's not the final step, as that has to go through cooking before it can be used in a mod. Cooking isn't part of the regular build process, because it takes a long time. There is a way to run the game uncooked, but that's going to be mostly for development (performance is much worse, and it's really tough to distribute).
The really major downside of total replacement is that only one mod can do it.
For those of you who want to see how to run uncooked, I'll include the info in spoiler below:
In the old EU/EW days, we'd simply hack into the hex and make the change directly to the XComGame.upk. However, given how amazingly popular (/s) that was, I don't think we'll be going to that as the default method for XCOM 2. ^_^
I'll list below the tools I've found for changing existing gameplay, in rough order of increasing complexity. As others get found/added, I'll try and keep the list updated.
----------------------
1) Configuration files
Config files are those files that end in *.ini. If the thing you want to change has a configuration variable that controls it, you're in luck! These are the easiest things of all to change.
To change your own game, you can directly edit the "Default" version of the config file in the XComGame/Config/ folder, but be warned that updates from Firaxis may well overwrite your changes.
To make a mod that applies config changes, create a mod with the SDK, and create a new file in the Config folder, named the same as the file you want to change, but with the "Default" prefix changed to "XCom", then use this info (https://udn.epicgames.com/Three/ConfigurationFiles.html) to control adding and removing lines during merge with the Default version.
--------------------
2) Kismet files
If the thing you want to change is handled in Kismet (e.g. Mission timers), then you can find the appropriate *.umap file with the Kismet, make your changes, then add the modified version to your mod project's Content folder, and the mod version will override the one in the game.
Pretty simple, but not quite as easy as config files
---------------
3) Class overrides
If you've gotten down here, the easy times are over. This requires some programming abilities.
XCOM 2 allows overriding classes when they are created at run-time using new or Spawn. (New is for things derived from Object, Spawn for things derived from Actor). This leaves out a few things, such as archetypes and game states, so it won't work for everything.
To override a class, add the following to an XComEngine.ini config file in your mod:
Code: Select all
[Engine.Engine]
+ModClassOverrides=(BaseGameClass="ABaseClassName", ModClass="YourModClassName")
I've listed this at #3 in difficulty, since it's not too hard, but it's not good for mod compatibility, since only one mod can overwrite a particular class. Since the overrides are in a dynamic array, I'm supposing that it's the first one in the array that the native override code handles, so it's whatever mod that gets loaded first that succeeds at the class override.
------------------
4) UIScreenListener
Despite the name UIScreenListeners can be used for more than just making UI changes. UIScreenListener is a class implemented by Firaxis, which you can create a child class of. The UIScreenListener gets assigned a UIScreen in default properties that determines when the listener is called. If you leave that at none, it will be invoked for every UIScreen.
A good example of how to use this is the base game UIStrategyScreenListener. As in that example, you can simply drop some code into the OnInit() event and it will run at least once, and in fact will run whenever a new UIScreen is created, so it's a bit like polling, but controlled by the rate of user UI navigation.
------------------
5) X2EventManager events
Next up is using an event that's already triggered. EventIDs are names, and events are triggered with code that looks like :
`X2EVENTMRG.TriggerEvent('UnitMoveFinished', UnitState, UnitState, NewGameState);
The primary restriction here is that if the function you want to hook into doesn't have a TriggerEvent, there's not much you can do about that. We're limited by the number of TriggerEvent calls added to the base game code.
The other tricky bit here is that you have to have something already created to listen to the event. I generally use either a class override or a UIScreenListener to initially instance a game state, but this can also be put into template delegate code (effects, abilities, etc). Once you have that, you can register to listen to the event with code like :
Code: Select all
local Object ThisObj;
ThisObj = self;
`X2EVENTMGR.RegisterForEvent(ThisObj, 'UnitMoveFinished', OnUnitMoveFinished);
function EventListenerReturn OnUnitMoveFinished(Object EventData, Object EventSource, XComGameState GameState, Name EventID)
{
// YOUR CODE GOES HERE
return ELR_NoInterrupt;
}
-------------------------
6) Total Replacement
This is the end of the line. You couldn't do anything else, so now you have to compile the entire XComGame.upk and replace the whole thing.
If you start a DefaultMod, all of the XComGame class files get copied into your mod, so you can just edit them there. When you build, you'll get a new XComGame.u. Unfortunately, that's not the final step, as that has to go through cooking before it can be used in a mod. Cooking isn't part of the regular build process, because it takes a long time. There is a way to run the game uncooked, but that's going to be mostly for development (performance is much worse, and it's really tough to distribute).
The really major downside of total replacement is that only one mod can do it.
For those of you who want to see how to run uncooked, I'll include the info in spoiler below:
- Spoiler: show