Jump to content

TUTORIAL : Using GameState Components


Amineri

Recommended Posts

  On 2/19/2016 at 8:58 PM, kosmo111 said:

Components are a way to add generic data to an object. It isn't strictly speaking an OOP design pattern. For example you might have a base Actor object. You could then add a DrawComponent and a MovementComponent to that Actor. The system could then, while drawing, look for all Actors that have a DrawComponent and give them a chance to draw. Then do the same for Movement.

 

Take a look at https://en.wikipedia.org/wiki/Entity_component_system for more information.

 

Ah, I see... Kind of. So basically "components" are objects within the class which can be added to and removed from at will? I'm familiar with the basic concept (now that I know what it's referring to, I studied programming in Bulgarian :)), and it sort of makes sense the way you describe it. The classes are designed to contain multiples of each other, to be used as necessary. Object-oriented programming at its finest and actually kind of a similar thing to what I teach in the university. Provided that's what it is and I don't just misunderstand.

Link to comment
Share on other sites

  • 2 weeks later...

Amineri, I need to ask for your help with this real stumper I've run into. I'm using the pattern you've described for creating new GameState component objects and attaching them to the effect's GameState, registering some event listeners and making 'interesting abilities'.

 

This method seems to work very well in action, but I'm having some really, really weird side-effects. Namely, hard CTDs from the game during transitions between the tactical and strategy games. Any time within the first mission or two following the soldier gaining that ability, the game gets into some state where a CTD is inevitable on transition, despite saving/loading the game, taking or not taking that particular soldier on the mission, winning or losing, the soldier living or dying, etc.

 

The only way to get past that transition screen is to then disable the mod, transition, and re-enable the mod. I can also comment out the whole "[Engine.ScriptPackages]" block to keep the scripts from loading entirely, and this also appears to stop the crash during the transition, but I can't find any sub-set of the scripts themselves to comment out to avoid the crash.

 

