Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Design Proposal - Planetary Statuses #676

Closed
BottledByte opened this issue Dec 9, 2023 · 12 comments
Closed

Design Proposal - Planetary Statuses #676

BottledByte opened this issue Dec 9, 2023 · 12 comments
Labels
enhancement Feature request Game mechanics New game feature to game mechanics Wait for verify Issue has been implemented but needs verification that it works.
Milestone

Comments

@BottledByte
Copy link
Contributor

Planetary conditions could be described by zero or more statuses, like planet having easily accessible minerals, etc. Such change would allow combining conditions on planets, promoting composition and code reuse. Definition of statuses could be easily moved to data files (as per GH-666).

PlanetaryStatus would work like a definition of a status, like how it affects planet's attributes. This PlanetaryStatus then could be applied to 0..N planets with AppliedStatus, where additional information would be added, such as at what turn the status should end (if time-bound). Statuses could be also used as flags, marking planets for some other code (in sense that planet "has" condition).

Statuses could be stackable (having the same status on 1 planet multiple times) or not.
For now I recommend the non-stackable status design - there are sometimes game-breaking issues due to stackability of statuses/flags in other games I know of. Non-stackability constraint can be easily removed later, if status stackability will appear as valuable concept.

Planetary statuses system has following benefits over current design:

  1. Data-driven design - Status definitions can be stored in data files.
  2. Code reuse - Statuses can be combined on a single planet to simulate new conditions. Other code could apply status to a planet as result of event, etc.
  3. Better visualization - GUI can show list of all statuses on a planet, with descriptions.
  4. Status dependencies - Statuses might require presence or absence of other statuses to be applicable.
  5. Hidden statuses and Planet-marking - Status could be hidden in GUI and not change planet in any way, but it's presence/absence in game's data model could be used as precondition for other behavior.
  6. Time-bound status - Planet could get a status as a result of some event, but removal of said status could be done automatically when the status expires.
  7. Independent from PlanetaryEvents - PlanetaryStatus represents that planet has a condition, while PlanetaryEvent describes "what happens if...". Discovering PlanetaryEvent could apply status(es) to a planet, promoting encapsulation / responsibilities delegation.

Programmer Point of View

As a programmer, I want to be able to model my ideas more efficiently. Planetary statuses allow me to mark and describe planets using composition. This allows me to reuse and organize code, while having new modelling tools at my disposal.


Player Point of View

As a player of 4X strategy games, I want to have better idea on what is happening in game, and PlanetaryStatuses describe conditions of planets clearly.

As the statuses could combine, it also possibly introduces new interesting situations to the game and could increase game depth. Especially if other mechanics will be made around planetary statuses.


Notes

I built a prototype of this and it seems to work, but such change will break existing save files.

Nonetheless, I think that planetary statuses are something that should be done in one way or another, because currently, planetary status is implemented using planetary events, which is confusing and very inflexible.

I think it that the statuses being optionally time-bound is a plus and very useful, but the design can be simplified by omitting the AppliedStatus class altogether and just directly using PlanetaryStatus on planets. However, I believe it makes sense to have distinction between status "template" and its "application", as apart from the time tracking, this could be used for i.e. tracking "source" of status, etc.

I consider ability to mark planets with optionally hidden statuses and then use such markers in other mechanics a slightly hacky, but still very manageable and clear. Many games use similar systems like this, for example in Cataclysm: Dark Days Ahead, NPCs use statuses as flags for things like "We just chatted".

And such "flags" are just another tool that can be used for creating new immersive mechanics.
Some mechanics, that could be implemented with or benefit from "status flags", that I have on top of my mind are:

  • Various forms of terraforming - both event-based and time-based (waiting to complete)
  • Allowing special buildings to be build only on planets with certain status
  • Marking planets as targets for future random events,
    like planet becoming source of a disease or being struck by an earthquake
  • Ownership of planet with some status could be precondition
    for unlocking a tech in research
  • Markers for procedural-generated story content*,
    like marking planet as source of planned galactic threat,
    somehow connected to realm's background (original homeplanet, mythological meaning, etc.)
    or somehow related to ascension victory... 😏
  • Many other mechanics 😄

Summary

