tuomount / Open-Realms-of-Stars

4X Strategy game
GNU General Public License v2.0
131 stars 32 forks source link

Design Proposal - Race Traits #673

Closed BottledByte closed 3 months ago

BottledByte commented 7 months ago

Races could be described by traits, both physical and mental. Such change would allow behavior (code) reuse, as any race with specified traits (or lack of traits) can be controlled by single code, which then does not have to be updated for each race. Such design can also be easily moved to data files (as per GH-666).

RaceTrait could work as a flag with extra information, like description and list of related traits (conflicting and/or required). It should NOT be implemented as enum, however, because that would harm future extensibility and data-driven benefits.

Race trait system has following benefits over current design:

  1. Code reuse - Trait can define behavior, not only race itself.
  2. Easier content addition - Race is composed from traits, meaning less code has to be written or examined when doing changes.
  3. Data-driven design - Since traits are data, this data can be de/serialized and tweaked without modifying code.
  4. Trait dependencies - Some traits might require absence or presence of other traits to be applicable.
  5. Trait scoring/type - Traits can have types like "good", "bad", "neutral", etc. and/or numeric scoring of how "good" they are. This can be reused by AI or in content generation.
  6. Better visualization - Allows distinctive visualization in GUI, making it more "rich" and/or informative.
  7. Opportunity for user-made-content - Players could theoretically compose a race from traits, creating new unique races, and thus play-styles, or customizing races for their play-style.
  8. Opportunity for content procedural generation - Race could be composed from traits even at runtime, by the game, creating new unique races/games.

Programmer Point of View

As a programmer, I hate duplicate, incomprehensible code, with many hard-to-track edge cases. Racial traits promote code reuse, (slightly) improve encapsulation and allow me to create new races using composition, reducing cognitive overhead and making my work way easier.

Player Point of View

As a player, I want 4X strategy game with a lot of content and replayability. Racial traits offer this to me, as I could experience more unique games and even customize the game more.

I also like to clearly see what each game aspect/feature/entity does. Race traits clearly describe the race's abilities, maybe even graphically (like with icons), so I am informed adequately.


Notes

The content generation opportunities are just opportunities such redesign offers. There is no need to use those newfound abilities in game design.

I however highly recommend using those opportunities in game design, since it would bring massive amount of value to the player.

During designing and prototyping this, I also discovered several logical inconsistencies and probably bugs in game code regarding races and their "traits" (which are not a thing now). I will add partial enumeration of such issues with explanations and other insights in next post.

Summary

Adding and using race trait system is the first step of limiting impact of SpaceRace enum, making it easier to be eventually de-hardcoded as part of GH-666, while adding opportunities for content-generation and moddability, as well as fixing and preventing future bugs due to ad-hoc copy-paste and having to tweak tens of lines of code with addition of a race. It will also remove ambiguity of race-related code.

I have changes implementing the core of this ready, awaiting review and merge of my refactors as I depend on them. :+1:

BottledByte commented 7 months ago

Recognized inconsistency 1

It seems that Lithovoric Leaders may gain Agricultural Perk, but Mechion leaders cannot. Neither of those races eats organic food. So why one should be able to understand Agriculture while the other not?

With race trait/attribute system, such ambiguity is not debatable, since there can be helping function isEatingFood(), which will just evaluate absence of LITHOVORIC and ENERGY_POWERED traits, clearly defining the logical argument "why this behavior".

Recognized inconsistency 2

Mechions drain 1 energy credit per 4 population, as "they are energy-powered", hence the made-up trait above. And AFAIK, that mechanic is not written anywhere in game. :smile:

Another error, which trait system would mitigate, as descriptions for traits the race has (and it has to have them, otherwise the game behavior would not work) could be automatically aggregated and printed in GUI, further simplifying game code and maintenance.

Recognized inconsistency 3

There is part of code in EspionageUtility that says Synthdroids cannot be affected by deadly virus. In RandomEventUtility, NewsFactory and StarMapUtilities the code for deadly virus cares only for Mechion and Synthdroids seems to be considered as a valid target. I am pretty sure that's unintentional, but the code is ambiguous anyway.

And there is partially duplicate logic and/or text. I strongly recommend removing deadly virus mechanic altogether.

I don't know how much code it affects, but I doubt it is well-isolated (duplicate code across different files means the answer is probably no). The mechanic could be redone at later date, probably in a much better way that would make it even more interesting, as it could pair with my other redesigns regarding planets (which I have to write down yet :slightly_smiling_face: ).

