ComponentNetworkGenerator doesn't deeply `Clone` collections
Nobody has claimed this yet.
Assessment
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Newbie friendliness
- 52/100
- Issue type
- Bug
- Clarity
- Mostly clear
- Activity status
- Quiet
- Tech stack
- csharp
- Domain
- game-dev, networking
Research direction
Start at ComponentNetworkGenerator and the generated state-handling code for AutoNetworkedField collections; trace how a Dictionary containing MyDatum values is copied. Reproduce the nested dictionary example and verify that recursive cloning reaches IRobustCloneable values, so repeated predicted ticks do not mutate shared objects before server state arrives.
Written by the indexing model from the issue text.
Description
Consider a situation like
public sealed partial class MyComponent : Component {
[DataField, AutoNetworkedField]
public Dictionary<string, MyDatum> MyData = new();
}
[DataDefinition]
public sealed partial class MyDatum {
public int MyInt = 0;
}
and consider a situation where a shared, predicted system does something like
Entity<MyComponent> ent = ...;
for (var (key, datum) in ent.Comp.MyData) {
datum.MyInt += 1;
}
Dirty(ent)
The client will repeatedly apply the tick where datum.MyInt += 1, meaning the MyInt value will increment wildly before server state is pushed down and resets the value to a single increment (The same basic issue resolved for SS14 solutions here -- the dictionary itself is copied, but the reference to MyDatums within it are what's copied, meaning the same MyDatum objects are mutated many times).
The fix is to implement IRobustCloneable so that the gamestate is deeply cloned for each tick, meaning the += 1 is applied to the same initial value every time.
HOWEVER, this does not work in our case above -- implementing IRobustCloneable for MyDatum is fruitless as something inside the generated state handling code for MyComponent does a shallow clone of MyData and then doesn't call Clone on the values in the dictionary, meaning our clone implementation isn't used.
Ideally, AutoNetworkedFields in a component which are standard C# collections would invoke clone on their data when doing their copies, or whatever "implementation of IRobustCloneable" that is used for these collections would work recursively because a Dictionary<string, Dictionary<string, List<T : IRobustCloneable<T>>> should still be cloned all the way down to the T value.
- Dominant language
- C#
- Stars
- 693
- Forks
- 746
- Avg merge
- 3d 9h
- Merged PRs (30d)
- 22
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from space-wizards/RobustToolbox
-
Difficulty 2/5 1-3 hours Newbie friendliness 68/100
space-wizards/RobustToolbox#7038 ·
-
Difficulty 2/5 1-3 hours Newbie friendliness 62/100
space-wizards/RobustToolbox#6948 · 1 comment ·
-
Difficulty 2/5 1-3 hours Newbie friendliness 75/100
space-wizards/RobustToolbox#6823 ·
-
A: Testing Priority: 2-Important
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
space-wizards/RobustToolbox#6607 · 1 comment ·
-
Difficulty 2/5 1-3 hours Newbie friendliness 65/100
space-wizards/RobustToolbox#6576 ·
All issues in space-wizards/RobustToolbox
Similar issues
-
Difficulty 2/5 1-3 hours Newbie friendliness 86/100
-
:watch: Not Triaged 11.0 fundamentals/subsvc
Difficulty 2/5 1-3 hours Newbie friendliness 92/100
dotnet/AspNetCore.Docs#37699 ·
-
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
SubtitleEdit/subtitleedit#15108 · 1 comment ·
-
area/docs-content Bug pulumi/docs
Difficulty 1/5 1-3 hours Newbie friendliness 94/100
-
agentic-workflows untriaged
Difficulty 2/5 1-3 hours Newbie friendliness 76/100