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

View File

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

View File

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