-
Notifications
You must be signed in to change notification settings - Fork 13
Automatic Member Replication
Thanks to C#'s reflection, MDReplicated is able to detect if a value has changed and update other peers over the network automatically.
To use it, mark your Node's field or property with the [MDReplicated]
attribute. You can also set one of Godot's RPCModes (Master, Puppet, Remote, etc), but if you don't MDReplicator
will automatically set it to Puppet
for you.
By default, it uses reliable replication, but you can change that by using [MDReplicated(MDReliablity.Unreliable)]
, which is recommended if the value changes very frequently.
By default, only the network master for the node will send out updated values, unless if the member is marked with [Master]
, in which case the puppets will send values - with more than 1 puppet, this will lead to some unnecessary Rset
calls.
When a new player connects, they will receive [MDReplicated]
values a short time after connect (about 1 second).
All [MDReplicated]
properties can also take multiple [MDReplicatedSettings]
attributes to configure additional features of the replicated member.
If set to true the member will be replicated even if the game is paused.
// This value will be replicated if it changes even if the game is paused
[MDReplicated]
[MDReplicatedSetting(MDReplicator.Settings.ProcessWhilePaused, true)]
protected int SomeValue;
For settings that are replicated at an interval you can provide a group name. If you do provide a group name it will ensure that these settings are replicated on the same frame. The replicator will by default split replication of members evenly in the frame window that replication is configured for. So if you configure replication every 6 frames all members will be distributed into 6 separate frame groups when replication will happen. If you need members to be replicated on the same frame you can set the frame group.
// Any member configured with the same group name (even in a different node or script) will be replicated on the same frame.
[MDReplicated(MDReliability.Unreliable, MDReplicatedType.Interval)]
[MDReplicatedSetting(MDReplicator.Settings.GroupName, "PlayerPositions")]
protected Vector2 NetworkedPosition;
By default the framework support a few different replicated members, for instance if you got a Vector2 it will automatically become an interpolated Vector2. In some cases this is not desierable in which case you can override what type of replication you want with this setting. You can also introduce your own classes that inherit from MDReplicatedMember if you desire custom logic.
// If we don't want interpolation for Vector2 we can enforce this by choosing what type of MDReplicatedMember to use.
[MDReplicated(MDReliability.Unreliable, MDReplicatedType.Interval)]
[MDReplicatedSetting(MDReplicator.Settings.ReplicatedMemberType, typeof(MDReplicatedMember))]
protected Vector2 NetworkedPosition;
If set the method with the given name will be called whenever the member is changed. This only works on networked peers, not on the peer that is changing the member value.
// Called every time the position is changed on the client
[MDReplicated(MDReliability.Unreliable, MDReplicatedType.Interval)]
[MDReplicatedSetting(MDReplicatedMember.Settings.OnValueChangedEvent, nameof(OnPositionChanged))]
protected Vector2 NetworkedPosition;
All replicated members require a converter to function, the converter is used to convert the member into a data format that we can send across the network. By default the framework comes with two converts and it will automatically select the correct converter for you.
- MDObjectDataConverter - The default data converter, supports any default type that godot can replicate across the network with Rpc calls.
- MDCustomClassDataConverter - Converter that can convert any custom class into a format that can be sent across the network.
- If you want your own custom converter you can implement the converter interface, IMDDataConverter, which you can find in the MDListDataConverters.cs file.
// Set a custom converter
[MDReplicated(MDReliability.Unreliable, MDReplicatedType.Interval)]
[MDReplicatedSetting(MDReplicatedMember.Settings.Converter, nameof(MyCustomConverterClass))]
protected Vector2 NetworkedPosition;
By default float
, Vector2
and Vector3
values marked with [MDReplicated]
will automatically interpolate to their new values when they received an update. You can disable this behaviour for a specific member by setting the MDReplicator.Settings.Interpolate
setting to false
.
[MDReplicated]
[MDReplicatedSetting(MDReplicator.Settings.Interpolate, false)]
private float FacingDirection = 1f;
If you want to replicate a custom class or a struct that is possible within the framework, however you need to tag each property you want to replicate with the [MDReplicated]
attribute. Settings such as OnValueChangedEvent is not supported on custom class/struct members.
// A custom class that can be replicated like any other member
public class PlayerSettings
{
[MDReplicated]
public Color PlayerColor { get; set; }
[MDReplicated]
public int PlayerShotCounter { get; set; }
[MDReplicated]
private String PlayerString = "";
// This string is not tagged with [MDReplicated] so it will not be networked
public int NotNetworkedString = "";
}
// Then you can just use your custom class like a normal replicated value
// Even with settings like change listener
[MDReplicated]
[MDReplicatedSetting(MDReplicatedMember.Settings.OnValueChangedEvent, nameof(PlayerSettingsChanged))]
protected PlayerSettings NetworkedPlayerSettings { get; set; }
It is also possible to replicate lists, please see MDList for how to do this. For dictionaries check out MDDictionary