Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reduce network burden of the hunger system #32986

Open
wants to merge 6 commits into
base: master
Choose a base branch
from

Conversation

Centronias
Copy link
Contributor

@Centronias Centronias commented Oct 24, 2024

About the PR

Replace HungerComponent's CurrentHunger with HungerSystem.GetHunger, which calculates the current hunger value from an initial value, a time when that initial value was set, and a constant decay rate.

Why / Balance

#28070

Technical details

  • HungerComponent no longer has CurrentHunger, and instead has LastAuthoritativeHungerValue and LastAuthoritativeHungerChangeTime
  • Replaced all usages of HungerComponent.CurrentHunger with HungerSystem.GetHunger, which calculates the current hunger value by predicting the decay since the last authoritative update:
    • LastAuthoritativeHungerValue - (IGameTiming.CurrTime - LastAuthoritativeHungerChangeTime) * ActualDecayRate
  • HungerSystem.Update now only looks to update the current hunger threshold (because there's no value to update)
  • Added HungerSystem.SetAuthoritativeHungerValue, which sets LastAuthoritativeHungerValue and LastAuthoritativeHungerChangeTime and dirties the component, causing those values to get pushed to the client, resetting the "current" calculation's basepoint.
  • HungerSystem.SetHunger and anything that modifies the current threshold call HungerSystem.SetAuthoritativeHungerValue to ensure any unpredictable changes are replicated to the client.

Media

Before:
(With non-game-logic-altering modifications made to raise an event on HungerComponent replication + popup creation when getting that event)

hunger-before.mp4

After:
(With non-game-logic-altering modifications made to raise an event on HungerComponent replication + popup creation when getting that event; and create a popup on every HungerSystem update tick)

hunger.mp4

Requirements

Breaking changes

  • HungerComponent's CurrentHunger no longer exists and must be replaced by a call to HungerSystem.GetHunger

Changelog
My understanding is that this is a totally under-the-hood change, so no CL.

@Centronias
Copy link
Contributor Author

I'll do the same thing to thirst if this PR doesn't get obliterated for my implementation.

@slarticodefast
Copy link
Member

I'll do the same thing to thirst if this PR doesn't get obliterated for my implementation.

Ideally someone finishes this derelict PR to combine the hunger and thirst systems into satiation #27481
But until then it should be fine to improve things step by step 👍

@PJB3005 PJB3005 self-assigned this Oct 28, 2024
Copy link
Member

@PJB3005 PJB3005 left a comment

Choose a reason for hiding this comment

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

This is absolutely not the right way to do this. The issue you linked literally explains the correct way to fix it instead. Do that.

And do not do random style changes/refactors in unrelated PRs.

@@ -15,9 +15,10 @@ public sealed partial class Hunger : EntityEffectCondition

public override bool Condition(EntityEffectBaseArgs args)
{
if (args.EntityManager.TryGetComponent(args.TargetEntity, out HungerComponent? hunger))
if (args.EntityManager.TryGetComponent(args.TargetEntity, out HungerComponent? hunger) &&
args.EntityManager.SystemOrNull<HungerSystem>() is { } hungerSystem)
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I don't know if args.EntityManager.SystemOrNull<HungerSystem>() is the right thing to do here, but I am not sure how else to access the system.

Copy link
Member

Choose a reason for hiding this comment

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

Just use GetEntitySystem?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The only GetEntitySystem I could find is on IEntitySystemManager which, I guess, would need to be injected, but I assume [Dependency]s can't be injected into non-systems like this.

Instead, I've changed it to just do args.EntityManager.System<...>(), based on

return args.EntityManager.System<TagSystem>().HasTag(tag, Tag) ^ Invert;

doing that same thing.

If this is still not the right thing, do you mind providing me with a bit more guidance?

@github-actions github-actions bot added the Status: Needs Review This PR requires new reviews before it can be merged. label Oct 28, 2024
@@ -1686,7 +1686,7 @@
Dead: 0
baseDecayRate: 0.04
- type: Hunger
currentHunger: 25 # spawn with Okay hunger state
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This name change definitely sucks, but I don't know a way around it.

It would be good for currentHunger or startingHunger to be the field in the yaml, but it would, I think, not be good to have either of those names show up in-game in something like ViewVariables.

Copy link
Member

Choose a reason for hiding this comment

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

This name change definitely sucks, but I don't know a way around it.

It would be good for currentHunger or startingHunger to be the field in the yaml, but it would, I think, not be good to have either of those names show up in-game in something like ViewVariables.

[ViewVariables(VVAccess.ReadOnly)] it.

Also I'm looking at the code, does setting this data field from YAML even work? It looks like it would always get replaced by the randomized amount selected in OnMapInit. (Note that this doesn't appear to be an issue with your PR, just an observation).

Copy link
Contributor Author

@Centronias Centronias Oct 30, 2024

Choose a reason for hiding this comment

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

It looks like this was changed with the last rewrite of all of this:
https://github.com/space-wizards/space-station-14/pull/14939/files#diff-7ff03c169eb454aed40cb0979bd1d81f65ce0db09590d25191682c783e7ac344L131
(PR line links never work for me, but it's this:

)

Should I get rid of the fields in the yaml, since they don't do anything now?

Copy link
Member

Choose a reason for hiding this comment

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

Your choice I suppose

@@ -15,9 +15,10 @@ public sealed partial class Hunger : EntityEffectCondition

public override bool Condition(EntityEffectBaseArgs args)
{
if (args.EntityManager.TryGetComponent(args.TargetEntity, out HungerComponent? hunger))
if (args.EntityManager.TryGetComponent(args.TargetEntity, out HungerComponent? hunger) &&
args.EntityManager.SystemOrNull<HungerSystem>() is { } hungerSystem)
Copy link
Member

Choose a reason for hiding this comment

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

Just use GetEntitySystem?

Content.Shared/Nutrition/EntitySystems/HungerSystem.cs Outdated Show resolved Hide resolved
@@ -120,7 +151,7 @@ private void UpdateCurrentThreshold(EntityUid uid, HungerComponent? component =
return;
component.CurrentThreshold = calculatedHungerThreshold;
DoHungerThresholdEffects(uid, component);
Dirty(uid, component);
SetAuthoritativeHungerValue((uid, component), GetHunger(component));
Copy link
Member

Choose a reason for hiding this comment

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

Why is this necessary?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

My thinking is any time the threshold changes, the "start point" values should be updated as well.
I suppose that's not strictly true as the only change that necessitates an update is a change to the decay rate. So I'll move this call down to exactly where the decay rate is modified.

@@ -1686,7 +1686,7 @@
Dead: 0
baseDecayRate: 0.04
- type: Hunger
currentHunger: 25 # spawn with Okay hunger state
Copy link
Member

Choose a reason for hiding this comment

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

This name change definitely sucks, but I don't know a way around it.

It would be good for currentHunger or startingHunger to be the field in the yaml, but it would, I think, not be good to have either of those names show up in-game in something like ViewVariables.

[ViewVariables(VVAccess.ReadOnly)] it.

Also I'm looking at the code, does setting this data field from YAML even work? It looks like it would always get replaced by the randomized amount selected in OnMapInit. (Note that this doesn't appear to be an issue with your PR, just an observation).

@@ -23,6 +24,7 @@ public sealed class HungerSystem : EntitySystem
[Dependency] private readonly MobStateSystem _mobState = default!;
[Dependency] private readonly MovementSpeedModifierSystem _movementSpeedModifier = default!;
[Dependency] private readonly SharedJetpackSystem _jetpack = default!;
[Dependency] private readonly INetManager _net = default!;
Copy link
Member

Choose a reason for hiding this comment

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

This is unused.

@@ -1686,7 +1686,7 @@
Dead: 0
baseDecayRate: 0.04
- type: Hunger
currentHunger: 25 # spawn with Okay hunger state
Copy link
Member

Choose a reason for hiding this comment

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

Your choice I suppose

@PJB3005 PJB3005 added Status: Awaiting Changes This PR needs its reviews addressed or changes to be made in order to be merged. and removed Status: Needs Review This PR requires new reviews before it can be merged. labels Nov 12, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Status: Awaiting Changes This PR needs its reviews addressed or changes to be made in order to be merged.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants