Game.Tools.LoanSystem
Assembly:
Namespace: Game.Tools
Type: class
Base: GameSystemBase, ILoanSystem
Summary:
LoanSystem manages the city's loan state and provides APIs to request loan offers and change the city's loan. It enqueues loan-change requests into a NativeQueue and applies them on the simulation thread via a scheduled IJob (LoanActionJob). Loan interest and payments are calculated from economy parameters, city modifiers and the city's creditworthiness. The system is designed to be thread-friendly by using ComponentLookup and JobHandle synchronization for job scheduling and completion.
Fields
-
private CitySystem m_CitySystem
Holds a reference to the CitySystem used to obtain the city entity (m_CitySystem.City) for reading/writing city-level components (Loan, PlayerMoney, CityModifier buffer). -
private SimulationSystem m_SimulationSystem
Reference to the SimulationSystem used to obtain the current simulation frame index (m_SimulationSystem.frameIndex) for timestamping loan modifications. -
private NativeQueue<LoanAction> m_ActionQueue
Persistent NativeQueue used to enqueue loan change requests (LoanAction). These queued actions are consumed in a scheduled job (LoanActionJob) on update. -
private JobHandle m_ActionQueueWriters
JobHandle tracking writers/scheduling dependencies for the action queue. Used to synchronize before enqueuing or scheduling jobs. -
private EntityQuery m_EconomyParametersQuery
EntityQuery used to read economy parameters (EconomyParameterData) such as loan interest min/max range. -
private TypeHandle __TypeHandle
Compiler-generated container holding ComponentLookup handles (Loan, PlayerMoney). Assigned in OnCreateForCompiler to be used for job component access through InternalCompilerInterface. -
(nested)
private struct LoanActionJob
(not listed as a field but important)
Defines an IJob that dequeues LoanAction entries and applies them to the city entity, adjusting PlayerMoney and Loan components atomically inside the job.
Properties
-
public LoanInfo CurrentLoan { get; }
Returns the current loan information (LoanInfo) for the city by reading the Loan component on the city entity and converting m_Amount to a detailed LoanInfo via CalculateLoan. If no Loan component exists, returns default(LoanInfo). -
public int Creditworthiness { get; }
Gets the city's current creditworthiness by reading the Creditworthiness component on the city entity (Creditworthiness.m_Amount). Used to limit/clamp loan amounts and to compute interest.
Constructors
public LoanSystem()
Default constructor. The system initializes resources in OnCreate (sets up queries, system references and the native queue).
Methods
-
protected override void OnCreate()
Initializes the system: creates the economy parameters EntityQuery, acquires CitySystem and SimulationSystem references, and creates the persistent NativeQueue. -
protected override void OnDestroy()
Disposes of persistent resources (disposes the m_ActionQueue) and performs any necessary cleanup. -
protected override void OnUpdate()
If the action queue is not empty, builds and schedules a LoanActionJob that consumes the queue and applies loan changes to the city's components. Combines m_ActionQueueWriters with the system Dependency to ensure proper synchronization. -
public LoanInfo RequestLoanOffer(int amount)
Returns a loan offer (LoanInfo) for the requested amount after clamping it with ClampLoanAmount — useful for UI previews without modifying game state. -
public void ChangeLoan(int amount)
Enqueues a loan change action. Completes m_ActionQueueWriters to ensure all writers are synchronized before enqueuing, then enqueues a LoanAction with the clamped amount. The change will be applied by the scheduled LoanActionJob during OnUpdate. -
private int ClampLoanAmount(int amount)
Clamps the requested loan amount between a lower bound and the city's Creditworthiness. The lower bound prevents lowering the loan below what would be forced by available cash (it uses current PlayerMoney and the current loan amount). Ensures requested amounts are valid. -
public LoanInfo CalculateLoan(int amount)
Instance helper that reads economy parameters and city modifiers and delegates to the static CalculateLoan(amount, creditworthiness, modifiers, interestRange). -
public static LoanInfo CalculateLoan(int amount, int creditworthiness, DynamicBuffer<CityModifier> modifiers, float2 interestRange)
Static calculation that, given an amount, creditworthiness, city modifiers and interest min/max range, computes LoanInfo (amount, daily interest rate, daily payment). If amount <= 0 returns default(LoanInfo). -
public static float GetTargetInterest(int loanAmount, int creditworthiness, DynamicBuffer<CityModifier> cityEffects, float2 interestRange)
Computes the target daily interest rate (as a fraction) based on a lerp of interestRange using the ratio loanAmount/creditworthiness, applies city modifiers of type LoanInterest, and returns a minimum of 0. The returned value is 0.01 * percentage value (e.g. 1% => 0.01f). -
private void __AssignQueries(ref SystemState state)
Compiler-helper used to set up entity queries (presently a no-op other than creating/disposing a temporary EntityQueryBuilder). Called by OnCreateForCompiler. -
protected override void OnCreateForCompiler()
Compiler-time setup method that calls __AssignQueries and assigns component lookup handles via __TypeHandle.__AssignHandles. -
(nested)
private struct TypeHandle
Contains ComponentLookup fields for Loan and PlayerMoney and provides __AssignHandles to initialize them from SystemState. Used by jobs via InternalCompilerInterface.GetComponentLookup. -
(nested)
private struct LoanActionJob.Execute() : System.Void
Job execution loop: while dequeuing LoanAction entries, it: - Reads PlayerMoney and current Loan from the city entity.
- Adjusts PlayerMoney by adding (newAmount - oldLoanAmount).
- Writes updated PlayerMoney back to the city entity.
- Writes a new Loan component with m_Amount set to newAmount and m_LastModified set to the current simulation frame index. This effectively applies the loan change atomically from the job.
Usage Example
// Example: Request an offer and apply a loan change from a MonoBehaviour or other script.
[Preserve]
void ExampleUsage()
{
// Acquire the managed World and LoanSystem instance (example API; adjust to your mod context)
var loanSystem = Unity.Entities.World.DefaultGameObjectInjectionWorld
.GetExistingSystemManaged<Game.Tools.LoanSystem>();
if (loanSystem == null) return;
// Request a preview offer for a 50,000 loan
var offer = loanSystem.RequestLoanOffer(50000);
Debug.Log($"Offer: amount={offer.m_Amount}, dailyInterest={offer.m_DailyInterestRate}, dailyPayment={offer.m_DailyPayment}");
// Apply the loan change (this enqueues the action; it will be applied by the system job)
loanSystem.ChangeLoan(50000);
}
{{ Additional notes: - Threading: LoanSystem uses a persistent NativeQueue and schedules an IJob (LoanActionJob) to consume and apply queued loan changes. Synchronization is handled via JobHandle (m_ActionQueueWriters and base.Dependency). Callers invoking ChangeLoan ensure safe ordering by the system completing the writer handle before enqueueing. - Calculations: Interest is derived from economy parameters (EconomyParameterData.m_LoanMinMaxInterestRate) and modified by city modifiers (CityModifierType.LoanInterest). Daily payment is rounded using Mathf.RoundToInt(amount * dailyInterestRate). - Integration: LoanSystem depends on CitySystem and SimulationSystem. It reads/writes city-level components (Loan, PlayerMoney, Creditworthiness, CityModifier buffer) via ECS ComponentLookup/GetComponentData/GetBuffer. }}