Browse Source

Lag & desync compensation

tags/crossplatform
madiwka3 4 years ago
parent
commit
5d42a7c855
4 changed files with 172 additions and 63 deletions
  1. +61
    -18
      main.lua
  2. +1
    -1
      readme.md
  3. +47
    -32
      server/server.lua
  4. +63
    -12
      src/baseGame.lua

+ 61
- 18
main.lua View File

@@ -24,7 +24,7 @@ wall1width = 30
nuclearanimation = 3 nuclearanimation = 3
easternum = 0 easternum = 0
ball_DIR = 0 ball_DIR = 0
updaterate = 0.03
updaterate = 0.015
RED = 255 RED = 255
hitNum = {} hitNum = {}
hitNum[1] = 0 hitNum[1] = 0
@@ -201,6 +201,7 @@ function love.load()
newButton( newButton(
"Online", "Online",
function() function()
MAP_TYPE = 0
gameState = "chooseIP" gameState = "chooseIP"
end end
) )
@@ -291,15 +292,15 @@ function love.load()
end end
) )
) )
table.insert(
settings,
newButton(
"Change Map",
function()
MAP_TYPE = MAP_TYPE + 1
end
)
)
--table.insert(
-- settings,
-- newButton(
-- "Change Map",
-- function()
-- MAP_TYPE = MAP_TYPE + 1
-- end
-- )
--)
table.insert( table.insert(
settings, settings,
newButton( newButton(
@@ -588,6 +589,7 @@ function love.load()
function() function()
gameState = "1serve" gameState = "1serve"
gameMode = "reversegame" gameMode = "reversegame"
globalState = "base"
end end
) )
) )
@@ -763,6 +765,7 @@ function nettest(dt)
for i = 1, maxBalls do for i = 1, maxBalls do
ts = ts + dt ts = ts + dt
if ts > updaterate then if ts > updaterate then
if ball[1].dx <= 0 then
--print (tostring(ball[i].dy)) --print (tostring(ball[i].dy))
udp:send(tostring(lastSentKey) .. udp:send(tostring(lastSentKey) ..
'|' .. tostring(ball[i].dy) .. '|' .. tostring(ball[i].dy) ..
@@ -777,8 +780,12 @@ function nettest(dt)
'|' .. gameState .. '|' .. gameState ..
'|' .. tostring(ball[i].dx) .. '|' .. tostring(ball[i].dx) ..
'|' .. tostring(ballSpeed) .. '|' .. tostring(ballSpeed) ..
'|' .. tostring(paddle_SPEED) ..
"|HOST") "|HOST")
print("SENT: " .. lastSentKey)
print("PRIVILEGE SENT: " .. lastSentKey)
else
udp:send(tostring(lastSentKey) ..'|' .. player1.y .. "|HOST")
end
ts = 0 ts = 0
end end
end end
@@ -795,14 +802,23 @@ function nettest(dt)
print("ReceivedINFO: " .. data) print("ReceivedINFO: " .. data)
confirmation = "N" confirmation = "N"
local p = split(data, '|') local p = split(data, '|')
if p[3] ~= "CLIENT" then
if p[3] ~= "CLIENT" and not p[15] then
confirmation = "U" confirmation = "U"
end end
if p[15] then
if p[15] ~= "CLIENT" then
confirmation = "U"
end
end
if tonumber(p[4]) > 90 then if tonumber(p[4]) > 90 then
confirmation = "L" confirmation = "L"
end end
if ball[1].dx <= 0 then
lastSentKeyClient = p[1] lastSentKeyClient = p[1]
player2.y = tonumber(p[2]) player2.y = tonumber(p[2])
elseif ball[1].dx > 0 then
lastSentKeyClient, ball[i].dy, player2.y, player1score, player2score, player1nukescore, player2nukescore, ball[i].x, ball[i].y, gameState, ball[i].dx, ballSpeed, paddle_SPEED = p[1], die, tonumber(p[4]), tonumber(p[5]), tonumber(p[6]), tonumber(p[7]), tonumber(p[8]), tonumber(p[9]), tonumber(p[10]), p[11], tonumber(p[12]), tonumber(p[13]), tonumber(p[14])
end
end end
until not data until not data
@@ -829,7 +845,27 @@ function clienttest(dt)
end end
ts = ts + dt ts = ts + dt
if ts > updaterate then if ts > updaterate then
if ball[1].dx <= 0 then
print("MINOR SENDING")
udp:send(tostring(lastSentKey) ..'|' .. player2.y .. "|CLIENT") udp:send(tostring(lastSentKey) ..'|' .. player2.y .. "|CLIENT")
elseif ball[1].dx > 0 then
print("PRIVILEGED SENDING")
udp:send(tostring(lastSentKey) ..
'|' .. tostring(ball[1].dy) ..
'|' .. tostring(player1.y) ..
'|' .. tostring(player2.y) ..
'|' .. tostring(player1score) ..
'|' .. tostring(player2score) ..
'|' .. tostring(player1nukescore) ..
'|' .. tostring(player2nukescore) ..
'|' .. tostring(ball[1].x) ..
'|' .. tostring(ball[1].y) ..
'|' .. gameState ..
'|' .. tostring(ball[1].dx) ..
'|' .. tostring(ballSpeed) ..
'|' .. tostring(paddle_SPEED) ..
"|CLIENT")
end
ts = 0 ts = 0
end end
local data local data
@@ -846,18 +882,25 @@ function clienttest(dt)
print("SENT TO SERVER:" .. lastSentKey) print("SENT TO SERVER:" .. lastSentKey)
confirmation = "N" confirmation = "N"
local p = split(data, '|') local p = split(data, '|')
if p[14] then
if p[14] ~= "HOST" then
if p[15] then
if p[15] ~= "HOST" then
confirmation = "U" confirmation = "U"
end end
if tonumber(p[15]) > 90 then
if tonumber(p[16]) > 90 then
confirmation = "L" confirmation = "L"
end end
for i = 1, maxBalls do for i = 1, maxBalls do
local die = tonumber(p[2]) local die = tonumber(p[2])
lastSentKeyClient, ball[i].dy, player1.y, player1score, player2score, player1nukescore, player2nukescore, ball[i].x, ball[i].y, gameState, ball[i].dx, ballSpeed = p[1], die, tonumber(p[4]), tonumber(p[5]), tonumber(p[6]), tonumber(p[7]), tonumber(p[8]), tonumber(p[9]), tonumber(p[10]), p[11], tonumber(p[12]), tonumber(p[13])
if ball[i].dx <= 0 then
lastSentKeyClient, ball[i].dy, player1.y, player1score, player2score, player1nukescore, player2nukescore, ball[i].x, ball[i].y, gameState, ball[i].dx, ballSpeed, paddle_SPEED = p[1], die, tonumber(p[4]), tonumber(p[5]), tonumber(p[6]), tonumber(p[7]), tonumber(p[8]), tonumber(p[9]), tonumber(p[10]), p[11], tonumber(p[12]), tonumber(p[13]), tonumber(p[14])
elseif ball[i].dx > 0 then
lastSentKeyClient = p[1]
player1.y = tonumber(p[4])
end end
end
end
elseif p[3] ~= "HOST" then
confirmation = "U"
end
end end
print("GOT: " .. lastSentKeyClient) print("GOT: " .. lastSentKeyClient)
until not data until not data
@@ -1360,7 +1403,7 @@ function love.draw()
baseDraw() baseDraw()
if (globalState == "nettest" or globalState == "clienttest") and confirmation == "D" then if (globalState == "nettest" or globalState == "clienttest") and confirmation == "D" then
love.graphics.clear(50 / 255, 50 / 255, 50 / 255, 255) love.graphics.clear(50 / 255, 50 / 255, 50 / 255, 255)
love.graphics.printf("WAIT FOR PLAYER 2", 0, VIRTUAL_HEIGHT / 2, VIRTUAL_WIDTH, "center")
love.graphics.printf("WAIT FOR OPPONENT", 0, VIRTUAL_HEIGHT / 2, VIRTUAL_WIDTH, "center")
end end
if (globalState == "nettest" or globalState == "clienttest") and confirmation == "U" then if (globalState == "nettest" or globalState == "clienttest") and confirmation == "U" then
love.graphics.clear(50 / 255, 50 / 255, 50 / 255, 255) love.graphics.clear(50 / 255, 50 / 255, 50 / 255, 255)


