Skip to content

Game.Simulation.TaxSystem

Assembly: Game
Namespace: Game.Simulation

Type: class

Base: GameSystemBase, ITaxSystem, IDefaultSerializable, ISerializable, IPostDeserialize

Summary:
TaxSystem manages all city tax logic: stores and clamps tax rates, schedules jobs that collect taxes from residential/commercial/industrial entities, computes estimated tax incomes from statistics, and handles serialization of tax settings. It exposes APIs to get/set global and area/resource/job-level tax rates, apply district policy modifiers, and obtain estimated income/expense values for UI and simulation decisions. Internally it schedules a Burst-compiled IJobChunk (PayTaxJob) that deducts money from entities' resources and pushes statistics events. It also respects game mode multipliers (ModeSettingData) and tax parameter limits (TaxParameterData).


Fields

  • public static readonly int kUpdatesPerDay
    Constant specifying how many tax updates happen per day (32). Used when computing update frames and converting untaxed income to per-day numbers.

  • private NativeArray<int> m_TaxRates
    Array storing the base/global tax rate at index 0 and offsets for area/resource/job-level rates in the remaining slots. Persisted across save/load and clamped against TaxParameterData limits.

  • private EntityQuery m_ResidentialTaxPayerGroup
    EntityQuery used to find residential tax payer entities for scheduling the PayTaxJob (households).

  • private EntityQuery m_CommercialTaxPayerGroup
    EntityQuery for commercial tax payer entities (commercial service buildings / businesses).

  • private EntityQuery m_IndustrialTaxPayerGroup
    EntityQuery for industrial tax payer entities (processing companies / industrial buildings).

  • private EntityQuery m_TaxParameterGroup
    Query to access TaxParameterData singleton (limits and rule parameters).

  • private EntityQuery m_GameModeSettingQuery
    Query to access ModeSettingData singleton (game mode multipliers such as m_TaxPaidMultiplier).

  • private CityStatisticsSystem m_CityStatisticsSystem
    Reference to CityStatisticsSystem for queuing statistic events and reading statistics used by estimators.

  • private SimulationSystem m_SimulationSystem
    Reference to SimulationSystem used to compute the current update frame.

  • private ResourceSystem m_ResourceSystem
    Reference to ResourceSystem for iterating resources and mapping resources → prefabs.

  • private TaxParameterData m_TaxParameterData
    Cached TaxParameterData containing allowed ranges for different tax categories; refreshed from m_TaxParameterGroup when needed.

  • private float3 m_TaxPaidMultiplier
    Multiplier applied to tax payments per area type (x=residential, y=commercial, z=industrial). Taken from ModeSettingData if enabled; otherwise defaults to (1,1,1).

  • private JobHandle m_Readers
    Combined JobHandle of external readers that must be synchronized with this system (used by AddReader/Readers).

  • private TypeHandle __TypeHandle
    Compiler-generated struct holding Entity/Component/Buffer handles used by the internal job scheduling paths.

  • private struct PayTaxJob (nested)
    Burst-compiled IJobChunk that iterates taxpayers for a specific IncomeSource (residential/commercial/industrial), calculates tax to pay, deducts money from their Resources buffer, and enqueues StatisticsEvent(s). It uses BufferLookup/ComponentLookup handles and respects UpdateFrame shared component to only process entities on the correct frame.

Properties

  • public int TaxRate { get; set; }
    Gets or sets the global base tax rate (m_TaxRates[0]). Setter clamps to m_TaxParameterData.m_TotalTaxLimits and then enforces area-specific limits via EnsureAreaTaxRateLimits for Residential, Commercial, Industrial, and Office.

  • public JobHandle Readers { get; }
    Returns the combined JobHandle for registered readers (m_Readers). Use AddReader to add dependencies.

  • public override int GetUpdateInterval(SystemUpdatePhase phase)
    Returns the system update interval used by the engine; uses kUpdatesPerDay to compute the frequency.

Constructors

  • public TaxSystem()
    Default constructor (preserved). Initialization of runtime data occurs in OnCreate.

Methods

  • protected override void OnCreate() : System.Void
    Initializes queries and subsystems, allocates m_TaxRates (size 92), sets defaults (m_TaxRates[0]=10), sets m_TaxPaidMultiplier to (1,1,1), and calls RequireForUpdate(m_TaxParameterGroup) so system updates only when parameter data is present. Also caches references to CityStatisticsSystem, SimulationSystem, ResourceSystem.

  • protected override void OnDestroy() : System.Void
    Disposes persistent NativeArray m_TaxRates and calls base.OnDestroy.

  • protected override void OnUpdate() : System.Void
    Main runtime update. Ensures TaxParameterData is loaded, computes updateFrame, prepares ResourcePrefabs, and schedules three PayTaxJob instances (residential, commercial, industrial) as parallel jobs. Collects JobHandles and sets base.Dependency accordingly. Also registers writers with CityStatisticsSystem and uses m_TaxPaidMultiplier per job.

  • public static int GetTax(TaxPayer payer) : int
    Utility to compute the tax amount from a TaxPayer: round(0.01 * payer.m_AverageTaxRate * payer.m_UntaxedIncome).

  • public void Serialize<TWriter>(TWriter writer) where TWriter : IWriter : System.Void
    Writes the length and contents of m_TaxRates to a writer for saving.

  • public void Deserialize<TReader>(TReader reader) where TReader : IReader : System.Void
    Reads tax rates back from save data. Handles format/version differences (e.g., older formats without averageTaxRate or fish resource tags) and applies migrations (shifting array entries, setting fish rates to 0) when needed.

  • public void PostDeserialize(Context context) : System.Void
    After deserialization this sets sensible defaults for very old versions that predate averageTaxRate by resetting the array.

  • public void SetDefaults(Context context) : System.Void
    Sets default tax values (m_TaxRates[0]=10, others 0).

  • public NativeArray<int> GetTaxRates() : NativeArray
    Returns the internal NativeArray containing all tax rate offsets and base value. Caller must not dispose.

  • public void AddReader(JobHandle reader) : System.Void
    Combines a JobHandle from an external reader with m_Readers so the TaxSystem can respect external dependencies.

  • public int GetTaxRate(TaxAreaType areaType) : int
    Returns tax rate for the given area type using the current m_TaxRates.

  • public static int GetTaxRate(TaxAreaType areaType, NativeArray<int> taxRates) : int
    Static variant that computes base + offset for areaType from a provided taxRates array.

  • public int2 GetTaxRateRange(TaxAreaType areaType) : int2
    Returns a min/max allowed tax rate for the given area type. For Residential this includes job-level modifiers; for others it uses resource ranges.

  • public int GetModifiedTaxRate(TaxAreaType areaType, Entity district, BufferLookup<DistrictModifier> policies) : int
    Returns modified tax rate in a district, applying district modifiers (e.g., LowCommercialTax). Static overload also exists.

  • private void EnsureTaxParameterData() : System.Void
    Ensures m_TaxParameterData is valid (refetches from m_TaxParameterGroup singleton if uninitialized).

  • public void SetTaxRate(TaxAreaType areaType, int rate) : System.Void
    Sets the effective tax for the areaType by storing an offset relative to base tax (m_TaxRates[areaType] = rate - base) and enforces limits.

  • private void EnsureAreaTaxRateLimits(TaxAreaType areaType) : System.Void
    Clamps and enforces per-area and per-resource/job limits based on m_TaxParameterData. Also iterates resources and job levels to ensure sub-rates obey allowed ranges.

  • private void EnsureJobLevelTaxRateLimits(int jobLevel) : System.Void
    Enforces job-level tax limits for a single residential job level.

  • private void ClampResidentialTaxRates() : System.Void
    If job-level offsets collectively exceed allowed ranges, this method redistributes adjustments to keep global/respective offsets consistent.

  • private int2 GetJobLevelTaxRateRange() : int2
    Returns min/max of the job-level offsets (m_TaxRates[5..9]).

  • private void EnsureResourceTaxRateLimits(TaxAreaType areaType, Resource resource) : System.Void
    Enforces resource-specific tax limits for commercial/industrial/office categories.

  • private void ClampResourceTaxRates(TaxAreaType areaType) : System.Void
    When resource-specific offsets collectively exceed allowed limits, this redistributes adjustments and applies offset corrections across taxable resources.

  • private int2 GetResourceTaxRateRange(TaxAreaType areaType) : int2
    Computes min/max offsets across all taxable resources for the given area type.

  • private int GetZeroOffset(TaxAreaType areaType) : int
    Returns the index offset used in m_TaxRates for the zero-based slot corresponding to resource arrays: 10 for Commercial, 51 for Industrial/Office. Throws for Residential.

  • Residential/commercial/industrial/office convenience APIs:

  • public int GetResidentialTaxRate(int jobLevel) / static overload
  • public void SetResidentialTaxRate(int jobLevel, int rate)
  • public int GetCommercialTaxRate(Resource resource) / static overload
  • public void SetCommercialTaxRate(Resource resource, int rate)
  • public int GetIndustrialTaxRate(Resource resource) / static overload
  • public void SetIndustrialTaxRate(Resource resource, int rate)
  • public int GetOfficeTaxRate(Resource resource) / static overload
  • public void SetOfficeTaxRate(Resource resource, int rate)
    Each getter composes base + area offset + resource/job offset. Setters store offsets and call Ensure... and Clamp... helpers.

  • public int GetTaxRateEffect(TaxAreaType areaType, int taxRate) : int
    Placeholder method that currently returns 0 in this code (could be intended to compute some effect on demand).

  • Estimation methods for UI/prediction:

  • public int GetEstimatedTaxAmount(TaxAreaType areaType, TaxResultType resultType, NativeParallelHashMap<...> statisticsLookup, BufferLookup<CityStatistic> stats)
  • Static helpers: GetEstimatedResidentialTaxIncome, GetEstimatedCommercialTaxIncome, GetEstimatedIndustrialTaxIncome, GetEstimatedOfficeTaxIncome
    These compute estimated tax income/expense using statistics values (e.g., StatisticType.*TaxableIncome) multiplied by the configured tax rate and divided by 100.

  • private static bool MatchesResultType(int amount, TaxResultType resultType) : bool
    Utility used by GetEstimatedTaxAmount to filter returned totals based on whether the caller wants Income, Expense, Any, etc.

  • Compiler/serialization helper methods (__AssignQueries, OnCreateForCompiler, __TypeHandle.__AssignHandles)
    These are support generated methods used by the DOTS compiler integration and should not be needed by typical modders.

