Multiplayer bugs becoming more prevalent - Harden & Improve Network / Multiplayer Support!

Client to server?

This works for us:

MyPlayerState.h:



    FString MyString;
    
    UFUNCTION()
    void SetMyString(FString NewMyString);

    UFUNCTION(Reliable, Server, WithValidation)
    virtual void ServerSetMyString();
    bool ServerSetMyString_Validate();
    void ServerSetMyString_Implementation();

    UFUNCTION(Reliable, Client)
    virtual void ClientRequestMyStringChunk(int32 ServerMyStringLen);
    void ClientRequestMyStringChunk_Implementation(int32 ServerMyStringLen);
    
    UFUNCTION()
    void RequestMyStringChunk();
    FTimerHandle TimerHandle_RequestMyStringChunk;

    UFUNCTION(Reliable, Server, WithValidation)
    virtual void ServerSendMyStringChunk(const FString& MyStringChunk);
    bool ServerSendMyStringChunk_Validate(const FString& MyStringChunk);
    void ServerSendMyStringChunk_Implementation(const FString& MyStringChunk);


MyPlayerState.cpp:



void AMyPlayerState::SetMyString(FString NewMyString)
{
    // Set my string.
    MyString = NewMyString;

    // If I'm  client & MyString isn't empty, tell  server I have it.
    if ((Role < ROLE_Authority) && !MyString.IsEmpty())
    {
        ServerSetMyString();
    }
}

bool AMyPlayerState::ServerSetMyString_Validate()
{
    return true;
}

void AMyPlayerState::ServerSetMyString_Implementation()
{
    // Client has told me it has set MyString.
    // Clear  server version and ask  client to start sending  first chunk.
    MyString.Empty();
    ClientRequestStringChunk(0);
}

void AMyPlayerState::ClientRequestMyStringChunk_Implementation(int32 ServerMyStringLen)
{
    static int32 MaxChunkSize = 512; // NOTE: 512 could be anything < 1024
    FString MyStringChunk;

    //  server has a MyString that as long as ours - tell  server its done.
    if (ServerMyStringLen >= MyString.Len())
    {
        MyStringChunk = TEXT("END");
    }
    // Not enough string to send an entire chunk - send what we can.
    else if (ServerMyStringLen + MaxChunkSize >= MyString.Len())
    {
        MyStringChunk = MyString.Mid(ServerMyStringLen, (MyString.Len() - ServerMyStringLen));
    }
    // Send an entire chunk.
    else
    {
        MyStringChunk = MyString.Mid(ServerMyStringLen, MaxChunkSize);
    }

    ServerSendMyStringChunk(MyStringChunk);
}

void AMyPlayerState::RequestMyStringChunk()
{
    // Ask  client to start sending another chunk
    ClientRequestStringChunk(MyString.Len());
}

bool AMyPlayerState::ServerSendMyStringChunk_Validate(const FString& MyStringChunk)
{
    return true;
}

void AMyPlayerState::ServerSendMyStringChunk_Implementation(const FString& MyStringChunk)
{
    //  client has told us we have  whole string.
    // Time to do something with it.
    if (MyStringChunk == TEXT("END"))
    {
    }
    else
    {
        // We have another chunk of string.
        // Add it to our version.
        MyString += MyStringChunk;
        // Delay request for next string chunk to prevent flooding.
        SETTIMERH(TimerHandle_RequestMyStringChunk, AMyPlayerState::RequestMyStringChunk, 0.05f, false);
    }
}


We send condensed JSON formatted strings from client to server using this method.
Easy to send it back, since arrays replicate :slight_smile:

You don’t have to use player state - any owner actor will do.
e.g PlayerController

Hope that helps.

Due to recent discussions on a specific forum thread and slack chat:

Dedicated Servers don’t work with Lobby System of Steam. Using presence bool (true) will crash attempt to register Server.
Using a Dedicated Server without presence is still not working out of box. There were changes to be made in Subsystem class and
socket class etc.

There were issues with overflowing GameTags and GameData when pushing Settings to Steam and also missing conditions to ensure usage
of WinSock.

Is there any chance that this will be addressed? I mean it’s interface between Steam and UE4, so i can understand if that is just totally backlogged,
but on other hand it’s way to undocumented to solve this with Engine Source on your own ):

OR maybe there is a solution that has not been discovered? I don’t know…

While not specifically Multiplayer, this is an issue with Online Sub System:

+1 for these; having to write a huge amount of custom code.

+1

I’m having all sorts of trouble with being private, among other things listed in here.

Maybe make it protected?