+ 1
- 1
readme.md View File

@@ -32,4 +32,4 @@ To play on Windows, download and install <a href = "https://love2d.org">Love</a>
To play an old, outdated EXE version on Windows, head to <a href = "https://madi-wka.club/Downloads.php">my website</a>, and download the old, outdated game. To play an old, outdated EXE version on Windows, head to <a href = "https://madi-wka.club/Downloads.php">my website</a>, and download the old, outdated game.


# Changes # Changes
<p>0.7.6 is here! With this update, I improved the AI, allowing it to follow 2 balls at the same time! I also added "Smart" difficulty, where the AI uses physics and math to pre-calculate where the ball is going to land. Alpha-testing of the Online gameplay is now here, although its stupid and doesnt work. </p>
<p>0.7.7 is here! Wiht this uodate, Online mode FINALLY, FINALLY WORKS! The default IP is my server, but you can launch the server from anywhere! The code for the server is under the server/ directory. The client is kind of laggy, though. I am trying my best to fix the issue. </p>

+ 47
- 32
server/server.lua View File

@@ -1,15 +1,20 @@
local running = true local running = true
local socket = require 'socket' local socket = require 'socket'
local udp = socket.udp() local udp = socket.udp()
local player1ip, player2ip, p1data, p2data, player1port, player2port = "none", "none", nil, nil, nil, nil
local player1ip, player2ip, player1port, player2port = "none", "none", nil, nil
udp:settimeout(0) udp:settimeout(0)
udp:setsockname('*', 12345) udp:setsockname('*', 12345)
local p1ping = 0 local p1ping = 0
local p2ping = 0 local p2ping = 0
local data, msg_or_ip, port_or_nil
while running do while running do
local data, msg_or_ip, port_or_nil
local p1data, p2data
repeat
data, msg_or_ip, port_or_nil = udp:receivefrom() data, msg_or_ip, port_or_nil = udp:receivefrom()
if data then if data then
print(string.sub(data,1,1) .. "Playerlist: " .. player1ip .. " " .. player2ip)
if (player1ip == msg_or_ip) then if (player1ip == msg_or_ip) then
p1ping = 0 p1ping = 0
p1data = data p1data = data
@@ -20,11 +25,13 @@ while running do
if (player1ip == "none") then if (player1ip == "none") then
player1ip = msg_or_ip player1ip = msg_or_ip
p1data = data p1data = data
p1ping = 0
player1port = port_or_nil player1port = port_or_nil
print("CONNECTED: PLAYER 1 FROM: " .. player1ip) print("CONNECTED: PLAYER 1 FROM: " .. player1ip)
elseif player2ip == "none" and msg_or_ip ~= player1ip then elseif player2ip == "none" and msg_or_ip ~= player1ip then
player2ip = msg_or_ip player2ip = msg_or_ip
p2data = data p2data = data
p2ping = 0
player2port = port_or_nil player2port = port_or_nil
print("CONNECTED: PLAYER 2 FROM: " .. player2ip) print("CONNECTED: PLAYER 2 FROM: " .. player2ip)
elseif (player1ip ~= msg_or_ip and player2ip ~= msg_or_ip) then elseif (player1ip ~= msg_or_ip and player2ip ~= msg_or_ip) then
@@ -32,38 +39,46 @@ while running do
end end
end end