This was tested as the only mod loaded to reproduce the issue, and I can get it to occur reliably (although it's a somewhat lengthy process). The debug log is not very helpful, and I have no idea how to use the other files that get dumped into the Logs directory on crash.

 

The following are the code for an ability template, the effect it creates, and the gamestate object I use for dealing with callbacks. Can you see anything I'm doing wrong here?

 

Ability template:

 

  Reveal hidden contents

 

 

Effect:

 

  Reveal hidden contents

 

 

GameState:

 

  Reveal hidden contents

 

 

I should note that when I comment out the "meat" of the OnEffectAdded and OnEffectRemove methods so that the gamestate component object isn't created and the callbacks aren't registered prior to the soldier taking the ability the crashes do not occur afterwards (but of course, the ability doesn't do anything), so I'm fairly sure that the gamestate objects or callbacks are involved the situation.

Link to comment
Share on other sites

  On 2/29/2016 at 6:23 AM, davidlallen said:

Not sure why Amineri posted this in the general discussion forum, but she seems to describe exactly the same thing, and how to fix it:

http://forums.nexusmods.com/index.php?/topic/3853330-psa-you-have-to-garbage-collect-your-components-yourself/

 

Oh.... OH! That definitely seems related. I had thought I was removing all my state objects, but I can at least take another look to see if I'm missing something. Thank you for pointing Amineri's post out to me.

 

Edit: Looks like I was marking them for removal but maybe not submitting the new gamestate via the `GAMERULES/`HISTORY? That sound right, Amineri (if you wind up reading this?)

 

I'm trying to implement your clean-up stuff in the end of my method, but I'm probably doing it wrong because it's not working out yet.

 

Edit: Looking more into it, I shouldn't need to submit the new gametate myself as long as I remove the object from it, because it gets submitted up the stack at OnUnitRemovedFromPlay. So maybe back to square one: banging head on wall.

Edited by Lucubration
Link to comment
Share on other sites

Got it. Took too long, but I darned well got it.

 

OnEffectRemoved isn't always called at the end of a mission. If the unit extracts it is called, but on missions where the action just ends, effects aren't removed because the unit isn't "removed from play".

 

I had each event state additionally hook onto 'TacticalGameEnd' and clean itself up when tactical gameplay, well, ends. Everything is getting cleaned up as it should and I've made it through eight missions straight with no CTD on transition. Just going to thoroughly test the related skills' callbacks now.

Edited by Lucubration
Link to comment
Share on other sites

  On 2/29/2016 at 6:23 AM, davidlallen said:

Not sure why Amineri posted this in the general discussion forum, but she seems to describe exactly the same thing, and how to fix it:

http://forums.nexusmods.com/index.php?/topic/3853330-psa-you-have-to-garbage-collect-your-components-yourself/

 

Yes, posting it there was an embarrassing mistake ... :sweat:

Link to comment
Share on other sites

  On 2/29/2016 at 11:18 AM, Lucubration said:

Got it. Took too long, but I darned well got it.

 

OnEffectRemoved isn't always called at the end of a mission. If the unit extracts it is called, but on missions where the action just ends, effects aren't removed because the unit isn't "removed from play".

 

I had each event state additionally hook onto 'TacticalGameEnd' and clean itself up when tactical gameplay, well, ends. Everything is getting cleaned up as it should and I've made it through eight missions straight with no CTD on transition. Just going to thoroughly test the related skills' callbacks now.

 

Another method you can use to clean up after effect components is what we used for the effect components in officer pack. XComGameState_Effect is always cleaned up after a tactical mission because of its inclusion in TransientTacticalClasses. So, for OfficerPack, I've included an XComGame.ini config with the following :

[XComGame.XComGameInfo]
;Transient tactical classes specify objects that should be set as removed in the history upon leaving a tactical session
+TransientTacticalClassNames=XComGameState_Effect_FocusFire
+TransientTacticalClassNames=XComGameState_Effect_Scavenger
+TransientTacticalClassNames=XComGameState_Effect_Collector

If you look in DefaultGame.ini, you'll see that XComGameState_Effect is also on the list, which is units don't clean up after themselves post-mission.

 

For debugging purposes, I'd also added the XComGameState_Unit_LWOfficer component as a TransientTacticalClassNames object, and this prevented the CTD on switch from tactical to strategy maps, which indicated the same root cause.

Link to comment
Share on other sites

  On 2/29/2016 at 4:48 PM, Amineri said:

 

  On 2/29/2016 at 11:18 AM, Lucubration said:

Got it. Took too long, but I darned well got it.

 

OnEffectRemoved isn't always called at the end of a mission. If the unit extracts it is called, but on missions where the action just ends, effects aren't removed because the unit isn't "removed from play".

 

I had each event state additionally hook onto 'TacticalGameEnd' and clean itself up when tactical gameplay, well, ends. Everything is getting cleaned up as it should and I've made it through eight missions straight with no CTD on transition. Just going to thoroughly test the related skills' callbacks now.

 

Another method you can use to clean up after effect components is what we used for the effect components in officer pack. XComGameState_Effect is always cleaned up after a tactical mission because of its inclusion in TransientTacticalClasses. So, for OfficerPack, I've included an XComGame.ini config with the following :

[XComGame.XComGameInfo]
;Transient tactical classes specify objects that should be set as removed in the history upon leaving a tactical session
+TransientTacticalClassNames=XComGameState_Effect_FocusFire
+TransientTacticalClassNames=XComGameState_Effect_Scavenger
+TransientTacticalClassNames=XComGameState_Effect_Collector

If you look in DefaultGame.ini, you'll see that XComGameState_Effect is also on the list, which is units don't clean up after themselves post-mission.

 

For debugging purposes, I'd also added the XComGameState_Unit_LWOfficer component as a TransientTacticalClassNames object, and this prevented the CTD on switch from tactical to strategy maps, which indicated the same root cause.

 

 

Ah, that helps makes sense of why cleaning up effect state is handled so inconsistently in script. While I think I've got it nailed with the explicit removal for now, I may as well also add those to the next release "just in case", since I'm not persisting any of that outside of tactical. Thanks once again.

Link to comment
Share on other sites

  • Recently Browsing   0 members

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