Having system for planetary statuses allows describing planetary conditions in a clear, data-driven way. It can also work as marking system, allowing the system to be used by other game mechanics to increase game depth.

Such system also makes distinction between "planetary event/anomaly" and "planetary condition", which is not necessarily the same thing. Statuses can also be clearly and distinctively visualized in GUI.

Overall, planetary status system could bring a lot of value to the player in the future.

@tuomount
Copy link
Owner

This is good idea. I think it would be beneficial to multiple status on planets. There could for example how much water is on planet, what is the gravity on planet: low, normal and high. Then for example Alterians live only on Orbital they would prefere zero-g planets(which would not exists), but low might be slightly more tolerable and high just honorific.

Future random events also sound good.

Ascension victory also requires new trait, it would need to know with planet has the ascension vein coming.
But again this would be quite big change.

But one thing which has been for me as guide line that there should be traits, status or techs which gave for example 5% more farming, mining or production. These traits should be some how that actually give something significant. I feel that give few pre cents there and there is a bit boring way to design 4X game. Currently ORoS only has planet habitability with 25% steps which tell maximum population for planet which it can sustain.

Also these traits could be interesting if we could skip using fixed tiles and planet images and use that rotating planet view which was in one version. We could do procedural planet textures which would be based on planet traits and maybe even modify it depending how many populations/buildings there are.

@BottledByte
Copy link
Contributor Author

BottledByte commented Dec 10, 2023

TLDR:
I consider this Proposal Accepted and will continue refining my prototype to presentable state 👍


This is good idea. I think it would be beneficial to multiple status on planets. There could for example how much water is on planet, what is the gravity on planet: low, normal and high.

In my design, planetary statuses work as "very fancy enumerations" with ability define how planet's attributes (production, happiness, etc) should change. I think statuses should mark "unusual" things (unusual depending on defined context of normality), while generally-applicable attributes should be implemented as data attributes.

In examples you said, I can imagine such enumerations as:
Water on planet:

  • "Dry" (less water on planet than usual for the planet type)
  • "Water Reserves" (more water than usual for the planet type)
  • "Normal" (absence of statuses Dry or Water Reserves)

Gravitation:

  • "Strong Gravitation" (unusually strong gravitation for habitable planet)
  • "Weak Gravitation" (unusually weak gravitation for habitable planet)
  • "Normal" (absence of either status)

But one thing which has been for me as guide line that there should be traits, status or techs which gave for example 5% more farming, mining or production. These traits should be some how that actually give something significant. I feel that give few pre cents there and there is a bit boring way to design 4X game. Currently ORoS only has planet habitability with 25% steps which tell maximum population for planet which it can sustain.

To be honest, I cannot clearly understand this statement because of English used is somewhat broken. Are you against or for "+5%" style of attribute modifications 🙂 .

Because I am for, but with decency.
Small increments allow for "slow but continuous build-up" and are more easily incorporated into balancing equations. But I agree that having everything being "+5%" is not optimal. Also it depends on what gets this +5%, as some attributes are way more "impactful" than others (think metal-mining vs max population on a planet).

With this in mind, planetary statuses mark "reasonable" things and have adequate impact. For example, there is no need to have status "there is a lot of grass on planet => +2% to food production" 😄 . But status like "fertile soil => +15% to food production" is IMHO reasonable. Just like in everything, lets use common sense 😄 .

Anyway, scale of bonuses a trait/status provides is more of a game-balancing thing.
This is more of a game-design issue, to be able to even have statuses in the first place and how those could be used. 🙂

@tuomount
Copy link
Owner

tuomount commented Dec 10, 2023

What I tried to say was that there always should be significant effect. For example currently planet's can have this status which gives food bonus. (Normally all planets give +2 food)
Desert -2, Arid -1, Lush vegetation +1, Paradise +2. I think that could be used also in that how much water is planet. Since what else water on planet could easy provide than food?

Then that gravity is bit more difficult. Since strength of gravity depends on size of the planet. So it would cause that space race with low gravity would only be able to live in small planets. So we could have something table like this:

Low gravity normal High gravity
Zero Gravity Mining 50% Mining & production 50% Mining & production & food 50%
Low gravity Normal Mining 50 % Mining & production 50%
Normal Mining 150% Normal Mining 50%
High Gravity Mining&Production 150% Mining 50% Normal