elseif player1ip ~= "none" then
p1ping = p1ping + 1
if p1ping > 5 then
if p2data then
udp:sendto(p2data .. '|' .. p1ping, player1ip, player1port)
end
print("PLAYER 1 DISCONNECTED")
p1data = nil
player1ip = "none"
player1port = nil
end
elseif player2ip ~= "none" then
p2ping = p2ping + 1
if p2ping > 5 then
if p1data then
udp:sendto(p1data .. '|' .. p2ping, player2ip, player2port)
end
print("PLAYER 2 DISCONNECTED")
p2data = nil
player2ip = "none"
player2port = nil
else
end
until not data
if player1ip ~= "none" then
p1ping = p1ping + 1
if p1ping > 100 then
if p2data then
udp:sendto(p2data .. '|' .. p1ping, player1ip, player1port)
end end
print("PLAYER 1 DISCONNECTED")
p1data = nil
player1ip = "none"
player1port = nil
end end
if data then
print(data .. "FROM " .. msg_or_ip .. "Playerlist: " .. player1ip .. " " .. player2ip)
end
if p1data and p2data then
end
if player2ip ~= "none" then
p2ping = p2ping + 1
if p2ping > 100 then
if p1data then
udp:sendto(p1data .. '|' .. p2ping, player2ip, player2port) udp:sendto(p1data .. '|' .. p2ping, player2ip, player2port)
udp:sendto(p2data .. '|' .. p1ping, player1ip, player1port)
print("SENT1: " .. player2ip .. " " .. player2port .. " " .. p1data)
print("SENT2: " .. player1ip .. " " .. player1port .. " " .. p2data)
end
print("PLAYER 2 DISCONNECTED")
p2data = nil
player2ip = "none"
player2port = nil
end end
socket.sleep(0.01)
end
if p1data and player2port then
udp:sendto(p1data .. '|' .. p2ping, player2ip, player2port)
print("SENT TO " .. player2ip .. ":" .. player2port .. " : " .. string.sub(p1data,1,1))
end
if p2data and player1port then
udp:sendto(p2data .. '|' .. p1ping, player1ip, player1port)
print("SENT TO " .. player1ip .. ":" .. player1port .. " : " .. string.sub(p2data,1,1))
--print("1::" .. p1data)
--print("2::" .. p2data)
--print("SENT1: " .. player2ip .. " " .. player2port .. " " .. p1data)
--print("SENT2: " .. player1ip .. " " .. player1port .. " " .. p2data)
end
socket.sleep(0.015)

