Effect System

AIAndy

Deity
Joined
Jun 8, 2011
Messages
3,428
I don't like how there is currently so much duplication between tags. Like for everything that a tag might change on a city, there is one tag on a building, the same on a trait and a civic.

The software architecture also splits that code in a hard coded way to many different functions where it is mixed in between a lot of other information (and as a result we have some large monster classes).

What I would like to introduce to change that is the Effect System. An effect is a class that inherits from an abstract base class a specific interface which includes virtual functions that are called when the effect begins, when the effect ends and one that is called once per turn. Also functions for reading its parameters from XML and both writing and reading to streams for savegame and cache. Finally a display function that generates info text about the effect and an AI value function (there might be more, tbd).
An effect specifies what kind of game object it applies to. So an effect might apply to cities which means that if the XML adds that effect to a trait, then all the cities of that player will get the effect.

Each effect class registers a singleton factory class for itself at a central registration with a tag name associated and gets an ID assigned that way (which is used for storing it in streams and remapping savegames).
All tags in XML info classes that support the effect system will be scanned if they fit to any of the registered effects and if they do the effect XML will be read and an instance of the effect class added to an array in the info class.

Application of an effect to a game object (e.g. a city) can be one time (just do something the moment it is applied), temporary (a certain number of turns) or bound to how long the game object modifier (e.g. a building) the effect was defined on is active.

This is only a concept at the moment. No code has been written yet.
What do you think?
Would you help with the implementation of the system, use it to implement effects or use it in XML?
 
I believe I get what you're saying, for the most part. It sounds rather interesting yes. I think we could benefit from some examples of application perhaps.
 
I like the idea, but it will run into a lot of problems when we get around to telling people that dozens of tags that they just implemented need to be junked. I would be fully willing to help develop this, and hope that it can be designed and made in a public process which everyone can contribute to, instead of some projects which are developed in secret with no input at all.

In terms of the specific ideas presented, here are a couple of my thoughts.

  • Time durations should be based on Gamespeed by default for the '# of turns' option. Since most effects would require that anyways it would make sense to only have to declare that it won't be using gamespeed scaling.
  • This is more of an external exposure type of issue, but I'd like it if the Effect system could be accessable from the Globals, with some sort of function like getEffects(someGameObject GameObject), which returns an array of effect objects on that gameobject, with overloads for each type of gameobject we intend for this to be applicable to (like units, buildings, etc).
 
I believe I get what you're saying, for the most part. It sounds rather interesting yes. I think we could benefit from some examples of application perhaps.
Currently when you want to add a tag to buildings for instance you have to add some code to CvBuildingInfo in multiple methods, then add something to several CvCity methods to get some effect and so on. So the actual implementation of the tag is spread to many files and still the new tag will only work for buildings now.
With the effect system you would add a new effect class instead for the tag in a new file. All the implementation of the tag would be concentrated in that file (although new mechanics might still need changes to other files). The new tag would now also be available for usage in traits, techs, civics and the like, not only buildings without any duplication of code or extra implementation effort.

I like the idea, but it will run into a lot of problems when we get around to telling people that dozens of tags that they just implemented need to be junked. I would be fully willing to help develop this, and hope that it can be designed and made in a public process which everyone can contribute to, instead of some projects which are developed in secret with no input at all.

In terms of the specific ideas presented, here are a couple of my thoughts.

  • Time durations should be based on Gamespeed by default for the '# of turns' option. Since most effects would require that anyways it would make sense to only have to declare that it won't be using gamespeed scaling.
  • This is more of an external exposure type of issue, but I'd like it if the Effect system could be accessable from the Globals, with some sort of function like getEffects(someGameObject GameObject), which returns an array of effect objects on that gameobject, with overloads for each type of gameobject we intend for this to be applicable to (like units, buildings, etc).
The XML based scaling I added some time ago should serve well for the duration of temporary effects.
Similar to what is there now CvGameObject will get foreachEffect and enumerateEffect methods. The effect system will heavily rely on the game object abstraction anyway where useful.
 
The XML based scaling I added some time ago should serve well for the duration of temporary effects.
Similar to what is there now CvGameObject will get foreachEffect and enumerateEffect methods. The effect system will heavily rely on the game object abstraction anyway where useful.

OK, that sounds good. We'll probably also have to make an additional abstraction effect which contains the sum total of all individual effects on a game object, so that you can quickly access those values.
 
Back
Top Bottom