Skip to content
This repository has been archived by the owner on Apr 22, 2023. It is now read-only.

MDReplicatedAttribute

Beider edited this page Jun 30, 2020 · 8 revisions

[MDReplicated] Attribute

This attribute is the main tool that makes networking in the MDFramework super easy. To use this attribute you need to ensure that your class is tagged with the MDAutoRegister attribute. Secondly the class needs to be instanced at the same place in the node tree for all players, this means either create it in your scene from the start or use the very handy this.SpawnNetworkNode(...) from any node. Read more about spawning network nodes on the GameSession page.

Basic Usage

By default any standard type member tagged with [MDReplicated] will be replicated across the network. So for instance if you want to setup a networked Vector2 for position you can simply do something like this

[MDAutoRegister]
public class Player : KinematicBody2D
{
    [MDReplicated(MDReliability.Unreliable, MDReplicatedType.Interval)]
    protected Vector2 NetworkedPosition;
}

Now the networked position will be automatically be sent every interval (which can be adjusted in the MDReplicator. By default if the GameClock is active this will be an interpolated Vector2 that uses the GameClock.

Customization

To customize your [MDReplicated] members you can use the [MDReplicatedSetting] attribute. This takes two parameters, a key and a value. Within the MDReplicator and the various implementations of MDReplicatedMember you will find a enum called Settings. These are the supported settings that you may use. You can use the list below to see the currently supported settings.

// Group for replicator to group by in case of interval (default: auto)
[MDReplicatedSetting(MDReplicator.Settings.GroupName, "PlayerPositions")]

// Process while paused (default: true)
[MDReplicatedSetting(MDReplicator.Settings.ProcessWhilePaused, false)]

// Allows to override the type of MDReplicatedMember we use, could be used to disable interpolation or for custom types
[MDReplicatedSetting(MDReplicator.Settings.ReplicatedMemberType, nameof(MDReplicatedMember))]

// A callback for whenever values are changed on remote clients (will not trigger on local client, only for clocked values)
[MDReplicatedSetting(MDClockedReplicatedMember.Settings.OnValueChangedEvent, nameof(OnPositionChanged))]

MDReplicator.Settings.ReplicatedMemberType

This custom setting can be used to override which MDReplicatedMember implementation is used for this member. In particular this is useful for providing custom implementations if you want to replicate a custom type or to turn off features such as the GameClock or interpolation.

For example if you want to replicate a Vector2 without using interpolation but with the GameClock you can set this to use the base MDClockedReplicatedMember implementation instead of the MDCRMInterpolatedVector2 which the framework would use by default for Vector2. This could be useful in certain instances for instance in the example below the Vector2 is set to be sent only when changed and without interpolation since we override which MDReplicatedMember to use.

[MDReplicated(MDReliability.Reliable, MDReplicatedType.OnChange)]
[MDReplicatedSetting(MDReplicator.Settings.ReplicatedMemberType, nameof(MDClockedReplicatedMember))]
protected Vector2 NetworkedVector2;

If you have the GameClock active and want to turn it off for one specific member you can do this by using the default MDReplicatedMember implementation.

[MDReplicated(MDReliability.Unreliable, MDReplicatedType.Interval)]
[MDReplicatedSetting(MDReplicator.Settings.ReplicatedMemberType, nameof(MDReplicatedMember))]
protected bool NetworkedBool;

MDClockedReplicatedMember.Settings.OnValueChangedEvent

This setting is only for clocked replicated members, it allows you to set a callback that will trigger on remote clients only when the given value is changed. This allows you to do something like the code below.

[MDAutoRegister]
public class Player : KinematicBody2D
{
    [MDReplicated(MDReliability.Unreliable, MDReplicatedType.Interval)]
    [MDReplicatedSetting(MDClockedReplicatedMember.Settings.OnValueChangedEvent, nameof(OnPositionChanged))]
    protected Vector2 NetworkedPosition;

    protected void OnPositionChanged()
    {
        // This will only be triggered on remote clients, no need to check if we are on a remote client
        Position = NetworkedPosition;
    }

    public override void _PhysicsProcess(float delta)
    {
        if (IsLocalPlayer)
        {
            // TODO: Movement code here
            NetworkedPosition = Position;
        }
    }
}

If the gameclock is active this would replicate the position over the network with automatic interpolation. The non-clocked member solution to this would be to implement your replicated member as a property with a custom setter and call your method from the setter.