end end

+ 63
- 12
src/baseGame.lua View File

@@ -1,5 +1,5 @@
function basegame(dt) function basegame(dt)
if gameMode == "reverse" then
if gameMode == "reversegame" then
reversegame(dt) reversegame(dt)
end end
if player1nukescore > 300 then if player1nukescore > 300 then
@@ -89,7 +89,7 @@ function basegame(dt)
end end
if (striken == 1) then if (striken == 1) then
player1nukescore = player1nukescore * 1.2
player1nukescore = player1nukescore * 1.5
if (synctype == 0) then if (synctype == 0) then
paddle_SPEED = paddle_SPEED * 1.10 paddle_SPEED = paddle_SPEED * 1.10
elseif (synctype == 1) then elseif (synctype == 1) then
@@ -355,7 +355,7 @@ end
function debugCheck(dt) function debugCheck(dt)
if (gameState == "menu") then if (gameState == "menu") then
updateTEXT = "0.7.6 Chalkboard Update"
updateTEXT = "0.7.7 Chalkboard Update"
end end
dangerChecker() dangerChecker()
elapsed = elapsed + dt elapsed = elapsed + dt
@@ -604,12 +604,7 @@ function normalDraw()
end end
end end


if gameMode == 'practice' then
practiceDraw()
end
if gameMode == 'normal' then
pongDraw()
end
pongDraw()
love.graphics.setFont(smallfont) love.graphics.setFont(smallfont)
for i = 1, maxBalls do for i = 1, maxBalls do
if areanuclear == 1 then if areanuclear == 1 then
@@ -743,7 +738,7 @@ function baseDraw()
nuclearDraw() nuclearDraw()
end end
if gameState == 'play' or gameState == '1serve' or gameState == '2serve' or gameState == 'done' then if gameState == 'play' or gameState == '1serve' or gameState == '2serve' or gameState == 'done' then
--print("Drawing normally")
print("Drawing normally")
normalDraw() normalDraw()
end end


