some progress...

This commit is contained in:
2025-03-21 23:25:14 +02:00
parent d68c1c26ff
commit cc9eacca8d
3 changed files with 86 additions and 43 deletions

View File

@@ -198,7 +198,7 @@ public class WorldStateManager
public PlayerFrame GetPlayerFrame(uint playerIndex, ulong frame)
{
WorldState worldState = NetworkManager.server != null ? serverWorldState : clientWorldState;
WorldState worldState = /*NetworkManager.server != null*/IsServer ? serverWorldState : clientWorldState;//NetworkManager.server != null ? serverWorldState : clientWorldState;
PlayerFrame[] playerFrames = worldState.playerFrameHistory[playerIndex];
PlayerFrame playerFrame = playerFrames[frame % 120];
@@ -208,22 +208,25 @@ public class WorldStateManager
return playerFrame;
}
public bool HasPlayerFrame(uint playerIndex, ulong frame)
public bool HasPlayerFrame(uint playerId, ulong frame)
{
return GetPlayerFrame(playerIndex, frame) != null;
return GetPlayerFrame(playerId, frame) != null;
}
public bool GetPlayerInputState(uint playerIndex, ulong frame, out PlayerInputState2 inputState)
public bool GetPlayerInputState(uint playerId, ulong frame, out PlayerInputState2 inputState)
{
PlayerFrame frameInfo = GetPlayerFrame(playerIndex, frame);
PlayerFrame frameInfo = GetPlayerFrame(playerId, frame);
inputState = frameInfo?.inputState ?? default;
return frameInfo != null;
}
public void RecordPlayerInput(uint playerIndex, ulong frame, PlayerInputState2 inputState, PlayerMovementState movementState)
public void RecordPlayerInput(uint playerId, ulong frame, PlayerInputState2 inputState, PlayerMovementState movementState)
{
WorldState worldState = /*NetworkManager.server != null*/IsServer ? serverWorldState : clientWorldState;
PlayerFrame[] playerFrames = worldState.playerFrameHistory[playerIndex];
if (!IsServer && playerId != NetworkManager.LocalPlayerClientId)
return; // Do not record input for networked players
PlayerFrame[] playerFrames = worldState.playerFrameHistory[playerId];
PlayerFrame playerFrame = playerFrames[frame % 120];
playerFrame.frame = frame;
@@ -295,7 +298,7 @@ public class WorldStateManager
//if (!playerMovement.Input.GetState(playerFrame, out var inputState, out var actorState))
if (frameInfo == null)
{
Console.Print("send input failure to client");
Console.Print($"send input failure to client, frame {playerFrame}");
continue;
}
@@ -341,21 +344,37 @@ public class WorldStateManager
// return;
if (welcomed)
foreach (PlayerActor playerActor in scene.GetChildren<PlayerActor>())
{
var playerId = playerActor.PlayerId;
if (!clientWorldState.playerFrameHistory.ContainsKey(playerId))
foreach (PlayerActor playerActor in scene.GetChildren<PlayerActor>())
{
var playerFrames = new PlayerFrame[120];
for (int j = 0; j < playerFrames.Length; j++)
playerFrames[j] = new PlayerFrame();
clientWorldState.playerFrameHistory.Add(playerId, playerFrames);
}
var playerFrameHistory = clientWorldState.playerFrameHistory[playerId];
var playerFrame = playerFrameHistory[ClientFrame % 120];
var playerId = playerActor.PlayerId;
if (!clientWorldState.playerFrameHistory.ContainsKey(playerId))
{
var playerFrames = new PlayerFrame[120];
for (int j = 0; j < playerFrames.Length; j++)
playerFrames[j] = new PlayerFrame();
clientWorldState.playerFrameHistory.Add(playerId, playerFrames);
}
var playerFrameHistory = clientWorldState.playerFrameHistory[playerId];
var playerFrame = playerFrameHistory[ClientFrame % 120];
playerFrame.frame = ClientFrame;
playerFrame.position = playerActor.Position;
playerFrame.frame = ClientFrame;
playerFrame.position = playerActor.Position;
if (playerId == NetworkManager.LocalPlayerClientId && GetPlayerInputState(playerId, clientWorldState.frame, out var inputState))
{
var message = NetworkManager.ClientBeginSendMessage();
message.WriteByte((byte)GameModeMessageType.PlayerInput);
message.WriteUInt64(clientWorldState.frame);
message.WriteSingle(inputState.ViewDelta.X);
message.WriteSingle(inputState.ViewDelta.Y);
message.WriteSingle(inputState.MoveForward);
message.WriteSingle(inputState.MoveRight);
message.WriteBoolean(inputState.Attack);
message.WriteBoolean(inputState.Jump);
NetworkManager.ClientEndSendMessage(ref message);
}
}
}
clientWorldState.frame++;
@@ -489,20 +508,20 @@ public class WorldStateManager
case GameModeMessageType.PlayerInput:
{
uint playerId = networkEvent.Sender.ConnectionId;
PlayerInputState inputState = new PlayerInputState();
inputState.frame = networkEvent.Message.ReadUInt64();
inputState.viewDeltaX = networkEvent.Message.ReadSingle();
inputState.viewDeltaY = networkEvent.Message.ReadSingle();
inputState.moveForward = networkEvent.Message.ReadSingle();
inputState.moveRight = networkEvent.Message.ReadSingle();
inputState.attacking = networkEvent.Message.ReadBoolean();
inputState.jumping = networkEvent.Message.ReadBoolean();
PlayerInputState2 inputState = new PlayerInputState2();
ulong frame = networkEvent.Message.ReadUInt64();
inputState.ViewDelta.X = networkEvent.Message.ReadSingle();
inputState.ViewDelta.Y = networkEvent.Message.ReadSingle();
inputState.MoveForward = networkEvent.Message.ReadSingle();
inputState.MoveRight = networkEvent.Message.ReadSingle();
inputState.Attack = networkEvent.Message.ReadBoolean();
inputState.Jump = networkEvent.Message.ReadBoolean();
UpdatePlayerInput(playerId, inputState);
UpdatePlayerInput(playerId, frame, inputState);
playerLastReceivedFrames[playerId] = inputState.frame;
playerLastReceivedFrames[playerId] = frame;
break;
}
case GameModeMessageType.PlayerPosition:
@@ -706,12 +725,30 @@ public class WorldStateManager
return actor;
}
private void UpdatePlayerInput(uint playerId, PlayerInputState inputState)
private void UpdatePlayerInput(uint playerId, ulong frame, PlayerInputState2 inputState)
{
#if false
WorldState worldState = /*NetworkManager.server != null*/IsServer ? serverWorldState : clientWorldState;
//if (!IsServer && playerId != NetworkManager.LocalPlayerClientId)
// return; // Do not record input for networked players
PlayerFrame[] playerFrames = worldState.playerFrameHistory[playerId];
PlayerFrame playerFrame = playerFrames[frame % 120];
playerFrame.frame = frame;
playerFrame.inputState = inputState;
//playerFrame.movementState = movementState;
playerLastFrame[playerId] = frame;
#endif
Console.Print($"server received input frame {frame}");
#if true
if (playerId == NetworkManager.LocalPlayerClientId)
{
playerLastFrame[playerId] = inputState.frame;
return;
//playerLastFrame[playerId] = inputState.frame;
//return;
}
PlayerActor playerActor = players[playerId];
@@ -720,20 +757,25 @@ public class WorldStateManager
ulong startFrame = playerLastFrame[playerId];
if (startFrame >= inputState.frame)
if (startFrame >= frame)
return; // dropped frame, ignore
// simulate at least one or more frame when receiving input frames from player. missing frames use inputs from previous frames
var simframs = 0;
ulong frame = startFrame+1;
PlayerFrame prevFrame = GetPlayerFrame(playerId, frame - 1);
ulong nextframe = startFrame+1;
PlayerFrame prevFrame = GetPlayerFrame(playerId, startFrame);
PlayerInputState2 prevInputState = prevFrame?.inputState ?? default;
//playerMovement.Input.GetState(frame - 1, out prevInputState, out var _);
for (; frame <= inputState.frame; frame++)
for (; nextframe <= frame; nextframe++)
{
PlayerFrame frameInfo = GetPlayerFrame(playerId, frame);
PlayerInputState2 lastInputState = frameInfo?.inputState ?? prevInputState;
if (!GetPlayerInputState(playerId, nextframe, out PlayerInputState2 lastInputState))
{
}
if (nextframe == frame)
lastInputState = inputState;
//PlayerInputState2 lastInputState = frameInfo?.inputState ?? prevInputState;
//if (!playerMovement.Input.GetState(frame, out var lastInputState, out var lastActorState))
/*if (frameInfo == null)
{
@@ -743,7 +785,7 @@ public class WorldStateManager
}*/
playerMovement.ApplyInputToCamera(lastInputState, true);
playerMovement.SimulatePlayerMovement(lastInputState, frame);
playerMovement.SimulatePlayerMovement(lastInputState, nextframe);
RecordPlayerInput(playerId, Frame, lastInputState, playerMovement.movementState);
/*playerMovement.Input.SetState(frame, lastInputState, new PlayerActorState()
@@ -765,10 +807,11 @@ public class WorldStateManager
if (playerActor.Position.Length < 1.0f)
simframs = simframs;
playerLastFrame[playerId] = inputState.frame;//frame;
playerLastFrame[playerId] = frame;//frame;
if (simframs > 1)
Console.Print($"simulated {simframs} frames");
#endif
}
}
#endif

View File

@@ -101,7 +101,7 @@ public class PlayerInputNetwork2 : IPlayerInput
_worldStateManager.GetPlayerInputState(_playerId, _frame, out _state);
}
public PlayerInputState2 GetState() { return default; }
public PlayerInputState2 GetState() => _state;
public void ResetState()
{

View File

@@ -286,7 +286,7 @@ public class PlayerMovement : Script
//if (Input is PlayerInputDemo /*&& currentInputFrame2 >= currentInputFrame*/)
// return;
Input.SetFrame(worldStateManager.ClientFrame);
Input.SetFrame(worldStateManager.Frame);
Input.UpdateState();
/*if (input.frame > 0)