Same stance "just remove it now, redo it later" should be taken for several other mechanics for similar reasons, which however deserves it's own issue (I might open one day :smile:).

tuomount commented 7 months ago

I totally agree this should be done, since it would allow to have custom races. This is quite big change.

Recognized inconsistency 1

This is obvious bug. Lithovorians leaders would not benefit from agricultural perk.

Recognized inconsistency 2

Mechions are creatures which have high capacity energy sources built-in and those does not require replacement. Reason why there is credit cost after 4 Mechion population is that they require a bit of maintenance to keep them working. This is for balancing reasons. But it is true it is not mentioned anywhere. Could can think that each population has 0.25 credit of maintenance cost.

Recognized inconsistency 3

Again bug. Synthdroids were done after Deadly virus event and I missed that news event. But yes having racial traits would be good. How ever not sure how that would affect or how easy it is to get working AI for planet handling based on traits.

BottledByte commented 7 months ago

I consider this Proposal Accepted and will send initial PR soon :+1:


I totally agree this should be done, since it would allow to have custom races. This is quite big change.

It took me less than 12 hours to implement. I don't consider that big change time-wise :smile: . It was more about figuring out what is and is not a bug in current code, keeping doors open for trait/race dehardcoding in the future, and rebasing my changes back and forth because of not being upstreamed (that took maybe like 2 hours from it :upside_down_face: ). That, and fighting with useless tests failing, because I altered GUI text with mentions about racial traits :expressionless: .

It also does not affect game-saving. Traits are only in "game definitions", attached to SpaceRaces and those are not saved.

This is obvious bug. Lithovorians leaders would not benefit from agricultural perk.

Will fix in my changes :+1:

Mechions are creatures which have high capacity energy sources built-in and those does not require replacement. Reason why there is credit cost after 4 Mechion population is that they require a bit of maintenance to keep them working. This is for balancing reasons. But it is true it is not mentioned anywhere. Could can think that each population has 0.25 credit of maintenance cost.

As the game does not use floating-point numbers for many calculations, so I described this in the ENERGY_POWERED trait as follows:

"Consumes energy credits instead of food at a rate of 1 credit per 4 population."

I think that it is vague enough to not have to be changed if population will start really draining 0.25 per population, rather than 1 per 4 population and 0 for 3. :slightly_smiling_face:

Again bug. Synthdroids were done after Deadly virus event and I missed that news event.

I won't fix this, because as I said, it think the whole mechanic should be scrapped and rewritten in the future, using racial traits, planetary statuses (GH-676), etc.

How ever not sure how that would affect or how easy it is to get working AI for planet handling based on traits.

For now, I would keep changes to AI low-profile and just occasionally change SpaceRace to RaceTrait where it makes sense... which is only on a few places, because of bad encapsulation and responsibility-delegation in AI code :frowning_face: . Still, better than nothing :+1:

BottledByte commented 6 months ago

Moving RaceTrait discussion from #700

So you would cut of attitude off from the space race and only use attitude from ruler. That would work fine, except when ruler dies and there is no new ruler. This is one reason why there is that default attitude. Of course that could be probably generated from traits, but something else would be better. I just don't know what. Or maybe it could be just randomized at beginning of the game for each AI. But on other hand something like Reborgians probably would not works as diplomatic traders. πŸ˜„

First of all, yes, attitude should be cut-of from SpaceRace, at least in it's current form. It is already very confusing with all the attitude "sources". #624 is nice example of how confusing it can be :slightly_smiling_face:

Second, you are answering your own questions yourself. Since it is theoretically possible to derive attitude from race's traits/attributes, why not do it? And also, there is nothing wrong about random attitudes. Again, it adds variety. And Reborgians would make great diplomatic traders. "You give Planet, we go away." :smile: Yes, even this bizarre scenario with race practically designed for conquest trying to act like a diplomat and miserably fail is a gameplay.

So, in the end, I see a system where attitudes are scored and weighted by "how they fit for the race", then one of them is randomly selected, and assigned to AI (human player should not use attitude at all). I haven't added weighted lists, because I wanted to fight with Java's generics. :smile: Such system make most games normal, but kept things like "friendly Reborgians from your neighborhood" appearing on occasion.

I just like that +5 cloaking(Just enough to get invisibility at beginning of the game, this should also give bonus for not getting detected in espionage missions.), since it has create such interesting story telling events at beginning of the game. I have had war against some third realm and moved my ships away from my own planet. Then out of nowhere cloaked ship arrives on my planet and I cannot get to orbit anymore. Now my options are start war against those cloaked ships, or research planetary scanner or hope it just goes away. I know that this isn't racial trait it is more like technological thing, but so is also Centaur's more rigid ships.

