Author Topic: Warning me when population runs low  (Read 1545 times)

WarpObscura

  • Newbie
  • *
  • Posts: 46
  • Karma: +0/-0
    • View Profile
Warning me when population runs low
« on: August 09, 2012, 10:15:27 AM »
I keep running into problems with my planets starving to death even when deliberately keeping Biology high and Sociology low. Is there any way to make the game automatically warn me when my population falls below a certain level or percentage of the max?

seronis

  • Distracted
  • ***
  • Posts: 338
  • Karma: +25/-0
    • View Profile
    • Steam Profile Link
Re: Warning me when population runs low
« Reply #1 on: August 09, 2012, 03:45:10 PM »
Yes.  Its not all too hard to do either. I already have warnings for running low on workers in the version of StarGov i have posted and my local copy warns for starvation too. It just puts a clickable message in the top panel so that clicking it lets you zoom directly to the planet having a problem
Any code/mods I post on this site should be considered Public Domain. Borrow it, steal it, shred it into little pieces to your hearts content. I dont require credit but I appreciate bug fixes and suggestions.

WarpObscura

  • Newbie
  • *
  • Posts: 46
  • Karma: +0/-0
    • View Profile
Re: Warning me when population runs low
« Reply #2 on: August 09, 2012, 09:09:05 PM »
What's the code necessary to do that?

seronis

  • Distracted
  • ***
  • Posts: 338
  • Karma: +25/-0
    • View Profile
    • Steam Profile Link
Re: Warning me when population runs low
« Reply #3 on: August 09, 2012, 11:23:39 PM »
If you look in planet.as the default version of a method about 80% of the way down the file looks like:

Code: [Select]
float populationConsume(Planet@ pl, const string@ state, double amnPer, double time) {
double pop = pl.getPopulation();
double maxPop = pl.getMaxPopulation();

State@ res = pl.toObject().getState(state);
double avail = res.getAvailable();
double needed = pop * time * amnPer;

if (avail >= needed) {
res.consume(needed, pl.toObject());
return 1.f;
}
else {
res.consume(avail, pl.toObject());
//Up to 10% of the population will die per second
pl.modPopulation(-1.f * min((needed - avail) / amnPer, pop * (1.f - pow(0.9f,float(time))) ));
return avail/needed;
}
}

This is what gets called up in the  planet::tick() method and it passes in a reference to the planets food supply (can also work with metal eating races etc...).  Anyways you can edit this method directly or edit the location it is called and check the return value.  That return value as you can see in the code is the ratio of 'food' that the population WANTS to eat, compared to how much was actually eaten due to availability limits.  If they're equal you are doing fine. If they are not you can use

Code: [Select]
emp.postMessage("#c:red#ALERT:#c# Governor on #link:o"+obj.uid+"##c:green#"+obj.getName()+"#c##link# reports not enough food available!");

Any code/mods I post on this site should be considered Public Domain. Borrow it, steal it, shred it into little pieces to your hearts content. I dont require credit but I appreciate bug fixes and suggestions.

WarpObscura

  • Newbie
  • *
  • Posts: 46
  • Karma: +0/-0
    • View Profile
Re: Warning me when population runs low
« Reply #4 on: August 12, 2012, 05:43:17 AM »
Do I just add that second Code box's contents into the
Code: [Select]
else {
res.consume(avail, pl.toObject());
//Up to 10% of the population will die per second
pl.modPopulation(-1.f * min((needed - avail) / amnPer, pop * (1.f - pow(0.9f,float(time))) ));
return avail/needed;
}
:-[

seronis

  • Distracted
  • ***
  • Posts: 338
  • Karma: +25/-0
    • View Profile
    • Steam Profile Link
Re: Warning me when population runs low
« Reply #5 on: August 12, 2012, 09:04:55 AM »
You can..  but if thats all you do you'll get spammed with the message repeatedly as soon as the planet begins starving.

Code: [Select]
// Consume food
if (!emp.hasTraitTag(strNoFood)) {
// Consume food
double consumption = 0.06/million * double(consumptionRate);
foodSupplyPct = populationConsume(pl, strFood, consumption, time);
}

// Consume metals if we have that trait
if (emp.hasTraitTag(strConsumeMetals)) {
double consumption = 6/million * double(consumptionRate);
foodSupplyPct = populationConsume(pl, strMtl, consumption, time);
}

//Check if warning for starvation is needed. Make it spam proof
if( foodSupplyPct < 0.99 ) {
float gt = gameTime;
State@ lastFoodAlert = pl.toObject().getState(strAlertFood);
if( gt > (lastFoodAlert.val + 30.f) ){
Object@ obj = pl.toObject();
emp.postMessage("#c:red#ALERT:#c# Governor on #link:o"+obj.uid+"##c:green#"+obj.getName()+"#c##link# reports not enough food available!");
pl.toObject().setStateVals(strAlertFood,gt,0,0,0);
}
}
}