@@ -1056,7 +1051,7 @@ function clientsBaseGame(dt)
end end
if (striken == 1) then if (striken == 1) then
player1nukescore = player1nukescore * 1.2
player1nukescore = player1nukescore * 1.5
if (synctype == 0) then if (synctype == 0) then
paddle_SPEED = paddle_SPEED * 1.10 paddle_SPEED = paddle_SPEED * 1.10
elseif (synctype == 1) then elseif (synctype == 1) then
@@ -1148,6 +1143,61 @@ function clientsBaseGame(dt)
player2nukescore = player2nukescore + 10 player2nukescore = player2nukescore + 10
ball[i].dx = -ball[i].dx ball[i].dx = -ball[i].dx
ball[i].x = player2.x - 30 ball[i].x = player2.x - 30
if ((love.keyboard.isDown(p2control.up))) then
select = math.random(1, 5)
if select == 1 then
ball[i].dy = -1
elseif select == 2 then
ball[i].dy = -1.2
elseif select == 3 then
ball[i].dy = -1.5
elseif select == 4 then
ball[i].dy = -1.8
elseif select == 5 then
ball[i].dy = -2
end
elseif (love.keyboard.isDown(p2control.down))then
select = math.random(1, 5)
if select == 1 then
ball[i].dy = 1
elseif select == 2 then
ball[i].dy = 1.2
elseif select == 3 then
ball[i].dy = 1.5
elseif select == 4 then
ball[i].dy = 1.8
elseif select == 5 then
ball[i].dy = 2
end
else
if ball[i].dy < 0 then
select = math.random(1, 5)
if select == 1 then
ball[i].dy = -1
elseif select == 2 then
ball[i].dy = -1.2
elseif select == 3 then
ball[i].dy = -1.5
elseif select == 4 then
ball[i].dy = -1.8
elseif select == 5 then
ball[i].dy = -2
end
else
select = math.random(1, 5)
if select == 1 then
ball[i].dy = 1
elseif select == 2 then
ball[i].dy = 1.2
elseif select == 3 then
ball[i].dy = 1.5
elseif select == 4 then
ball[i].dy = 1.8
elseif select == 5 then
ball[i].dy = 2
end
end
end
end end
hitIdentifier() hitIdentifier()
if ball[i].y <= 0 then if ball[i].y <= 0 then
@@ -1155,7 +1205,7 @@ function clientsBaseGame(dt)
sounds["wallhit"]:setPitch(ballSpeed / 250) sounds["wallhit"]:setPitch(ballSpeed / 250)
sounds["wallhit"]:play() sounds["wallhit"]:play()
ball[i].y = 0 ball[i].y = 0
ball[i].dy = -ball[i].dy
end end


-- -4 to account for the ball's size -- -4 to account for the ball's size
@@ -1164,6 +1214,7 @@ function clientsBaseGame(dt)
sounds["wallhit"]:setPitch(ballSpeed / 250) sounds["wallhit"]:setPitch(ballSpeed / 250)
sounds["wallhit"]:play() sounds["wallhit"]:play()
ball[i].y = VIRTUAL_HEIGHT - 40 ball[i].y = VIRTUAL_HEIGHT - 40
ball[i].dy = -ball[i].dy
end end
--love.window.setTitle('Trying to update the ball') --love.window.setTitle('Trying to update the ball')


Loading…
Cancel
Save