Skip to content

Re-add Spring.AddTeamResourceStats for Lua economy controllers#3032

Merged
sprunk merged 3 commits into
beyond-all-reason:resource-excess-callinfrom
keithharvey:resource-excess-callin-stats
Jun 30, 2026
Merged

Re-add Spring.AddTeamResourceStats for Lua economy controllers#3032
sprunk merged 3 commits into
beyond-all-reason:resource-excess-callinfrom
keithharvey:resource-excess-callin-stats

Conversation

@keithharvey

Copy link
Copy Markdown
Contributor

Ported from the eco branch. BAR's resource transfer controller moves shared pools via Spring.SetTeamResource on the gadget:ResourceExcess path; without this, sharing is miscounted as production/usage. Records sent/received/excess into team + lifetime stats without moving resources.

@keithharvey keithharvey force-pushed the resource-excess-callin-stats branch from 2cdb8bc to 0777126 Compare June 19, 2026 06:33
@keithharvey

Copy link
Copy Markdown
Contributor Author

@sprunk I did rebase master since we were pretty far behind.

@sprunk

sprunk commented Jun 19, 2026

Copy link
Copy Markdown
Collaborator

I think this should be just for the excess stat, since the others already have functions to adjust them.

@keithharvey keithharvey force-pushed the resource-excess-callin-stats branch from e88cdbb to 4813b7d Compare June 19, 2026 19:26
@keithharvey

keithharvey commented Jun 19, 2026

Copy link
Copy Markdown
Contributor Author

@sprunk
So ShareTeamResource can't represent that (unless there's another call that I am missing).

  1. it is 1:1 so every call forces sent==received, so it can't faithfully carry taxed sent/received. The tax that gets destroyed has nowhere to go.
  2. Pooled, not pairwise - the solver gives net per-team flows, no sender -> receiver pairs. Pairs would have to be synthesized (doable but only matters if we go this way).

Poking around for another way to do this now but yeah, that's one of the main reasons I moved away from the existing API originally, it just wasn't designed with the game doing the underlying math comprehensively in mind.

That said, there is a path that uses only existing calls if we accept lossy stats under tax:

  1. ShareTeamResource(sender -> receiver, net) - moves the net amount and records sent/received (both = net), after synthesizing pairs as in (2) above.
  2. SetTeamResource(sender, target) - drops the destroyed tax as a pure pool reduction (SetTeamResource touches no stats, so it doesn't pollute produced/used).
  3. AddTeamResourceStats(excess) - records waste only.

The catch is that ShareTeamResource being 1:1 makes sent the net delivered amount rather than the gross, and the taxed portion is destroyed silently - which is how it works today anyway, tax never lands in excess.

So the two viable options are: keep AddTeamResourceStats carrying gross sent/received/excess (faithful to the numbers the game computes), or take the ShareTeamResource + SetTeamResource route and accept sent==net under tax. I lean toward the former since it preserves the gross figures, but I'm happy either way.

@keithharvey keithharvey force-pushed the resource-excess-callin-stats branch from 4813b7d to e88cdbb Compare June 19, 2026 19:57
@sprunk

sprunk commented Jun 19, 2026

Copy link
Copy Markdown
Collaborator

Stats can be implemented in Lua, and for BAR specifically there are motions in that direction already (cf. beyond-all-reason/Beyond-All-Reason#7584, beyond-all-reason/Beyond-All-Reason#6862 and the others linked from discussion there). If you go this route you can design the stats to be whatever you want.

The engine's native stats implementation seems to be designed as a sort of ledger where every resource is accounted for, with spSetTeamResource (the one call that currently breaks this invariant) being meant to be used largely as initialisation. I think it's good to keep it that way, since it's elegant in simplicity and anybody unhappy with it can use Lua. The new gadget:ResourceExcess also breaks this invariant, which is why adding a callout to control it would be alright.

@keithharvey keithharvey force-pushed the resource-excess-callin-stats branch 2 times, most recently from 4813b7d to fd89cf0 Compare June 19, 2026 21:19
@keithharvey

keithharvey commented Jun 19, 2026

Copy link
Copy Markdown
Contributor Author

Aite the consumer side wasn't as bad as I imagined because of the way stats already worked over there. I was worried I'd have to unpack waterfill into a per-team munge step and that's a hot path, but it turned out to be like 4 lines of code so yay.

Note I renamed it to AddTeamResourceExcessStats to reflect its diminished scope.

@sprunk how do you want to do this? I'm currently targetting your branch with this PR but can open a new PR and switch it to master if that's easier. Merging this should make your PR the clean merge point.

@sprunk

sprunk commented Jun 22, 2026

Copy link
Copy Markdown
Collaborator

I don't mind this going either onto the ResourceExcess branch or directly to master, but either way it probably shouldn't have 264 commits though. The code itself looks alright.

@sprunk sprunk added the area: Lua API The Lua scripting API exposed to game mods, widgets, and gadgets label Jun 24, 2026
@keithharvey

keithharvey commented Jun 30, 2026

Copy link
Copy Markdown
Contributor Author

The 264 commits are a byproduct of the merge target being your branch, which is not rebased on master. Rebasing your branch then merging it should produce the desired single-commit merge. Or just force-pushing your branch here and merging master. I can rebase again whenever you're ready if that helps.

@sprunk sprunk force-pushed the resource-excess-callin branch from 024e0ce to cc28920 Compare June 30, 2026 00:12
Economy controllers that redistribute pools via Spring.SetTeamResource bypass the
engine's resource ledger, so per-frame excess would otherwise be miscounted as
production. This call records a team's excess (per-tick prev-excess + lifetime total)
without moving resources.

Scoped to excess only, as a plain amount: excess is the one quantity that legitimately
leaves the conservation ledger (cf. gadget:ResourceExcess). Conserved transfer stats
(sent/received) belong in Lua, where controllers can shape them freely.
@sprunk sprunk force-pushed the resource-excess-callin-stats branch from fd89cf0 to 938f165 Compare June 30, 2026 00:21

@sprunk sprunk left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good, just minor nits.

Comment thread rts/Lua/LuaSyncedCtrl.cpp Outdated
Comment thread rts/Lua/LuaSyncedCtrl.cpp Outdated
keithharvey and others added 2 commits June 29, 2026 23:37
@sprunk sprunk merged commit 48acdac into beyond-all-reason:resource-excess-callin Jun 30, 2026
4 checks passed
@sprunk

sprunk commented Jun 30, 2026

Copy link
Copy Markdown
Collaborator

Cool, thanks.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area: Lua API The Lua scripting API exposed to game mods, widgets, and gadgets

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants