Devlog #44 - City Enum - scriptable Object , ***Game System Update*** - City Growth fixed , InverseLerp for productUnlock ( changes from previous logs)
******City Enum, introduction to fixed system of city names and values (tiers) , which caps the unlocking products to the difference between the base population and next tier/enum for other product unlocks*****
Lets start from the begining and why this matters so much.
Idea 1 :
The city has proportional growth based on the base population, tier 1 to tier 2 would mean that the city grows by 100%. so in essence to reach tier 2 it has to double in population. if(cityPop >= baseCityPop *2)
The productUnlock System was based upon the percentage of difference between the currentPopulation / basePopulation.
For example: first 2 products unlock at the ratio 1.0 , means that when the game starts the pop/basePop = 1, so 2 products opet, but other 2 products unlock at 1.4 and 1.7 ratio of the currentPop. in essence:
float popRatio = currentPop / basePop;
and then we say, product a - unlocks at 1.4. ratio, and product b - unlocks at 1.7 ratio.
Problems with this long term:
-First, the Tier2 is not universal, its reather proportional to the original base population, which means, a city that starts at 3k, 6k is alreay tier2, while, the city that starts with 6k needs 12k to be tier 2.. so its not balanced and makes not much sense in reality.
-Second, the products unlocks then would have to always increment, 2.4, 2.7, then 3.4.3.7 or if there is more products its always the same principle. One mistake, grave mistake.. hahah
_______________________________________________________________________
Idea 2 :
We introduce Enum for city, but this time we dont use Database, but rather just a condition for City size.
For example:
So now, instead of using proportions we are using Enum as set values, so we say,
//pseudo
static void UpdateCityTier
{
city.cityTier = city.Population switch
< 5000 => cityTier.Village
< 10000 = > cityTier.Town
etc
}
So , we run this each turn, and it updates, so if the city grows over 5000, becomes Town, if not stays Village. Which worked! But.. of course it wouldn't be that easy.
Problem? - We cant use percentage for the purpose of unlocking more products on the way to the tier 2. - (Welcome to one of the most frustrating stuff that i have had in this game, because of mixed enums) , Anyhow:)
So I had somehow to bring back the values for different cityTiers(5000,10000), but they couldnt be coded within the switch. -So either give up idea on unlocking more products or calculate it from the current pop and 0, and artificially keep the ratio somehow,but again, same issue, the city with 3k is not the same as with 6k.. and now the CityTiers are set.
____________________________________________________________________________________
Idea 3: solution .................. 👀💬
Introduce another array, with actualy population limits for each tier so it can be used for calculating popRatio. In essence we take currentTier and nextTier, and calculate the difference inbetween with inverseLerp, so we get the ratio....
For example, we put it paralel we say
CityTier Enum { village, town, city... }
Threshold int[] { 5000,10000,150000...}
(that was the most frustration ever) anyhow,
Now we can combine both and use the values instead of switch to actually use the values from the array threshold.
so we say,
if(city.Pop < threshold(int)city.CityTier // here we take the value from the array but choose the same value as the cityTier , value i mean int) ;
This way, we can get the same result, and but still use the values for the later popRatio, and also we have the edge case if thepopulation is bigger then the array 5(6) , it will never pass through the for(int i) . Goes through all 6 and its all wrong,
Thats why we added and said before for , calculatedTierIndex = 5; 5 is actually cityTier that is actually 6, because enums start at 0,1,2,3,4,5.
So then, we also changed the way ratio is calculated, now we have to calculate the currentTier (for example 5000 on 0 place) and also nextTier is 10000, place 1
we define currentTier = (int)city.cityTier
then nextTier = (int)cityTier +1
so we say popRatio = InverseLerp(threshold[currentTier],threshold[nextTier],city.Pop) -so in essence, we now calculate the ratio inbetween the tier 1 and tier2 (town's windonw) to get when the 2 second products will be activated.
Makes sense?
This way we say calculate between 5000 and 10000 ratio with population that is for example 7500 at the moment, so Mathf.InverseLerp(5000,10000,7500) = 0.5;
so its working! now we just change for each product instead of 1.4, 1.7 to 0.4 and 0.7. and set the minimum tier is tier 2. (1 by enum value)
What this also changed, is that each new product that will be unlocked on tier3 for example, will actually just have set 0.4 or if there are 3 we can say, first 0.3, second 0.6, third 0.9...
So with this we solved the CityTier, we solved the ratio for each cityTier separately to again show the percentage until its unlocked which was very important for visual reference. And we set up the system much better and more predictable and logical then it was with using basePopulation and proportion for calculating city tier's. Now the structure is much more stable and logical. Each city has the same chance.
Addapting it to our existing structure, and improving the code . -update
So in order to improve and later be able to better adjust or change elements without searching through the code and changing values, I added the same as i had for other systems as well. Introduced scriptable object, that contains 6 values, which is 6 enums, but also has values for threshold. So we can just call from the database, compare and get the result, and not rely upon using spaghetti code in a way. Same logic all the same only we dont use int[] array but rather scriptable object combined with enum. For example:
So we can give the cityTier and as well set the threshold value.
So instead of doing for, we do like this:
and then we simply compare city.pop < threshold
calculatedTierIndex = (int)tier;
and GetThreshold(tier) is actually a public int method, that returns the value of threshold.
Simply said, foreach CityTierData data in allCityTiers
if(data.cityTier ==tier ){return tier.threshold
Hope that makes sense!!
It can probably be better,but for now this is not as easy for me hah.
Thank you!!!


Comments
Post a Comment