Page 1 of 1

Adding new variables to UDP tutorial: SOLVED

Posted: Mon Mar 31, 2014 8:05 pm
by Prynok
Hi! For a game I'm making, I've decided to make it multiplayer. I have used lua for about a year now, and love2d for about two months. So I think I'm ready. How ever, whenever I try to add something new to the client and server, it won't work! Any suggestions?

Thanks, Prynok.

:nyu:

EDIT: I managed to fix it, there were a few lua pattern errors in the server, where I forgot to put the dollar sign. I also forgot to set dir in the world table.

Re: Adding new variables to UDP tutorial

Posted: Mon Mar 31, 2014 8:06 pm
by Robin
Welcome! Could you show us what you're doing?

Re: Adding new variables to UDP tutorial

Posted: Mon Mar 31, 2014 8:13 pm
by Prynok
Sure! This is the client, all I changed was the port and tried adding directions for each player

Code: Select all


local socket = require "socket"

-- the address and port of the server
local address, port = "localhost", 25565

local entity -- entity is what we'll be controlling
local updaterate = 0.1 -- how long to wait, in seconds, before requesting an update

local world = {} -- the empty world-state
local t


function love.load()


    udp = socket.udp()

    udp:settimeout(0)
    
  
    udp:setpeername(address, port)
    
 
    math.randomseed(os.time()) 

    
    entity = tostring(math.random(99999))


   

    local dg = string.format("%s %s %d %d", entity, 'at', 320, 240)
    udp:send(dg) 
    
    -- t is just a variable we use to help us with the update rate in love.update.
    t = 0 -- (re)set t to 0
end

-- love.update, hopefully you are familiar with it from the callbacks tutorial
function love.update(deltatime)

    t = t + deltatime -- increase t by the deltatime
    

    
    if t > updaterate then

        local x, y = 0, 0
        local dir = 1
        if love.keyboard.isDown('up') or love.keyboard.isDown('w') then dir=1  y=y-(20*t) end
        if love.keyboard.isDown('down') or love.keyboard.isDown('s') then dir=2   y=y+(20*t) end
        if love.keyboard.isDown('left') or love.keyboard.isDown('a') then dir=3    x=x-(20*t) end
        if love.keyboard.isDown('right') or love.keyboard.isDown('d')then dir=4  x=x+(20*t) end


    
        local dg = string.format("%s %s %f %f %f", entity, 'move', x, y, dir)
        udp:send(dg)    

    
 
        local dg = string.format("%s %s $", entity, 'update')
        udp:send(dg)

        t=t-updaterate -- set t for the next round
    end

    
 
    repeat

        data, msg = udp:receive()

        if data then 
    
            ent, cmd, parms = data:match("^(%S*) (%S*) (.*)")
            if cmd == 'at' then

                local x, y, dir = parms:match("^(%-?[%d.e]*) (%-?[%d.e]*) (%-?[%d.e]*)$")
                assert(x and y and dir) -- validation is better, but asserts will serve.
            
    
                x, y = tonumber(x), tonumber(y) dir = tonumber(dir)
                -- and finally we stash it away
                world[ent] = {x=x, y=y, dir=dir}
            else

                print("unrecognised command:", cmd)
            end
        

        elseif msg ~= 'timeout' then 
            error("Network error: "..tostring(msg))
        end
    until not data 

end


function love.draw()

    for k, v in pairs(world) do

        love.graphics.print(k, v.x, v.y)
        love.graphics.print(string.format("%s %s %f %f %f", 124, 'move', 50, 50, 100), 50, 50)
        love.graphics.print(v.dir,100,50)
    end
end
Server:

Code: Select all

local socket = require "socket"

-- begin
local udp = socket.udp()

udp:settimeout(0)




udp:setsockname('*', 25565)

local world = {} -- the empty world-state


local data, msg_or_ip, port_or_nil
local entity, cmd, parms

local running = true

-- the beginning of the loop proper...
print "Beginning server loop."
while running do
  
    data, msg_or_ip, port_or_nil = udp:receivefrom()
    if data then
        -- more of these funky match paterns!
        entity, cmd, parms = data:match("^(%S*) (%S*) (.*)")
        if cmd == 'move' then
            local x, y, dir = parms:match("^(%-?[%d.e]*) (%-?[%d.e]*)$")
            assert(x and y and dir) -- validation is better, but asserts will serve.

            x, y = tonumber(x), tonumber(y) dir = tonumber(dir)
       
            local ent = world[entity] or {x=0, y=0, dir = 1}
            world[entity] = {x=ent.x+x, y=ent.y+y, dir}
        elseif cmd == 'at' then
            local x, y, dir = parms:match("^(%-?[%d.e]*) (%-?[%d.e]*) (%-?[%d.e]*)")
            assert(x and y and dir) -- validation is better, but asserts will serve.
            x, y = tonumber(x), tonumber(y) dir = tonumber(dir)
            world[entity] = {x=x, y=y, dir=dir}
        elseif cmd == 'update' then
            for k, v in pairs(world) do
                udp:sendto(string.format("%s %s %d %d %d", k, 'at', v.x, v.y, v.dir), msg_or_ip,  port_or_nil)
            end
        elseif cmd == 'quit' then
            running = false;
        else
            print("unrecognised command:", cmd)
        end
    elseif msg_or_ip ~= 'timeout' then
        error("Unknown network error, might just be two servers open under same ip and port: "..tostring(msg))
    end
    
    socket.sleep(0.01)
end

print "Thank you."

Re: Adding new variables to UDP tutorial

Posted: Tue Apr 01, 2014 9:04 am
by Robin
This might be a silly question, but are you sure that port is open on your computer?

Re: Adding new variables to UDP tutorial

Posted: Tue Apr 01, 2014 1:05 pm
by Prynok
Yes, I ported 25565. Does love have a special port it uses?

Re: Adding new variables to UDP tutorial: SOLVED

Posted: Tue Apr 01, 2014 1:54 pm
by Robin
No, but I've run into problems with closed ports in the past. I don't know much else about UDP, so someone else will have to help you then. :o:

Re: Adding new variables to UDP tutorial: SOLVED

Posted: Wed Apr 02, 2014 8:19 pm
by I~=Spam
I recommend you use LUBE: http://www.love2d.org/wiki/LUBE It is very useful and even comes with table serialization so that you can send tables as strings.