Jump to content

"What am I working on" Showcase


Deleted32045420User

Recommended Posts

Well since this thread is getting going, I might as well contribute to what I've been working on.

I've been working on a highlander mod that aims to fix issues with the vanilla game, change some mechanics, and make it easier for mods to work.

 

https://www.dropbox.com/s/2519oe5jlu5y6uh/mcm-implementation-20160428.png?dl=0

 

For example, davidallen just recently posted a guide to creating mission narratives in custom maps ( http://forums.nexusmods.com/index.php?/topic/4057890-guide-creating-narrative-moments/ ). I've done this before while working on another mod (that I have kind of put aside for the time being to work on this core mod). One thing that severely bugged me about narrative moments, was that while you can change the objective text pools whenever you want just by modifying the localization int file, you have to recompile UnrealScript code in order to change the narrative moment audio references.

That didn't make any sense to me, so I changed the (normally native) X2MissionNarrativeTemplate class to load narrative moments from the localized int file, so that you can change the audio references without needing to recompile any code. Of course you still can do so, it's just an added option in this core mod because I was sick of having to recompile in order to test a new audio file.

Here's a list of all the modifications that are included so far, in order that I have them in my notes document for my own simplicity:


1. Enhance XCOM Spawn Distance Algorithms

The game's spawn point generation basically forces XCOM to spawn far away from the objective. There's no real easy way to make a new mission type that spawns XCOM near the objective, at least not without editing map files. And for a mod that I'm making, I just want to be able to re-use a bunch of vanilla maps without have to edit literally every single one in order to make the mission type that I want.

Basically, it's going to be a Defend Device replacement for the current Protect Device mission types, where XCOM spawns with the objective, and must defend it against waves of enemies. Kinda like the Avenger Defense mission. I want to do this because the current Protect Device mission can be kinda bulls***, and a proper defense mission is a nice change of pace from yet-another-timed-mission (YATM).

But I couldn't figure out a way of easily doing it! The mission schedules can define a minimum range at which XCOM is allowed to spawn, but there is no way to define a maximum range away from the objective that XCOM is allowed to spawn. And even if there was, spawn restrictors (I think also called falcons in the game code) basically force XCOM to spawn away from the objective. AND STILL, even if you somehow got around those restrictions, alien spawn pod locations are tied to the objective location, and if they try to spawn too close to XCOM's spawn location, they literally will just not spawn on the mission.

So I made a bunch of changes to the spawn selection algorithms. You can specify that XCOM spawns near the objective, that aliens spawn away from it. It's completely optional for other mods to use, and the vanilla algorithm is perfectly intact for the vanilla mission schedules. But its purpose is to give other mods more leeway in how the missions generation algorithms act in the code.


2. Localized X2MissionNarrativeTemplate

As mentioned above. This template has ObjectiveTextPools localized and loading from the localization int file by default, but not the NarrativeMoments. I've modified it so that a mod can (optionally) specify the NarrativeMoments in the int file, allowing them to change audio based on language or at the very least, change their audio without recompiling code.

(There is no 3, it has been removed for now.)

 

4. Change Critical Hit Chance Algorithms

Critical hit chance in XCOM2 is awful. If you have a 50% chance to hit, and a 50% chance to crit a target, then in the vanilla algorithms, your shot will miss 50% of the time, land a critical 50% of the time, and land a non-critical 0% of the time. If this was Enemy Within, then you would miss 50% of the time, land a critical 25% of the time, and land a non-critical 25% of the time.

This is why people may sometimes say that flashbangs in XCOM2 are broken, or don't work. That's because the algorithms currently suck! If you flash a target, you may reduce the chance of the landing a shot. But they are technically more likely to land a critical hit if they land a shot at all!

And so, I've changed the algorithms so that this doesn't happen! The % chance to crit transforms a normal shot into a crit, it doesn't override the value anymore.

I've also added in an option to re-enable dodging on 100% chance to hit shots. Just to make the game harder. And I didn't agree with them removing that, doesn't make sense that dodging can go from, what? 33% at 99% chance to hit, to 0% at 100% chance to hit? No thanks.


5. Stop My2K Startup Popup

I've added in a bit of code to stop the default My2K EULA popup. If you interact with My2K at all, this is overridden. And it only stops the popup the first time it occurs. Needs testing with an actual connected My2K account, I've never used it and I just find the popup annoying. There's even a comment in the official game code:

// TODO: Perhaps save this preference in the profile so they don't have to decline every time? @ttalley


6. Show Perks

There's already a mod for this, but it's just a few lines of code to change it, so I figured it out and coded it in. Just show the soldier abilities and psi abilities trees, since if you've played the game once already you know what all the skills are.


7. See Through Ladders

I've run in to this situation several times. You blow up the cover of an enemy near a ladder (grenade or stray missed shot or Demolition ability) and all of a sudden you lose line of sight to the target. Because the wall is gone and there was a ladder against the wall, the target doesn't "lean" around the corner, and since the ladder blocks line of sight you can't see the target. This has actually cost me soldiers in the past, and is incredibly annoying.

So I've added in some code to the map generation that, before finalizing the loading process, iterates over ladders in the world map and makes them no longer block line of sight. It's totally configurable, so if someone makes a map and doesn't want line of sight to be blocked, they can just not include that instance name in the configuration file for it.


8. Grant AWC Retroactive Over Time

I never did like how you can "miss out" on AWC abilities on soldiers by not building the AWC early enough in your campaign. And I also don't like that the True Retroactive AWC Mod or whatever it's called, just instantly gives you a bunch of AWC abilities on your soldiers. It feels "too easy".

So I've made an addition to my mod that allows you to gain AWC abilities on soldiers that would normally not be able to unlock their ability, through one of two ways. The first is to just use the AWC respec ability, that will allow you to unlock their ability, but ONLY if they can't get it through rank-ups normally. The second is to just take soldiers out on missions. If the mission is a succes, and they get a kill, and are not wounded or shaken, then their AWC ability's hidden rank gets incremented by one, until it is unlocked. So, you can just play normally and, if you play well, you'll get AWC abilities unlocked through your normal play.


9. Mod Override Analysis

One thing that I'm trying to work on currently, is a system for scanning for conflicting mods and present that information to the player when the game states. Unfortunately there doesn't seem to be any way to see what individual functions are overridden, you can only get as granular as the class itself. But maybe if Firaxis adds in some sort of native reflection function or something we can get per-function granularity. But at least it will allow people to know what mods are conflicting.


10. Hide Main Menu Soldier In Options Menus

Something I've included in the mod (and can give the code to MCM if they want it) is a fix for the main menu soldier clipping over the options when he has a big gun. If he's carrying a Cannon or Sniper Rifle, it can be impossible to read or click on options in the menus (especially if you have a lot of options in the MCM menu like I do).

So, I just have an option that hides the soldier temporarily while the menu is open. He comes back when you leave the options menu. Simple.


11. Skulljacking Tweaks

Still slightly in progress, but it works so far. I had a mission recently where I hacked an Advent Tower and gained control of a random enemy unit. I tried to skullmine him to kill him, and realized that I couldn't actually target him! The game doesn't have the code built-in to allow you to target a mind-controlled enemy unit. I realized that this should be possible, but also that it should be possible to get a bonus to chance-to-hit and hack-defense against a mind-controlled unit.

The reason for this is simple from a realistic and game mechanic perspective: Realistically, if you've mind controlled a unit, it's easy for one of your soldiers to walk up to the (former) enemy, try to give him a hug, and jam a holo-dagger in to his chin. But even from a game mechanic perspective, it encourages late game players to mind control lowly Advent troopers instead of Archons, Andromedons, etc. You *can* mind control a super unit, or you can mind control a crappy trooper to get a bonus to your hacking chances.

I then thought about expanding this process further. I never really liked the idea that you could just Skullmine an enemy at max HP and kill him in 1 hit. So, I've also added in an option to grant a bonus to hacking if the target is wounded (along with a static increase in difficulty to offset this). Basically, like Enemy Within, you need to reduce the target to low HP in order to have better-than-even odds of a successful Skullmine. This changes the tactics around Skullmining, as you have to plan more carefully how you Skullmine, instead of just use it to kill an enemy with one unit's action.


12. Mimic Beacon Tweaks

Currently the only tweak in this section is to fix the issue with mimic beacons that "expire" still taking up a tile location. Mimic beacons that are killed are properly removed, as they have a 'UnitDied' event that triggers clean up code. But a mimic beacon that survives a turn and expires on the beginning of XCOM's turn isn't properly cleaned up.


There's some other things that I've been implementing:

Everything that I mentioned above is toggleable in the options menu (which I am using MCM for). Don't want to play with an option enabled? Just switch it off.

All options are saved to the user's config folder, so that they are saved between games. These options are also upgradeable when the mod itself is updated. It will load the previous config version, upgrade it, then save it again. So if options are added or removed between mod versions, the config file will reflect that.

More events. I'm going through right now actually, removing custom code from the vanilla classes and replacing it with new events where possible. You may have seen that "Help with Event Manager" thread I made earlier. Took forever, but I finally figured out why my events were being removed and how best to register for events.

Making some things not private. If I need access to a method, function, or variable that's private to a class, I can just make it not private. Since it's a highlander mod, modding the core packages to make them more accessible is relatively trivial.

More functions. For example, there currently exists one function in the XComPresentationLayerBase that allows you to spawn a UIScreen by just it's name. I don't know why there isn't one that lets you spawn a UIScreen by it's class reference, so I added in a function to do that. Just makes sense to me, because you get extra compile-time type checking and protection.


This all started as a sort of personal project, but I've been thinking more and more that some of this stuff just makes sense. The code that makes my modding easier is pretty generalized, other mods could benefit from it. You could say that it's a potential start to a community mod project, if people like it, agree with design decisions, etc.

Edited by abeclancy
Link to comment
Share on other sites

5. Stop My2K Startup Popup

 

Although, there's this little workaround solution created by Drakous79 (( https://www.nexusmods.com/xcom2/mods/486/? )) that does the same via some PatcherGUI tweaks -- and more with the bottom Message-of-the-Day Ticker splash line. Both of which i can't do without anymore! ;)