What I do is i define a state that is attached to each planet that just tracks the time stamp of the last instance it reported the population was starving. As long as at least 30 'game seconds' have passed since the last warning, a new message will be posted. In the code above I also define a string constant at the top of planet.as named 'strAlertFood'.  The text contained in that string variable just has to be something unique.
Any code/mods I post on this site should be considered Public Domain. Borrow it, steal it, shred it into little pieces to your hearts content. I dont require credit but I appreciate bug fixes and suggestions.

seronis

  • Distracted
  • ***
  • Posts: 338
  • Karma: +25/-0
    • View Profile
    • Steam Profile Link
Re: Warning me when population runs low
« Reply #6 on: August 12, 2012, 09:07:29 AM »
Last thing..  you should not keep sociology low.  Sociology is the 2nd most important technology to Metallurgy for giving you the highest possible production. Mathematically, the two techs should be kept equal (soc/metal).  If you just assign a couple of your 14slot or smaller planets to farm worlds you shouldnt have food problems.
Any code/mods I post on this site should be considered Public Domain. Borrow it, steal it, shred it into little pieces to your hearts content. I dont require credit but I appreciate bug fixes and suggestions.

WarpObscura

  • Newbie
  • *
  • Posts: 46
  • Karma: +0/-0
    • View Profile
Re: Warning me when population runs low
« Reply #7 on: August 12, 2012, 11:16:26 PM »
What I do is i define a state that is attached to each planet that just tracks the time stamp of the last instance it reported the population was starving. As long as at least 30 'game seconds' have passed since the last warning, a new message will be posted. In the code above I also define a string constant at the top of planet.as named 'strAlertFood'.  The text contained in that string variable just has to be something unique.