Usage Example

// Example: change base tax and a resource-specific commercial tax, then query an estimate.
var taxSystem = World.DefaultGameObjectInjectionWorld.GetExistingSystemManaged<Game.Simulation.TaxSystem>();

// Set global base tax to 12%
taxSystem.TaxRate = 12;

// Set commercial tax for Entertainment resource to 15% total
taxSystem.SetCommercialTaxRate(Resource.Entertainment, 15);

// Read residential tax rate for job level 0 (low level)
int lowResRate = taxSystem.GetResidentialTaxRate(0);

// Get an estimated commercial income (Income-only) for UI reporting
int estimatedCommercialIncome = taxSystem.GetEstimatedTaxAmount(
    TaxAreaType.Commercial,
    TaxResultType.Income,
    cityStatisticsLookup, // NativeParallelHashMap<StatisticsKey, Entity>
    cityStatisticsBufferLookup // BufferLookup<CityStatistic>
);

Notes for modders: - Tax rates are stored as a base (index 0) + offsets. When setting rates you usually call the Set* methods (they store offsets and enforce limits). - Many methods accept or return NativeArray or NativeParallelHashMap and BufferLookup — these are DOTS/native containers; be careful with thread safety and job dependencies. - Tax collection runs in Burst jobs (PayTaxJob). If you need to read resources modified by tax collection you should use AddReader to add your JobHandle to m_Readers (or combine dependencies) so reads/writes are synchronized. - Serialization handles older save formats; if adding new tax-related fields be sure to extend Serialize/Deserialize/PostDeserialize as appropriate.