Link to comment
Share on other sites

@Zyxpsilon

Yeah, quite likely that some of this stuff was done before. That's fine though! Looking at his stuff, first of all it seems like PatcherGUI would be difficult to integrate to the Steam Workshop (something that I would like to do eventually, if Firaxis ever figures out a way to allow loading of core mods through Workshop). But also, his mod and mine do different things.

 

His permanently hides the My2K button from the screen and the MOTD banner. The button on the main menu being removed to me seems a bit harsh, it's not like it's hard to ignore. And the MOTD banner... well, I've never connected to a My2K account, so I've never seen it before! My modification makes the EULA popup (that occurs every time you start the game and don't connect to My2K) not appear, taking over the screen no matter what you are doing.

 

And in fact, I have a suspicion that some of the game hangs that occur during loading are related to this My2K EULA popup. If I start the game, wait, dismiss the two popups, then load a save, it works fine. If I start the game, and quickly load a save before the popups appear, they still "appear" in the background, and I give the game worse than even odds of hanging during the loading process. Don't know if everyone shares that experience, but it just seems very annoying.

 

@davidallen

It looks like it's just an external launcher that analyzes the mod packages and informs the user. Doesn't look like it's a solution accessible from inside the unrealscript code itself. My own attempts are mainly focused on information gathering and testing right now.

 

But you know, thinking about it, right now all of the code that I'm using is just a part of the core XComGame package. Had to be a long time ago before I found a nice way to permanently keep an object instance in memory.

 

I could go through everything, and split it apart in to a separate package that contains all the non-native class modifications, and leave only the native modifications in the XComGame package. But the problem in my head I have with that, is it means that no other mods would be able to modify those classes. If I put all modifications in the XComGame package, then I can always analyze the class overrides, see "oh hey, UIArmory_Promotion has been overridden", and just internally disable whatever code I have that shows all perks, because who cares, the other mod might NEED that class override in order to function, and the player might WANT that mod to function correctly. They installed it, after all.

 

But lets say that I add in 100 new events throughout the various vanilla classes. These events are added to both native classes and non-native classes. If I put these modifications in to a separate package, then no other mod can override those classes. But if I put those modifications in to the base XComGame package, then another mod might override the class and override the function. Events could become unusable due to this overriding.

 

It's a bit of a shitty situation, as far as I know no one has come up with anything that really "solves" the conflict problem. Especially with no function-level reflection. I've got 24 classes modified right now. I can bring that number down now that I've got a handle on the event manager's registration purging "feature". But do you know if anyone has really come up with a solution to "solve" the conflict problem? Do you have any ideas for what would make the best behavior from a core mod? Or is there no good way about it, other than letting an external mod launcher inform people of conflicts, and if they run in to issues with overrides it's their fault for installing conflicting mods? (serious question, no /s)

Edited by abeclancy
Link to comment
Share on other sites

The advantage of the alternate launcher is that it can do various cleanups, before the game is actually launched. It replaces the native launcher, which appears by default anyway, so it doesn't add any extra step. There are at least 3-4 mod conflicts with my mods reported on steam comments, where the debugging would have been much faster if the user had used that launcher and told me which class files were conflicting.

 

I agree that there are cases where two mods extend the same class, but it happens that the changes are nonoverlapping (I modify functions a,b,c and you modify functions d,e,f). However, the launcher randomly picks one, and as far as we can tell unrealscript doesn't provide a way to automatically union them. I know at least two cases where a new mod conflicted with a widely installed old mod, so the new mod author took the step of including the old mod into the new mod. Of course, only after obtaining, or making a reasonable effort to obtain, permission from the old mod author, and giving credit in the mod description.

 

The solution in those cases is for one, or both mod authors to use some other kind of hook to mod, instead of extending the class. I am sure a single platform highlander mod, with enough hooks, would solve this. But, the challenges are getting all the right hooks, and then convincing everybody with a mod to build on top of the platform.

Link to comment
Share on other sites

Yeah, and especially since right now, highlander+workshop don't mix, that's highly unlikely.

 

Kinda why I was thinking that I could include some override analysis code. If I modify functions d,e,f in the XComGame package (instead of a separate package), and you override a,b,c (in your own package), you (or I) could just include a bit of config that says:

 

+ModOverrideFunction(BaseClass="UIArmory_Promotion", ModClass="ALLEN_UIArmory_Promotion", Function="InitPromotion")

 

And use that information to make decisions on what features to enable, or if those functions are required for the core code inform the player of a conflict and shut down.

 

 

But there's also some interesting code in the event manager that I'm thinking in the back of my mind, that maybe we could use that to do some of this stuff. Because it's a C++ native implementation, it does some things that are abnormal for UnrealScript to do on its own. Namely, you give it an object and a function to use for the event callback, but the function doesn't HAVE to be a part of the object. The engine effectively tries to call "Object.Function()" for the callback, and the game crashes horrendously. But I can't help but wonder if maybe there is a way to abuse that, to allow for pseudo-anonymous classes, or coexisting mod class overrides, or something.

 

Someone more experienced with this stuff (UnrealScript especially) might have to figure it out though.

Link to comment
Share on other sites

Or, I should say, the problem is that the order of game loading was that the steam workshop API (and hence mods) would load after the game has initialized the list of installed mods, and that at this point it was "too late" to override a core package. I'll see if I can't get it working later today I suppose.

Link to comment
Share on other sites

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...