Indeed, a mechanic where some realm has ships that are stealthy from game start is good. And it is not subject of removal. It is more like that "Has cloaked ships" trait will be renamed to "Stealthy" :smile:. So that it matches design logic. It can be said that given the race is naturally stealthy, it also keeps their ships in "low-power" mode or similar, to simulate their own properties in space (since they are used to have stealthy advantage). Trait justified.

But yes there could be trait for better spy which would give bonus for espionage missions.

I would add that to the Stealthy trait, as per reasoning described above and in previous conversation regarding "chameleon-like abilities". Both bonuses to cloaking and espionage missions (for leaders, as they are stealthy) should be rather small, like +5 or something. This is an example where small number makes large difference in balancing (in terms of cloaking). The espionage bonus is a "nice to have", that could incentivize recruitment of Stealthy-race leaders as spies. Which can consequently benefit game's "leader trading" mechanic.

And the realm espionage mechanic should be renamed to intelligence. Because there are two espionages, one being about realm-wide data (like ship positions, etc), while the second is mostly unrelated mechanic of leader espionage missions. It is confusing, both in-code and in-game. I will open a separate issue for that.

Those diplomatic traits sounds fine, but not sure about removing that built-in cloaking device.

TLDR: The "cloaking device trait" will not be removed, just renamed and slightly extended.

Charming and repulsive I was planning to add give diplomatic bonus. Humans should have diplomatic or similar trait which would give +2, charming +1, repulsive -2.

Another design thing: Don't create many "insignificant levels of traits" for one basic aspect. Two levels both ways are absolute maximum (like -2, -1, 0, +1, +2). After that, it becomes hard for player to keep track of traits as "categorization marker". Too high granularity for one aspect is bad for traits. Think about it like this:

As a player, I check out a race in intelligence view that I just met.

So the 2 levels both directions (bonus/malus) are maximum in terms of player's cognition. And the first level should be an above average in that case, while the second level should be very dramatic. In terms of diplomacy, I will have 3 traits specific for that aspect:

Trait points valuation in brackets. Notice the gaps. Additionally, there can be some other trait, that adds very minor (+1/-1) bonus to diplomacy, while focusing on other aspect or just describing something, but those should be both rare and "not game-changers in terms of diplomacy".

Population rush could give -1 diplomacy bonus so that would explain why it cost zero points.

TLDR: Rushing mechanic should be decoupled from races completely.

How do you justify the traits for rushing with credits/population? How is rushing related to race? What is even rushing? I know you have added the traits to keep the existing systems working, but there are unanswered questions. If population rush is slavery, then it is not a racial trait!. Governmental aspect? For sure, but not racial aspect.

It could understand Population rush trait for i.e. Robotic races, which could "deconstruct/transform themselves" to aid building the project, or similar weak explanation. But its really weak. And the Credit rushing RaceTrait... I cannot explain that one at all.

Again, race physique, mentality and realm governance is mixed-up here. It makes the design smell. And it makes game confusing. I personally was not able to understand "why some of those rushing buttons are sometimes greyed-out when I play for different realm". It can be from Government, it can be from Race... and in case of Sporks, they even had special ability where both rushing methods were allowed :upside_down_face: . VERY confusing.

tuomount commented 6 months ago

First of all, yes, attitude should be cut-of from SpaceRace, at least in it's current form. It is already very confusing with all the attitude "sources". #624 is nice example of how confusing it can be πŸ™‚

Second, you are answering your own questions yourself. Since it is theoretically possible to derive attitude from race's traits/attributes, why not do it? And also, there is nothing wrong about random attitudes. Again, it adds variety. And Reborgians would make great diplomatic traders. "You give Planet, we go away." πŸ˜„ Yes, even this bizarre scenario with race practically designed for conquest trying to act like a diplomat and miserably fail is a gameplay.

Something like that actually happened me in one of the test plays I had. Reborgians were elder race, when I first met them, they wanted to trade map of planets and they even sweetened deal giving something extra tech for me. I agreed and then next meeting, they announced now you will die. :smile: Diplomacy bonus or malus is guidance for AI how easily it is willing to do deal. Negative means that another party requires something extra on deal, positive means that deals will be a bit cheaper.

So, in the end, I see a system where attitudes are scored and weighted by "how they fit for the race", then one of them is randomly selected, and assigned to AI (human player should not use attitude at all). I haven't added weighted lists, because I wanted to fight with Java's generics. πŸ˜„ Such system make most games normal, but kept things like "friendly Reborgians from your neighborhood" appearing on occasion.

