• We have updated our Community Code of Conduct. Please read through the new rules for the forum that are an integral part of Paradox Interactive’s User Agreement.

nucleartux

Sergeant
7 Badges
Jun 27, 2024
66
42
  • Magicka
  • Cities: Skylines
  • Cities: Skylines - After Dark
  • Cities: Skylines - Mass Transit
  • Cities: Skylines - Green Cities
  • Cities: Skylines Industries
  • Cities: Skylines - Campus

Information​

When reporting a crash, stability or performance problems, please use the Report a Crash button on the earlier screen​

[CLICK] I understand

Required​

Summary​

Economy Bugs Combined

Steps to reproduce​

They are below

Expected Result​

They are below

Actual Result​

They are below

Game Version​

1.2.0f

What mods do you have installed?​

ExtendedTooltip

Affected Feature​

  • Gameplay

Platform​

  • Steam

Additional Information​

Additional Information​

Hello developers,

I've made a mod that fixes economy bugs. You can check it out here: https://github.com/nucleartux/CS2BetterEconomy (all bugs are marked with a "// bug" comment in the code).

However, I think explaining it here would be a nice addition:

0. In CompanyMoveAwaySystem.cs, you have:
if (companyTotalWorth < m_EconomyParameters.m_CompanyBankruptcyLimit || random.NextInt(100) < companyMoveAwayChance)
{
m_CommandBuffer.AddComponent(unfilteredChunkIndex, entity, default(MovingAway));
}
This basically says, "move away if the company is below the bankruptcy limit OR the chance is above zero." This chance is calculated using taxes and efficiency. After thinking about it for a long time, I concluded that this is a bug.
Even with a slight chance of moving away, all companies in the city will eventually move away, making the economy meaningless. Instead, the condition should use "AND" instead of "OR."
With this change, companies will move away only if they have a negative balance. This makes player actions more meaningful. For example, players can slightly increase taxes without losing companies immediately. They can wait to collect money, as companies will likely pause their development instead. Then, players can return taxes to their previous levels.

1. In BuildingUpkeepSystem.cs, you have the following line:
num9 = -m_BuildingConfigurationData.m_BuildingConditionDecrement * (int)math.pow(2f, (int)spawnableBuildingData.m_Level) * math.max(1, dynamicBuffer.Length);

For some reason, this is always 0 in my case. As a result, buildings never experience a condition decrement and never collapse. I don’t know the exact reason, but setting the minimal value to 1 works:

num9 = -math.max(1, m_BuildingConfigurationData.m_BuildingConditionDecrement * (int)math.pow(2f, (int)spawnableBuildingData.m_Level) * math.max(1, dynamicBuffer.Length));

2. In the same file, a few lines below, you have:

int price = num / dynamicBuffer.Length;
m_UpkeepExpenseQueue.Enqueue(new UpkeepPayment
{
m_RenterEntity = dynamicBuffer[k].m_Renter,
m_Price = price // price is positive here
});

Then you handle this queue as follows:

if (m_Resources.HasBuffer(item.m_RenterEntity))
{
EconomyUtils.AddResources(Resource.Money, item.m_Price, m_Resources[item.m_RenterEntity]);
}

If I understand correctly, this is the building upkeep expense system. However, the price is always positive (I even debugged this value to confirm), so instead of subtracting money from the renter, it is added to them.

3. In ProcessingCompanySystem.cs, you have:

int num11 = (int)((float)num * EconomyUtils.GetIndustrialPrice(output.m_Resource, m_ResourcePrefabs, ref m_ResourceDatas) - (float)num4 * EconomyUtils.GetIndustrialPrice(input.m_Resource, m_ResourcePrefabs, ref m_ResourceDatas) + (float)num5 * EconomyUtils.GetIndustrialPrice

I think the intended calculation is:

num11 = output - (input1 + input2) = output - input1 - input2

But since num4 and num5 are already negative (I double-checked in the game), the calculation becomes:

num11 = output + input1 - input2

4. In PropertyRenterSystem.cs, there is a bug in the fee calculation for garbage:
When collecting the fee and adding it to the player's value, num is divided by updates per day:

if (m_ProvidedGarbageService)
{
m_StatisticsEventQueue.Enqueue(new StatisticsEvent
{
m_Statistic = StatisticType.Income,
m_Change = 1f * (float)num / (float)kUpdatesPerDay,
m_Parameter = 12
});
m_FeeQueue.Enqueue(new ServiceFeeSystem.FeeEvent
{
m_Amount = 1f,
m_Cost = 1f * (float)num / (float)kUpdatesPerDay,
m_Outside = false,
m_Resource = PlayerResource.Garbage
});
}

However, later in the same file:

int num2 = MathUtils.RoundToIntRandom(ref random, 1f * (float)num / (float)dynamicBuffer.Length);
...
if (!m_Storages.HasComponent(renter))
{
EconomyUtils.AddResources(Resource.Money, -num2, m_Resources[renter]);
}


The subtraction does not divide by updates per day. This is very noticeable in the game, as households cannot maintain a positive balance due to this bug.

5. In LeisureSystem.cs, the issue lies in the calculation of money added and subtracted:

EconomyUtils.AddResources(Resource.Money, Mathf.RoundToInt(num), resources);
EconomyUtils.AddResources(Resource.Money, -Mathf.RoundToInt(num), resources2);


Previously, num was calculated as:

num = marketPrice * serviceConsuming * serviceMultiplier * kLeisureConsumeAmount;


But when the resource is subtracted, only kLeisureConsumeAmount is used. I suspect the price (or amount) is incorrect. It should be something like marketPrice * serviceMultiplier. I fixed it by adjusting the calculation to multiply the amount by serviceConsuming.


6. When industries export their resources (at least to outside connections), they receive money twice: once when the truck leaves the building and again when it returns from the outside connection.

I fixed this in ResourceExporterSystem.cs by removing this line:

EconomyUtils.AddResources(Resource.Money, num, m_Resources[item.m_Seller]);

However, I’m not entirely sure if this fix is correct. Still, the bug exists and needs to be addressed.

7. There is a bug with the profitability of processing companies. In the game, profitability jumps from 0 to 100 every tick. This happens because of a loss of precision in ProcessingCompanySystem.cs:

int num = MathUtils.RoundToIntRandom(ref random, 1f * (float)companyProductionPerDay / (float)EconomyUtils.kCompanyUpdatesPerDay);


This variable, used later in profitability calculations, needs to be a float.

Save Game​



Other Attachments​



 
  • 2Like
  • 1
  • 1
Reactions:
With this change, companies will move away only if they have a negative balance. This makes player actions more meaningful. For example, players can slightly increase taxes without losing companies immediately. They can wait to collect money, as companies will likely pause their development instead. Then, players can return taxes to their previous levels.
This kind of runs counter to what occurs in real life. Companies will move away from a city even if they don't have a negative balance. In-game, this simulates the concept of companies simply moving away to a city with lower taxes. So the way it behaves in game I would think is intended and not a bug.
 
Another bug.
There are multiple places where the game collects untaxed income to apply taxes later, each for different types of companies: service, extraction, and processing.
In all these places, except for processing companies (usually industrial companies), there is a check for negative values. Because of this, a bug is possible: if a company has negative income, instead of subtracting tax money, the game will add money to this company.
 
  • 1Like
Reactions:
> For some reason, this is always 0 in my case. As a result, buildings never experience a condition decrement and never collapse. I don’t know the exact reason, but setting the minimal value to 1 works

Agreed, I started my current city back in September last year and I have never seen a building collapse occur. I’ve also never seen a building become formally “abandoned”, only emptied (notifications before emptying: too high rent if residential, too few workers if industrial/commercial).
 
  • 1
Reactions: