Changeset 25001

Timestamp:
Mar 3, 2021, 10:02:57 PM (3 years ago)
Author:
wraitii
Message:

Increase MP Command delay to 4 turns, decrease MP turns to 200ms.

To hide network latency, MP turns send commands not for the next turn but N turns after that (introduced in rP).
Further, MP turn length was increased to 500ms compared to 200ms SP turns (introduced in rP7551).
Unfortunately, increasing MP turn length has negative consequences:

  • makes pathfinding/unit motion much worse & unit behaviour worse in general.
  • makes the game more 'lag-spikey', since computations are done less often, but thus then can take more time.

This diff essentially reverts rP8400, instead increasing COMMAND_DELAY from 2 to 4 in MP. This:

  • Reduces the 'inherent command lag' in MP from 1000ms to 800ms
  • Increases the lag range at which MP will run smoothtly from 500ms to 600ms
  • makes SP and MP turns behave identically again, removing the hindrances described above.

As a side effect, single-player was not actually using COMMAND_DELAY, this is now done (can be used to simulate MP command lag).

Refs #3752

Differential Revision: https://code.wildfiregames.com/D3275

Location:
ps/trunk/source
Files:
9 edited

Legend:

Unmodified
Added
Removed
  • ps/trunk/source/main.cpp

    r24891 r25001  
    469469
    470470    static u32 turn = 0;
    471     debug_printf("Turn %u (%u)...\n", turn++, DEFAULT_TURN_LENGTH_SP);
    472 
    473     g_Game->GetSimulation2()->Update(DEFAULT_TURN_LENGTH_SP);
     471    debug_printf("Turn %u (%u)...\n", turn++, DEFAULT_TURN_LENGTH);
     472
     473    g_Game->GetSimulation2()->Update(DEFAULT_TURN_LENGTH);
    474474
    475475    g_Profiler.Frame();
  • ps/trunk/source/network/NetClient.cpp

    r24952 r25001  
    4141#include "network/StunClient.h"
    4242
     43
     44
     45
     46
     47
     48
     49
     50
    4351CNetClient *g_NetClient = NULL;
    4452
     
    335343    }
    336344
    337     // Report if we have a bad ping to the server
     345    // Report if we have a bad ping to the server
    338346    u32 meanRTT = m_Session->GetMeanRTT();
    339     if (meanRTT > DEFAULT_TURN_LENGTH_MP)
     347    if (meanRTT > )
    340348    {
    341349        PushGuiMessage(
     
    858866    for (size_t i = 0; i < message->m_Clients.size(); ++i)
    859867    {
    860         if (message->m_Clients[i].m_MeanRTT < DEFAULT_TURN_LENGTH_MP || message->m_Clients[i].m_GUID == client->m_GUID)
     868        if (message->m_Clients[i].m_MeanRTT < || message->m_Clients[i].m_GUID == client->m_GUID)
    861869            continue;
    862870
  • ps/trunk/source/network/NetClientTurnManager.cpp

    r22867 r25001  
    3737
    3838CNetClientTurnManager::CNetClientTurnManager(CSimulation2& simulation, CNetClient& client, int clientId, IReplayLogger& replay)
    39     : CTurnManager(simulation, DEFAULT_TURN_LENGTH_MP, clientId, replay), m_NetClient(client)
     39    : CTurnManager(simulation, DEFAULT_TURN_LENGTH_MP, clientId, replay), m_NetClient(client)
    4040{
    4141}
     
    4646
    4747    // Transmit command to server
    48     CSimulationMessage msg(m_Simulation2.GetScriptInterface(), m_ClientId, m_PlayerId, m_CurrentTurn + COMMAND_DELAY, data);
     48    CSimulationMessage msg(m_Simulation2.GetScriptInterface(), m_ClientId, m_PlayerId, m_CurrentTurn + , data);
    4949    m_NetClient.SendMessage(&msg);
    5050
    5151    // Add to our local queue
    52     //AddCommand(m_ClientId, m_PlayerId, data, m_CurrentTurn + COMMAND_DELAY);
     52    //AddCommand(m_ClientId, m_PlayerId, data, m_CurrentTurn + );
    5353    // TODO: we should do this when the server stops sending our commands back to us
    5454}
     
    9999    // Notice the sending is not reliable and rarely makes it to the Server.
    100100    if (m_NetClient.GetCurrState() == NCS_INGAME)
    101         NotifyFinishedOwnCommands(m_CurrentTurn + COMMAND_DELAY);
     101        NotifyFinishedOwnCommands(m_CurrentTurn + );
    102102}
    103103
  • ps/trunk/source/network/NetServer.cpp

    r24952 r25001  
    6868static const int HOST_SERVICE_TIMEOUT = 50;
    6969
     70
     71
     72
     73
     74
     75
     76
     77
    7078CNetServer* g_NetServer = NULL;
    7179
     
    605613        }
    606614        // Report if the client has bad ping
    607         else if (meanRTT > DEFAULT_TURN_LENGTH_MP)
     615        else if (meanRTT > )
    608616        {
    609617            CClientPerformanceMessage* msg = new CClientPerformanceMessage();
  • ps/trunk/source/network/NetServerTurnManager.cpp

    r24512 r25001  
    2828
    2929#if 0
     30
    3031#define NETSERVERTURN_LOG(...) debug_printf(__VA_ARGS__)
    3132#else
     
    3435
    3536CNetServerTurnManager::CNetServerTurnManager(CNetServerWorker& server)
    36     : m_NetServer(server), m_ReadyTurn(1), m_TurnLength(DEFAULT_TURN_LENGTH_MP), m_HasSyncError(false)
     37    : m_NetServer(server), m_ReadyTurn(), m_HasSyncError(false)
    3738{
    3839    // Turn 0 is not actually executed, store a dummy value.
    3940    m_SavedTurnLengths.push_back(0);
    40     // Turn 1 is special: all clients run it without waiting on a server command batch.
    41     // Because of this, it is always run with the default MP turn length.
    42     m_SavedTurnLengths.push_back(m_TurnLength);
     41    // Turns [1..COMMAND_DELAY - 1] are special: all clients run them without waiting on a server command batch.
     42    // Because of this, they are always run with the default MP turn length.
     43    for (u32 i = 1; i < COMMAND_DELAY_MP; ++i)
     44        m_SavedTurnLengths.push_back(m_TurnLength);
    4345}
    4446
     
    140142        for (const std::pair<const int, std::string>& hashPair : clientStateHash.second)
    141143        {
    142             NETSERVERTURN_LOG("sync check %d: %d = %hs\n", it->first, cit->first, Hexify(cit->second).c_str());
     144            NETSERVERTURN_LOG("sync check %d: %d = %hs\n", second).c_str());
    143145            if (hashPair.second != expected)
    144146            {
     
    175177
    176178    ENSURE(m_ClientsReady.find(client) == m_ClientsReady.end());
    177     m_ClientsReady[client] = turn + 1;
     179    m_ClientsReady[client] = turn + 1;
    178180    m_ClientsSimulated[client] = turn;
    179181}
  • ps/trunk/source/rlinterface/RLInterface.cpp

    r24962 r25001  
    390390            }
    391391
    392             const u32 deltaRealTime = DEFAULT_TURN_LENGTH_SP;
     392            const u32 deltaRealTime = DEFAULT_TURN_LENGTH;
    393393            if (nonVisual)
    394394            {
  • ps/trunk/source/simulation2/system/LocalTurnManager.cpp

    r23917 r25001  
    2121
    2222CLocalTurnManager::CLocalTurnManager(CSimulation2& simulation, IReplayLogger& replay)
    23     : CTurnManager(simulation, DEFAULT_TURN_LENGTH_SP, 0, replay)
     23    : CTurnManager(simulation, DEFAULT_TURN_LENGTH_SP, 0, replay)
    2424{
    2525}
     
    2727void CLocalTurnManager::PostCommand(player_id_t playerid, JS::HandleValue data)
    2828{
    29     AddCommand(m_ClientId, playerid, data, m_CurrentTurn + 1);
     29    AddCommand(m_ClientId, playerid, data, m_CurrentTurn + );
    3030}
    3131
    3232void CLocalTurnManager::PostCommand(JS::HandleValue data)
    3333{
    34     // Add directly to the next turn, ignoring COMMAND_DELAY,
    35     // because we don't need to compensate for network latency
    36     AddCommand(m_ClientId, m_PlayerId, data, m_CurrentTurn + 1);
     34    AddCommand(m_ClientId, m_PlayerId, data, m_CurrentTurn + m_CommandDelay);
    3735}
    3836
  • ps/trunk/source/simulation2/system/TurnManager.cpp

    r24333 r25001  
    3131#include "simulation2/Simulation2.h"
    3232
    33 const u32 DEFAULT_TURN_LENGTH_MP = 500;
    34 const u32 DEFAULT_TURN_LENGTH_SP = 200;
    35 
    36 const int COMMAND_DELAY = 2;
    37 
    3833#if 0
    3934#define NETTURN_LOG(...) debug_printf(__VA_ARGS__)
     
    4237#endif
    4338
     39
     40
     41
     42
     43
     44
     45
     46
     47
     48
     49
     50
     51
     52
    4453const CStr CTurnManager::EventNameSavegameLoaded = "SavegameLoaded";
    4554
    46 CTurnManager::CTurnManager(CSimulation2& simulation, u32 defaultTurnLength, int clientId, IReplayLogger& replay)
    47     : m_Simulation2(simulation), m_CurrentTurn(0), m_ReadyTurn(1), m_TurnLength(defaultTurnLength),
     55CTurnManager::CTurnManager(CSimulation2& simulation, u32 defaultTurnLength, int clientId, IReplayLogger& replay)
     56    : m_Simulation2(simulation), m_CurrentTurn(0), m_1), m_TurnLength(defaultTurnLength),
    4857    m_PlayerId(-1), m_ClientId(clientId), m_DeltaSimTime(0), m_HasSyncError(false), m_Replay(replay),
    4958    m_FinalTurn(std::numeric_limits<u32>::max()), m_TimeWarpNumTurns(0),
    5059    m_QuickSaveMetadata(m_Simulation2.GetScriptInterface().GetGeneralJSContext())
    5160{
    52     // When we are on turn n, we schedule new commands for n+2.
    53     // We know that all other clients have finished scheduling commands for n (else we couldn't have got here).
    54     // We know we have not yet finished scheduling commands for n+2.
    55     // Hence other clients can be on turn n-1, n, n+1, and no other.
    56     // So they can be sending us commands scheduled for n+1, n+2, n+3.
    57     // So we need a 3-element buffer:
    58     m_QueuedCommands.resize(COMMAND_DELAY + 1);
     61    // Lag between any two clients is bounded. Add 1 for inclusive bounds.
     62    m_QueuedCommands.resize(MaxClientTurnDelta(m_CommandDelay) + 1);
    5963}
    6064
     
    109113
    110114    // Check that the next turn is ready for execution
    111     if (m_ReadyTurn <= m_CurrentTurn)
     115    if (m_ReadyTurn <= m_CurrentTurn)
    112116    {
    113117        // Oops, we wanted to start the next turn but it's not ready yet -
     
    133137
    134138        // Check that the i'th next turn is still ready
    135         if (m_ReadyTurn <= m_CurrentTurn)
     139        if (m_ReadyTurn <= m_CurrentTurn)
    136140            break;
    137141
    138         NotifyFinishedOwnCommands(m_CurrentTurn + COMMAND_DELAY);
     142        NotifyFinishedOwnCommands(m_CurrentTurn + );
    139143
    140144        // Increase now, so Update can send new commands for a subsequent turn
     
    232236void CTurnManager::AddCommand(int client, int player, JS::HandleValue data, u32 turn)
    233237{
    234     NETTURN_LOG("AddCommand(client=%d player=%d turn=%d)\n", client, player, turn);
    235 
    236     if (!(m_CurrentTurn < turn && turn <= m_CurrentTurn + COMMAND_DELAY + 1))
     238    NETTURN_LOG("AddCommand(client=%d player=%d turn=%d current=%d, ready=%d)\n", client, player, turn, m_CurrentTurn, m_ReadyTurn);
     239
     240    // Reject commands for turns that we should not be able to compute (in the past or too far future).
     241    if (m_CurrentTurn >= turn || turn > m_CurrentTurn + MaxClientTurnDelta(m_CommandDelay) + 1)
    237242    {
    238243        debug_warn(L"Received command for invalid turn");
  • ps/trunk/source/simulation2/system/TurnManager.h

    r23917 r25001  
    3030class CSimulation2;
    3131class IReplayLogger;
    32 
    33 extern const u32 DEFAULT_TURN_LENGTH_SP;
    34 extern const u32 DEFAULT_TURN_LENGTH_MP;
    35 
    36 extern const int COMMAND_DELAY;
    3732
    3833/**
     
    5550
    5651/**
     52
     53
     54
     55
     56
     57
     58
     59
     60
     61
     62
     63
     64
     65
     66
     67
     68
     69
     70
     71
     72
     73
     74
     75
     76
    5777 * Common turn system (used by clients and offline games).
    5878 */
     
    6484     * Construct for a given network session ID.
    6585     */
    66     CTurnManager(CSimulation2& simulation, u32 defaultTurnLength, int clientId, IReplayLogger& replay);
     86    CTurnManager(CSimulation2& simulation, u32 defaultTurnLength, int clientId, IReplayLogger& replay);
    6787
    6888    virtual ~CTurnManager() { }
     
    165185    u32 m_CurrentTurn;
    166186
     187
     188
     189
    167190    /// The latest turn for which we have received all commands from all clients
    168191    u32 m_ReadyTurn;
Note: See TracChangeset for help on using the changeset viewer.