Indeed, a mechanic where some realm has ships that are stealthy from game start is good. And it is not subject of removal. It is more like that "Has cloaked ships" trait will be renamed to "Stealthy" πŸ˜„. So that it matches design logic. It can be said that given the race is naturally stealthy, it also keeps their ships in "low-power" mode or similar, to simulate their own properties in space (since they are used to have stealthy advantage). Trait justified.

Calling it stealthy is fine.

But yes there could be trait for better spy which would give bonus for espionage missions.

I would add that to the Stealthy trait, as per reasoning described above and in previous conversation regarding "chameleon-like abilities". Both bonuses to cloaking and espionage missions (for leaders, as they are stealthy) should be rather small, like +5 or something. This is an example where small number makes large difference in balancing (in terms of cloaking). The espionage bonus is a "nice to have", that could incentivize recruitment of Stealthy-race leaders as spies. Which can consequently benefit game's "leader trading" mechanic.

And the realm espionage mechanic should be renamed to intelligence. Because there are two espionages, one being about realm-wide data (like ship positions, etc), while the second is mostly unrelated mechanic of leader espionage missions. It is confusing, both in-code and in-game. I will open a separate issue for that.

Calling realm espionage as intelligence is fine and makes sense since now these two are called almost same names.

TLDR: The "cloaking device trait" will not be removed, just renamed and slightly extended.

Charming and repulsive I was planning to add give diplomatic bonus. Humans should have diplomatic or similar trait which would give +2, charming +1, repulsive -2.

Another design thing: Don't create many "insignificant levels of traits" for one basic aspect. Two levels both ways are absolute maximum (like -2, -1, 0, +1, +2). After that, it becomes hard for player to keep track of traits as "categorization marker". Too high granularity for one aspect is bad for traits. Think about it like this:

As a player, I check out a race in intelligence view that I just met.

  • With traits, I look and see "Ah, they are Strong, so they will have stronger troops than I have, since I am not Strong."
  • With a full numeric system, I can think "Ah, they have 13 troop power, I have 12, they are stronger, but not that much".
  • With granulated traits, I see "Ah, they are Mildly Strong, but I am Slightly Weak... They are stronger, but how big is the difference?" How about there would be numeric system in code, but only showing textual information to player. Numeric value could be shown when conquering then calculate actual troop power or similarly in planet view show troop power somewhere. In that case player would get feedback if barracks or such is being built and would also know how long bomb the planet before sending the troops.

So the 2 levels both directions (bonus/malus) are maximum in terms of player's cognition. And the first level should be an above average in that case, while the second level should be very dramatic. In terms of diplomacy, I will have 3 traits specific for that aspect:

  • Natural Charm (+1) => +2 diplomacy
  • Repulsive (-1) => -2
  • Disgusting (-3) => -7

Trait points valuation in brackets. Notice the gaps. Additionally, there can be some other trait, that adds very minor (+1/-1) bonus to diplomacy, while focusing on other aspect or just describing something, but those should be both rare and "not game-changers in terms of diplomacy".

TLDR: Rushing mechanic should be decoupled from races completely.

Yes, this sounds good idea.

How do you justify the traits for rushing with credits/population? How is rushing related to race? What is even rushing? I know you have added the traits to keep the existing systems working, but there are unanswered questions. If population rush is slavery, then it is not a racial trait!. Governmental aspect? For sure, but not racial aspect.

This is more governmental aspect.

It could understand Population rush trait for i.e. Robotic races, which could "deconstruct/transform themselves" to aid building the project, or similar weak explanation. But its really weak. And the Credit rushing RaceTrait... I cannot explain that one at all.

Again, race physique, mentality and realm governance is mixed-up here. It makes the design smell. And it makes game confusing. I personally was not able to understand "why some of those rushing buttons are sometimes greyed-out when I play for different realm". It can be from Government, it can be from Race... and in case of Sporks, they even had special ability where both rushing methods were allowed πŸ™ƒ . VERY confusing. Rushing options should be only game from Governments. Let's change that.

tuomount commented 6 months ago

Would it help, if there would be another enum class for example SpaceRaceEnum which would contain those spacerace enums and include for example theme music, ship background, ship image, race picture etc. Then current SpaceRace would be turn into class which would contain Race name, which images use for ship, race, bridge and so on. These could get value from spacerace enums, but still use actual file paths. Reason why to use that SpaceRaceEnum is that when there is custom race, it would be nice to have some kind of name for example ship style and so on. Of course those images should be also shown

tuomount commented 3 months ago

Works now. Closing.