Show first column is what kind of gravity space race is used to. Then production and mining would depend on what kind of
gravity planets would have. Then most of the production and mining bonuses could depend on what kind of gravity race is used.
So what that 50% means that you need to have one population as miners for get one metal. If there is 150% production every 2 workers give 3 metal or production.

@tuomount
Copy link
Owner

Now that I think fertile soil is quite good. So maybe drop the paradise, change lush vegetation +2 and fertile soil +1.
That 15% is bit problematic, since it would require 7 population as worker to give one extra. I think full integers are much more easier to player to understand and get grasp of them. Something like 50% and 150% is okay since affect is visible quite soon when dealing with workers. If you think about 15% more that would require 7 workers before it actually affects on integer levels.

@tuomount tuomount added enhancement Feature request Game mechanics New game feature to game mechanics labels Dec 10, 2023
@tuomount tuomount added this to the 0.26.0 milestone Dec 10, 2023
@BottledByte
Copy link
Contributor Author

What I tried to say was that there always should be significant effect.

👍 Agreed, statuses should have significant effects.
But as I said, changes in some attributes have more weight/impact than others, i.e. having one more population on planet is much more powerful than one more food production (since I can dedicate the population to other tasks + it may be even more efficient in food production that the bonus itself).

So maybe drop the paradise, change lush vegetation +2 and fertile soil +1.

Will incorporate this in my changes 👍 .

That 15% is bit problematic, since it would require 7 population as worker to give one extra. I think full integers are much more easier to player to understand and get grasp of them.