Where does the above code go?  :-[

Last thing..  you should not keep sociology low.  Sociology is the 2nd most important technology to Metallurgy for giving you the highest possible production. Mathematically, the two techs should be kept equal (soc/metal).  If you just assign a couple of your 14slot or smaller planets to farm worlds you shouldnt have food problems.

Planets starving to death everywhere. I just don't know what went wrong!

seronis

  • Distracted
  • ***
  • Posts: 338
  • Karma: +25/-0
    • View Profile
    • Steam Profile Link
Re: Warning me when population runs low
« Reply #8 on: August 12, 2012, 11:30:50 PM »
Where does the above code go?  :-[
Sorry im used to seeing the code so it was more obvious to me. The first half of that paste is already in the file. Its only the bottom section that is new so you can look for the top part for reference of where the code goes (its in the tick() method)
Quote from: WarpObscura
Planets starving to death everywhere. I just don't know what went wrong!
If your galactic bank has no food then its because you dont have enough farm worlds. If your galactic bank HAS food and a planet is still starving then its because that planet cant get food FROM the bank fast enough for the requirements of your population


-edit-
Added my copy of planet.as to this post. Its a vanilla SR 1.2.1 copy with ONLY the changes added to enable the starvation message, which will display every 30 game seconds than a planet is starving.

I post snippets to help people LEARN how to do modding related things, or for people who already know to just grab a feature and save themselves the time writing it. Id prefer you actually make an effort to understand the code change rather than just grab the file and use without thought but thats a preference, not a requirement.
« Last Edit: August 12, 2012, 11:52:49 PM by seronis »
Any code/mods I post on this site should be considered Public Domain. Borrow it, steal it, shred it into little pieces to your hearts content. I dont require credit but I appreciate bug fixes and suggestions.

WarpObscura

  • Newbie
  • *
  • Posts: 46
  • Karma: +0/-0
    • View Profile
Re: Warning me when population runs low
« Reply #9 on: August 13, 2012, 09:39:33 AM »
Code: [Select]
foodSupplyPct = populationConsume(pl, strFood, consumption, time);
Code: [Select]
float populationConsume(Planet@ pl, const string@ state, double amnPer, double time) {
Code: [Select]
if( foodSupplyPct < 0.99 ) {
...

How does the function returning less than that value mean I don't have enough?  :-\

seronis

  • Distracted
  • ***
  • Posts: 338
  • Karma: +25/-0
    • View Profile
    • Steam Profile Link
Re: Warning me when population runs low
« Reply #10 on: August 13, 2012, 10:22:30 AM »
Look at the very first method i pasted. Its at the bottom of the file.  The return value is the ratio between

how much i ate / how much i wanted to eat

So if you have surplus food you will eat exactly what you wanted.  The only time you eat less is when you run out of food. So any return value of less than 1.0 means that planet is not receiving as much food as its population demands. Depending on how severe this is you might be getting enough food to keep 80% (random number) of your max population alive or you might be getting so food that your entire population will die off after enough time passes.  You could have a tiered approach to the warnings if you wanted like:

Code: [Select]
    if( foodSupplyPct < 0.1 ) {
        //OMG_WTF_DOOM message
    }
    else if( foodSupplyPct < 0.25 ) {
        //extremely urgent sounding message
    }
    else if( foodSupplyPct < 0.66 ) {
        //urgent sounding message
    }
    else if( foodSupplyPct < 0.99 ) {
        //message
    }

I dont bother going into that much detail (yet). Im probably gonna have 2 urgency levels in my own final product with a cut off so that if there are a TON of planets starving all at the same time you dont get mass spammed and instead get one or two specific planets then a "Your empire is in urgent need of Food supplies!!" if another shows up in the same timeframe with all others silenced until the couple are dealt with. Notifications are good. But too many is just pointless as by that time the player KNOWS they are doing something wrong
Any code/mods I post on this site should be considered Public Domain. Borrow it, steal it, shred it into little pieces to your hearts content. I dont require credit but I appreciate bug fixes and suggestions.

WarpObscura

  • Newbie
  • *
  • Posts: 46
  • Karma: +0/-0
    • View Profile
Re: Warning me when population runs low
« Reply #11 on: August 15, 2012, 02:41:43 AM »
Okay, I dun goof again.  :-[

I added in this:
Code: [Select]
//Check if warning for starvation is needed. Make it spam proof
if( foodSupplyPct < 0.99 ) {
float gt = gameTime;
State@ lastFoodAlert = pl.toObject().getState(strAlertFood);
if( gt > (lastFoodAlert.val + 30.f) ){
Object@ obj = pl.toObject();
emp.postMessage("#c:red#ALERT:#c# Governor on #link:o"+obj.uid+"##c:green#"+obj.getName()+"#c##link# reports not enough food available!");
pl.toObject().setStateVals(strAlertFood,gt,0,0,0);
}
}
and killed my labour generation. These are the error messages:
Code: [Select]
AS Server Error in D:\Program Files (x86)\Steam\steamapps\common\Star Ruler\Mods\WLO_Vanilla\Game Data\scripts\server\planet.as: Compiling void tick(Planet@, float)
 line: 130, col: 1
AS Server Error in D:\Program Files (x86)\Steam\steamapps\common\Star Ruler\Mods\WLO_Vanilla\Game Data\scripts\server\planet.as: 'strAlertFood' is not declared
 line: 182, col: 50
AS Server Error in D:\Program Files (x86)\Steam\steamapps\common\Star Ruler\Mods\WLO_Vanilla\Game Data\scripts\server\planet.as: Can't implicitly convert from 'const int' to 'State@&'.
 line: 182, col: 27
AS Server Error in D:\Program Files (x86)\Steam\steamapps\common\Star Ruler\Mods\WLO_Vanilla\Game Data\scripts\server\planet.as: No matching signatures to 'Object::setStateVals(int, float, const uint, const uint, const uint)'
 line: 186, col: 19
AS Server Error in D:\Program Files (x86)\Steam\steamapps\common\Star Ruler\Mods\WLO_Vanilla\Game Data\scripts\server\planet.as: Candidates are:
 line: 186, col: 19
AS Server Error in D:\Program Files (x86)\Steam\steamapps\common\Star Ruler\Mods\WLO_Vanilla\Game Data\scripts\server\planet.as: void Object::setStateVals(const string&inout, float, float, float, float) const
 line: 186, col: 19
How did I screw it up?

seronis

  • Distracted
  • ***
  • Posts: 338
  • Karma: +25/-0
    • View Profile
    • Steam Profile Link
Re: Warning me when population runs low
« Reply #12 on: August 15, 2012, 10:01:08 AM »
Umm.. those errors are just in the version you tried to edit yourself, right?  Not the planet.as i uploaded?  (cause i dont think i left out any dependancies)

Anyways i'll go over the error lines one at a time so you can get a grasp on how to read them. And i'll highlight key parts
Quote
AS Server Error in D:\Program Files (x86)\Steam\steamapps\common\Star Ruler\Mods\WLO_Vanilla\Game Data\scripts\server\planet.as: Compiling void tick(Planet@, float)
 line: 130, col: 1
This first line, and ANY other line that says "compiling blah blah" is not an actual error. What it is, is a hint where the next 1 or more errors can be found. Its telling you that a method named  'void tick' which is found at line 130 (starting with the 1st character in the line) was not able to fully compile and the next lines are the actual problems as the compiler can understand them. From here on i'll continue highlighting the portion that is the error in red and its location in  yellow so it stands out.

Quote
AS Server Error in D:\Program Files (x86)\Steam\steamapps\common\Star Ruler\Mods\WLO_Vanilla\Game Data\scripts\server\planet.as: 'strAlertFood' is not declared
 line: 182, col: 50
First i highlighted a section in green. This will be before any error and just tell you the full path of the file we are dealing with. The error here is saying a variable name (strAlertFood) that we used was not found to be declared anywhere. It found us attempting to use this variable name on line 182, 50 characters from the beginning of the line (i will assume you fully understand the yellow location information from now on). A variable can only be used after its declared. A declaration is a line that has the variables type, then its name. In the case of 'strAlertFood' in the copy of planet.as I uploaded near the top of the file you will see:
Quote
const string@ strAlertFood = "plalert_food";
I highlighted the 'type' part of the declaration in purple and the name in maroon. This means we want the computer to set aside space in memory for a 'string' (series of characters, line of text) and to refer to that string by the name strAlertFood. We put an 'identifier' of const in front of the declaration. This is just a hint to the compiler that our string is meant to be used, not changed. We immediately assign the string the contents of  "plalert_food".  I could have used "foodAlertName" or anything else i wanted. It just needs to be a unique name not used by any other string.

Quote
No matching signatures to 'Object::setStateVals(int, float, const uint, const uint, const uint)
The last 3 things listed is actually just one error. Its telling you that what it sees you trying to do is not allowed.  'No Matching Signature' means you used the wrong type of variable in a location. Since you did not declare 'strAlertFood' above, the compiler will always assume a name it doesnt understand is supposed to be an integer. The method you are calling here does not allow an integer as its first argument, it requires a string. This error can be ignroed because our variable IS meant to be a string, it just wasnt declared.


Hope this helps you.
Any code/mods I post on this site should be considered Public Domain. Borrow it, steal it, shred it into little pieces to your hearts content. I dont require credit but I appreciate bug fixes and suggestions.

WarpObscura

  • Newbie
  • *
  • Posts: 46
  • Karma: +0/-0
    • View Profile
Re: Warning me when population runs low
« Reply #13 on: August 16, 2012, 12:52:29 AM »
Yes, I was able to get it to work. How silly of me. :-[

I'm glad you dissected the code. I'd never used AS before this, so I was quite lost.

seronis

  • Distracted
  • ***
  • Posts: 338
  • Karma: +25/-0
    • View Profile
    • Steam Profile Link
Re: Warning me when population runs low
« Reply #14 on: August 16, 2012, 04:44:09 AM »
The only thing i love more than doing little tweaks to increase my enjoyment is showing someone else how to do tweaks themzelves. The more modders doing things the more total ideas floating around.  Everyone wins
Any code/mods I post on this site should be considered Public Domain. Borrow it, steal it, shred it into little pieces to your hearts content. I dont require credit but I appreciate bug fixes and suggestions.