Add resource collector pipeline; migrate population growth and country score#33
Merged
Merged
Conversation
…y score Introduces IResourceCollector/ResourceCollectorRegistry/ResourceCollector, mirroring the BotFeatureRegistry pattern, so a ResourceEffect's Value can be recomputed from world state each time it is processed instead of staying static. ResourceSystem.Update gains optional collectorRegistry/ resourceIdUpdateOrder parameters that resolve-then-apply effects resourceId by resourceId in a configured order, so a later resourceId's collector can read an earlier one's already-applied value within the same tick. Existing call sites are unaffected (null/empty args reproduce the old single-pass behavior exactly). Migrates three mechanics onto the new pipeline: - Province population growth becomes a self-referential Monthly collector effect; ProvincePopulationGrowthSystem is removed. - New country_population resource, fed by a collector that sums the population of every province currently owned by that country. - country_score moves from a Score component composed onto Country to a Resource fed by a collector reading country_population * coefficient. CountryScoreSystem.GetScore is preserved as a query over the new storage. OrgScoreSystem.Recompute and VisualStateConverter.UpdateCountryScore are updated to read scores via GetScore instead of a Country+Score archetype. InitSystem.Run gains a bootstrap resolve-then-apply pass (previousTime == currentTime, so only Instant effects fire) so country_population/ country_score seed correctly before OrgScoreSystem.Recompute reads them, without disturbing province population's Monthly-only growth on the first tick. Adds resourceIdUpdateOrder to GameSettings/game_settings.json (default: population, country_population, country_score) and updates ecs_patterns.md's composition example to reflect the move. Note: Assets/Plugins/Core/*.dll are not rebuilt in this commit — the .NET SDK is unavailable in this sandbox (network egress to the dotnet CDN is blocked, and apt's dotnet packages 404). dotnet build src/GlobalStrategy.Core.sln -c Release and dotnet test src/GlobalStrategy.Core.sln still need to be run in an environment with the SDK before this is considered verified. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GLxj7CXoSVmUHzKZe6PSxa
- Fix stale Score.cs comment still describing the removed
CountryScoreSystem.Update/Recompute-driven Country+Score composition.
- Document the silent-no-op risk when a ResourceCollector-tagged effect's
resourceId isn't listed in resourceIdUpdateOrder.
- Add CountryScoreCollector.ResourceId ("country_score") as the shared
constant, matching the pattern already used for "population"/
"country_population", and reference it from InitSystem.cs,
CountryScoreSystem.GetScore, and OrgScoreSystemTests.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GLxj7CXoSVmUHzKZe6PSxa
Adds a fourth resourceId, recruits, on top of the resource collector pipeline: seeds at recruitsInitialPercent% of country_population via an Instant collector effect, grows monthly by recruitsMonthlyIncreasePercent% of the current country_population via a Monthly collector effect, clamped to recruitsCapPercent% of country_population (never negative, so recruits never shrinks when population — and its cap — drops). No new mechanism: two IResourceCollector implementations (RecruitsSeedCollector, RecruitsGrowthCollector) plugged into the existing pipeline, and recruits is appended to resourceIdUpdateOrder after country_population so both collectors always read that pass's already-aggregated total. Extracts src/Game.Systems/ResourceQuery.cs (GetValue(world, ownerId, resourceId)) as the single shared "look up a country-owned resource by id" implementation, and refactors CountryScoreCollector.Compute, CountryScoreSystem.GetScore, and ResourceSystem's internal collector-resolve lookup to all go through it instead of three near-identical inline scans. ResourceCollectorRegistry.CreateDefault gains three new parameters (recruitsInitialPercent, recruitsCapPercent, recruitsMonthlyIncreasePercent); both call sites (GameLogic's constructor and InitSystem.Run's bootstrap resolve pass) are updated. Three new GameSettings/game_settings.json tunables added (defaults: 5/15/1). No VisualState/VisualStateConverter change — recruits' total and last-applied-delta already surface through the existing generic Resource/ResourceEffect display path the same way gold does. Note: Assets/Plugins/Core/*.dll are not rebuilt in this commit — the .NET SDK is unavailable in this sandbox (network egress to the dotnet CDN is blocked, and apt's dotnet packages 404). dotnet build src/GlobalStrategy.Core.sln -c Release and dotnet test src/GlobalStrategy.Core.sln still need to be run in an environment with the SDK before this is considered verified. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GLxj7CXoSVmUHzKZe6PSxa
Eliminates the Score component and its OrgScoreSystem/CountryScoreSystem wrappers now that both country and org scores run through the same generic Resource/ResourceEffect/ResourceCollector pipeline as population/recruits, adding PayType.Daily so org_score can recompute on day boundaries where control changes land. Also tightens InitSystem to stop calling other systems directly (ProvinceOwnershipSystem.Seed, ResourceSystem.Update) - those now run from GameLogic's regular per-tick pipeline, self-gated by the existing IsInitialized marker or by Instant effects self-destroying after their first apply, per the new "no system-to-system calls" ECS rule. Consolidates every resource id string (gold/population/country_score/ org_score/recruits/etc.) that was previously duplicated across collector classes and call sites into a single ResourceDefinitions class in Game.Configs, the one project every consumer already depends on. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Introduces IResourceCollector/ResourceCollectorRegistry/ResourceCollector,
mirroring the BotFeatureRegistry pattern, so a ResourceEffect's Value can be
recomputed from world state each time it is processed instead of staying
static. ResourceSystem.Update gains optional collectorRegistry/
resourceIdUpdateOrder parameters that resolve-then-apply effects resourceId
by resourceId in a configured order, so a later resourceId's collector can
read an earlier one's already-applied value within the same tick. Existing
call sites are unaffected (null/empty args reproduce the old single-pass
behavior exactly).
Migrates three mechanics onto the new pipeline:
effect; ProvincePopulationGrowthSystem is removed.
population of every province currently owned by that country.
Resource fed by a collector reading country_population * coefficient.
CountryScoreSystem.GetScore is preserved as a query over the new storage.
OrgScoreSystem.Recompute and VisualStateConverter.UpdateCountryScore are
updated to read scores via GetScore instead of a Country+Score archetype.
InitSystem.Run gains a bootstrap resolve-then-apply pass (previousTime ==
currentTime, so only Instant effects fire) so country_population/
country_score seed correctly before OrgScoreSystem.Recompute reads them,
without disturbing province population's Monthly-only growth on the first
tick.
Adds resourceIdUpdateOrder to GameSettings/game_settings.json (default:
population, country_population, country_score) and updates
ecs_patterns.md's composition example to reflect the move.
Note: Assets/Plugins/Core/*.dll are not rebuilt in this commit — the .NET
SDK is unavailable in this sandbox (network egress to the dotnet CDN is
blocked, and apt's dotnet packages 404). dotnet build
src/GlobalStrategy.Core.sln -c Release and dotnet test
src/GlobalStrategy.Core.sln still need to be run in an environment with the
SDK before this is considered verified.
Co-Authored-By: Claude Sonnet 5 noreply@anthropic.com
Claude-Session: https://claude.ai/code/session_01GLxj7CXoSVmUHzKZe6PSxa