That was just an example. Don't take everything I write as a specific proposal 😄 .
I have no problem with full numbers (I don't even have the "improve attribute by n%" system implemented now).
Also, there is the "attribute impact" thing, where just "one more" can change everything.

Then that gravity is bit more difficult. Since strength of gravity depends on size of the planet. So it would cause that space race with low gravity would only be able to live in small planets.

Nice idea 👍 . But it sounds like a different new mechanic altogether, which may or may not fuse with planetary statuses concept, and deserves it's own issue/proposal.


I suggest we stop discussing exact numbers and bonuses here, lest that's not scope of this proposal.
How specifically the planetary status "content" will look like is mostly unrelated to this proposal, maybe except the concept of stackability of said statuses.

@tuomount
Copy link
Owner

I know that 15% was just an example, but when I started this project, I also considered something like that but then I found out that small % bonus do not give significant bonus. There are quite many 4X games which give small bonuses and then player can decided if they want to increase 5% maximum fleet size or 5% more food or 5% production and when selecting first of these it does not make any difference. Player needs to stack same bonuses in order to have them some effect.

I also started to think if temperature could be used also bit like gravity:
Artic, Cold, Temperate, subtropical, tropical.

Arctic Cold Temperate Subtropical Tropical
Arctic 100% 75% 50% 25% 0%
Cold 75% 100% 75% 50% 25%
Temperate 50% 75% 100% 75% 50%
Subtropical 25% 50% 75% 100% 75%
Tropical 0% 25% 50% 75% 100%

That percentage would be to maximum population based on planet temperature. Temperature and vegetation could be something that would allow terra-forming. So there could be technology to heat or cool down the planet. Also technology that would cause planet have more vegetation. Yes, these should be on separate issue. If these would be implement I would drop planet types and just use these statuses.

@BottledByte
Copy link
Contributor Author

I know that 15% was just an example, but when I started this project, I also considered something like that but then I found out that small % bonus do not give significant bonus. There are quite many 4X games which give small bonuses and then player can decided if they want to increase 5% maximum fleet size or 5% more food or 5% production and when selecting first of these it does not make any difference. Player needs to stack same bonuses in order to have them some effect.

It's ALL about game balancing. Well, except this issue. 😄
I think that bonus sizes, numerical systems and balancing equations of the game are out of scope of this proposal. In my prototype, I try to keep all balancing as it was, with exception of the potentially multiple different statuses (thus bonuses) on a single planet.

I also started to think if temperature could be used also bit like gravity:
Artic, Cold, Temperate, subtropical, tropical.

Very cool idea and a hot topic 👍 (puns intentional 😄 )!
This definitely sounds like a planetary climate/type redesign proposal to me. 😏

When already out of scope, I will just add that such design changes would probably made sense as planetary attributes rather than statuses, since every Planet has temperature and gravitation. And with varying strengths. Statuses could cater such system, but I believe they should not. Radiation is also an attribute, not a status (and like 9-10 statuses would be needed to describe current system).

Planetary status should represent unusual condition. If there should be a system for planetary gravitation/temperature, it will then no longer be "unusual". What could be described by status in such design would be i.e. something like "changing gravity/temperature/radiation" (like for climatically unstable planets, etc.).

@tuomount
Copy link
Owner

Sounds good those unusual condition like unstable climate, which could very climate certain change per star year or something like that.

But funny thing about this temperature and gravity redesign, is that one of my inspiration was 1995 Stars! 4X game where all planets had temperature, gravity and radiation as attributes.

@tuomount
Copy link
Owner

So If I understand correctly AppliedStatus class should have attributes how long PlanetaryStatus is going to be in effect or how many star years it takes before it activates and or some other conditions. Since with these it could be possible to do some cool starting scenarions, for example after planet has been colonized for 40 star years, ancient relic is found and it boost science +1, after 80 star years ancient building is discover and again it boost +1 science and finally after 120 star years ancient city ruins are discovered +1 science is gained.

Current class does not have any of this yet? Did you have some plans how to do it? It could have maybe some activity type and then star year counter, when those hit zero type could be changed something like active and set timer for -1 which would indicate infinity. If timer would be something else then it would change to deactive and set timer for some other value. This could be used to create for example pulsating effects.

@BottledByte
Copy link
Contributor Author

So If I understand correctly AppliedStatus class should have attributes how long PlanetaryStatus is going to be in effect or how many star years it takes before it activates and or some other conditions.

Based on this text, you understand. Just to clarify, AppliedStatus holds exact information related to instance of a PlanetaryStatus. There could be PlanetaryStatus "Grant relic after mining some amount of planet's minerals" (that's overly specific example, would need some hardcoding or overhaul, but let's ignore this for now). The AppliedStatus could then have two attributes, the relic given and amount of minerals the planet must have.
In case of timed statuses, simple "trigger on date" attribute would suffice. 👍

Current class does not have any of this yet?

No, it does not. I left AppliedStatuses intentionally half-finished. 😄
More knowledge and design was (and still sort of is) needed. That's why I filed all those design/discussion issues, like how it could relate to the event system, what needs could arise from starting scenarios, etc. 🙂

Did you have some plans how to do it?

I had 4 different plans:

  1. Adding a Map<String, Object> field to AppliedStatus
  2. Sub-class AppliedStatus for specific "kinds" of "attribute groups"
  3. Adding fields directly to the AppliedStatus as needed
  4. Hybrid of directly added fields and Map<> of additional attributes

I don't know what you plan with PlanetaryStatuses, what vision you have.

If I should decide, I would go with (1). It is just the most flexible.
I don't know what I, you or other people will come up with, but this design has all covered, while remaining coherent. And it can be converted to design (4) on demand, in case some performance hit or abundant boilerplate code or whatever appears.


It could have maybe some activity type and then star year counter, when those hit zero type could be changed something like active and set timer for -1 which would indicate infinity.

I designed the AppliedStatus to be unable to change it's PlanetaryStatus externally (which was the only logic way).
This is intentional, as PlanetaryStatus is working like a "class" here.

Thus, a "status changing on expiring" is translated to "when status expires, new status is applied".
This is for coherency, so there are no doubts on "how this status got there?".
It was added. Somewhere, by some piece of code, but it was added.
Of course, the AppliedStatus data could be changed (like it's expiration time reset), but not its PlanetaryStatus class.
If this will prove limiting, it can be redesigned.

I also designed it this way to potentially allow implementation of "hooks"/"reactions", which could run code on add/remove automatically, the code being tied to the PlanetaryStatus, not AppliedStatus. Like automatically add additional status "onAdd", when some other status is already present, etc.

This is sometimes done, for example, in advanced buff-systems in RPGs. And it is useful for modding.
But I did not implement hooks, again intentionally, as they have their own problems (like reacting on things when it is undesired), and similar could be instead achieved by an advanced event system (and that's another issue 🙂 ).

This could be used to create for example pulsating effects.

See text above 😄


But, this is just a proposal. Things may change. And as there are currently no planetary statuses defined at all, the code can be changed without breaking something rather easily 😄

@tuomount
Copy link
Owner

I had 4 different plans:

  1. Adding a Map<String, Object> field to AppliedStatus
  2. Sub-class AppliedStatus for specific "kinds" of "attribute groups"
  3. Adding fields directly to the AppliedStatus as needed
  4. Hybrid of directly added fields and Map<> of additional attributes
  1. This would definitely allow most flexibility, but how much flexibility is actually going to be needed.
  2. This probably is going to be over-engineered easily and could make saving the information into save game file a bit more complex.
  3. This would be my initial try out, just adding type and turn counter.
  4. This could be taken later if number 3 is not enough.

I don't know what you plan with PlanetaryStatuses, what vision you have.

  1. There should be way to activate planetary status after certain amount of star years has passed after colonization or away team has done survey.
  2. Status would activate after certain amount turn after game has started, this could be used for example doomed starting scenario.
  3. There is status which would activate after certain amount star years and then deactivate for a while and keep looping that.

If I should decide, I would go with (1). It is just the most flexible. I don't know what I, you or other people will come up with, but this design has all covered, while remaining coherent. And it can be converted to design (4) on demand, in case some performance hit or abundant boilerplate code or whatever appears.

Choices 1 and 3 both can join up at choice 4.

It could have maybe some activity type and then star year counter, when those hit zero type could be changed something like active and set timer for -1 which would indicate infinity.

I designed the AppliedStatus to be unable to change it's PlanetaryStatus externally (which was the only logic way). This is intentional, as PlanetaryStatus is working like a "class" here.

PlanetaryStatus should be the working class and AppliedStatus just containing extra information and automatic handling. Problem I see is that I would like define how long some status takes before activation to be defined in JSON, thing is that part is actually in AppliedStatus class.

Thus, a "status changing on expiring" is translated to "when status expires, new status is applied". This is for coherency, so there are no doubts on "how this status got there?". It was added. Somewhere, by some piece of code, but it was added. Of course, the AppliedStatus data could be changed (like it's expiration time reset), but not its PlanetaryStatus class. If this will prove limiting, it can be redesigned.

I kind of like just the idea it was added. Sounds simple but then again some certain level of automation would be nice. For example automatically do timer calculations and so on.

At the moment I would try to create following planet status:

  • Fertile soil, + 1 Food after being colonized 5 star years.
  • Metal rich sufface, +1 metals after being colonized 5 star years.
  • Gems +1 credit after being colonized 10 star years.
  • Lava flows on surface, +1 production and +1 metal but -1 happiness after being colonized 2 star years.
  • Highly tectonic crust, every 20 star years one building is going to be destroyed and 50% of one population dies
  • Doomed planet, after certain years planet turns into inferno planet and cannot be colonized anymore

tuomount added a commit that referenced this issue Mar 31, 2024
Creates base.json for planetary status and method to get all.
tuomount added a commit that referenced this issue Apr 5, 2024
tuomount added a commit that referenced this issue Apr 6, 2024
Adds pictures for fertile soil, metal rich surface and molten lava.
tuomount added a commit that referenced this issue Apr 8, 2024
tuomount added a commit that referenced this issue Apr 9, 2024
tuomount added a commit that referenced this issue Apr 10, 2024
Adds two new research statuses.
tuomount added a commit that referenced this issue Apr 11, 2024
tuomount added a commit that referenced this issue Apr 27, 2024
#692 MusicTest no longer enables music after testing it silently.
tuomount added a commit that referenced this issue May 1, 2024
tuomount added a commit that referenced this issue May 13, 2024
@tuomount tuomount added the Wait for verify Issue has been implemented but needs verification that it works. label May 17, 2024
@tuomount
Copy link
Owner

Closing.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement Feature request Game mechanics New game feature to game mechanics Wait for verify Issue has been implemented but needs verification that it works.
Projects
None yet
Development

No branches or pull requests

2 participants