From c106094540cb3f4c8dcb06bcfca0ee4af5d32fed Mon Sep 17 00:00:00 2001 From: Barry Kane Date: Sun, 9 Jul 2023 01:15:05 +0100 Subject: [PATCH] Basic Client Side Prediction --- README.org | 11 +++++++++++ src/client/cspt-client.c | 12 +++++++++++- src/cspt-state.c | 37 ++++++++++++++++++++++++++++--------- src/server/cspt-server.c | 4 ++-- 4 files changed, 52 insertions(+), 12 deletions(-) diff --git a/README.org b/README.org index 49c9d15..2db6212 100644 --- a/README.org +++ b/README.org @@ -32,6 +32,17 @@ I think my first step will be creating the TCP portion of the client-server interaction. This should be relatively trivial, so I can get right to it. Simply transmitting a few integers back and forth will do well. +** Entry 02: TCP & UDP basics completed: +The TCP portion is completed, and I have also created a basic simulation which +is based on the model that is described in the first article in the series, and +the model which "Spacewar!" currently uses. Time to start work on actual client +side prediction and other techniques. + +** Entry 03: That seems far too easy: +Simply duplicating the server's game thread seems to meet the concept of client +side prediction described in the second article. I'd imagine there's still a lot +more to deal with, but we'll see how much of a difference this makes to how it +feels. I'll report back. * Notes On Techniques: ** Entry 00: Where I'm Learning All This From: diff --git a/src/client/cspt-client.c b/src/client/cspt-client.c index 3fda7f1..02f89e1 100644 --- a/src/client/cspt-client.c +++ b/src/client/cspt-client.c @@ -91,6 +91,15 @@ void * networkHandler(void * parameters) } } +void * gameThreadHandler(void * arguments) +{ + while (true) + { + doGameTick(arguments); + usleep(15625); + } +} + void * graphicsThreadHandler(void * parameters) { struct gameState * state = ((struct threadParameters *)parameters)->state; @@ -201,7 +210,7 @@ void * graphicsThreadHandler(void * parameters) int main(int argc, char ** argv) { int serverSocket = 0; - pthread_t graphicsThread, networkThread; + pthread_t graphicsThread, networkThread, gameThread; struct CsptMessage currentMessage; bool continueRunning = true; struct gameState * currentState = calloc(1, sizeof(struct gameState)); @@ -249,6 +258,7 @@ int main(int argc, char ** argv) parameters.message = clientInput; parameters.state = currentState; pthread_create(&graphicsThread, NULL, graphicsThreadHandler, ¶meters); + pthread_create(&gameThread, NULL, gameThreadHandler, currentState); pthread_create(&networkThread, NULL, networkHandler, ¶meters); while (continueRunning) diff --git a/src/cspt-state.c b/src/cspt-state.c index 1935d4f..b6795f7 100644 --- a/src/cspt-state.c +++ b/src/cspt-state.c @@ -20,31 +20,50 @@ void doGameTick(struct gameState * state) // Calculate acceleration: if (state->clients[index].leftAcceleration) { - state->clients[index].xVelocity -= 0.1; + state->clients[index].xVelocity -= 0.5; } if (state->clients[index].rightAcceleration) { - state->clients[index].xVelocity += 0.1; + state->clients[index].xVelocity += 0.5; + } + if (!state->clients[index].leftAcceleration && !state->clients[index].rightAcceleration) + { + state->clients[index].xVelocity *= 0.9; } if (state->clients[index].upAcceleration) { - state->clients[index].yVelocity -= 0.1; + state->clients[index].yVelocity -= 0.5; } if (state->clients[index].downAcceleration) { - state->clients[index].yVelocity += 0.1; + state->clients[index].yVelocity += 0.5; + } + if (!state->clients[index].upAcceleration && !state->clients[index].downAcceleration) + { + state->clients[index].yVelocity *= 0.9; } - // Do movement: state->clients[index].xPosition += state->clients[index].xVelocity; state->clients[index].yPosition += state->clients[index].yVelocity; - if(state->clients[index].xPosition > 600 || state->clients[index].xPosition < 0) + if(state->clients[index].xPosition > 1000) { - state->clients[index].xPosition = 300; + state->clients[index].xPosition = 1000; + state->clients[index].xVelocity = 0; } - if(state->clients[index].yPosition > 600 || state->clients[index].yPosition < 0) + if(state->clients[index].xPosition < 0) { - state->clients[index].yPosition = 300; + state->clients[index].xPosition = 0; + state->clients[index].xVelocity = 0; + } + if(state->clients[index].yPosition > 1000) + { + state->clients[index].yPosition = 1000; + state->clients[index].yVelocity = 0; + } + if(state->clients[index].yPosition < 0) + { + state->clients[index].yPosition = 0; + state->clients[index].yVelocity = 0; } } } diff --git a/src/server/cspt-server.c b/src/server/cspt-server.c index 2b514c9..58efb31 100644 --- a/src/server/cspt-server.c +++ b/src/server/cspt-server.c @@ -70,10 +70,10 @@ void * networkThreadHandler(void * arguments) void * gameThreadHandler(void * arguments) { - while(true) + while (true) { doGameTick(arguments); - usleep(9000); + usleep(15625); } } int main(int argc, char ** argv)