@dave1707, at least the server duplication problem is now fixed! I’ll do some more code and see if anything improves
@dave1707, if this works, when the second player joins that player should show on the first players screen but not have its position updated.
function setup()
scene = craft.scene()
craft.scene.main = scene
socket = require("socket")
messenger = socket.udp()
messenger:setoption("broadcast", true)
messenger:settimeout(0)
parameter.text("Server Name", "")
parameter.action("Host", createServer)
client_data = {}
clients = {}
entities = {}
servers = {}
my_client = nil
my_entity = nil
my_server = nil
server_name = ""
connected = false
-- Something to land on so the clients dont fall endlessly into the void
ground = scene:entity()
ground.model = craft.model(asset.builtin.Primitives.RoundedCube)
ground.position = vec3(0, -2, 10)
ground.scale = vec3(10, 0.1, 10)
gbody = ground:add(craft.rigidbody, STATIC)
ground:add(craft.shape.model, ground.model)
-- Setup camera
scene.camera.position = vec3(0, 8, -10)
scene.camera.rotation = quat.eulerAngles(25, 0, 0)
end
function joinServer(ip)
if my_client == nil then
local client = socket.udp()
client:setpeername(ip, "14285")
client:settimeout(0)
table.insert(clients, client)
makePlayer(vec3(0, 0, 10), client)
positions = {x = entity.position.x, y = entity.position.y, z = entity.position.z}
my_client = client
client:send("join")
end
end
function createServer()
if my_server == nil then
server = socket.udp()
server:setsockname("*", 14285)
server:setoption("broadcast", true)
server:settimeout(0)
my_server = server
server_name = Server_Name
end
end
function makePlayer(pos, client)
if not entities[entity] then
entity = scene:entity()
entity.model = craft.model(asset.builtin.Primitives.Sphere)
entity.position = pos
body = entity:add(craft.rigidbody, DYNAMIC)
entity:add(craft.shape.sphere, 1)
entity.material = craft.material(asset.builtin.Materials.Specular)
entity.material.diffuse = color(math.random(0, 255), math.random(0, 255), math.random(0, 255))
body.linearDamping = 0.3
my_entity = entity
if client ~= nil then
entity.master = client
end
table.insert(entities, entity)
end
end
function touched(touch)
if touch.state == MOVING then
if touch.deltaX > 0 then
for i,e in pairs(entities) do
if e == my_entity then
e:get(craft.rigidbody):applyForce(vec3(-30, 0, 0))
end
end
elseif touch.deltaX < 0 then
for i,e in pairs(entities) do
if e == my_entity then
e:get(craft.rigidbody):applyForce(vec3(30, 0, 0))
end
end
elseif touch.deltaY > 0 then
for i,e in pairs(entities) do
if e == my_entity then
e:get(craft.rigidbody):applyForce(vec3(0, 0, 30))
end
end
elseif touch.deltaY < 0 then
for i,e in pairs(entities) do
if e == my_entity then
e:get(craft.rigidbody):applyForce(vec3(0, 0, -30))
end
end
end
end
end
function draw()
messenger:sendto("checking for servers", "255.255.255.255", "14285")
if my_server ~= nil then
local data, ip, port = my_server:receivefrom()
if data == "checking for servers" then
my_server:sendto("server available"..my_server:getsockname(), ip, tostring(port))
elseif data ~= nil then
if data == "join" then
print("A client has successfully joined!")
local uid = {ip = ip, port = port}
if not client_data[uid] then
table.insert(client_data, uid)
end
for i,cl in pairs(client_data) do
my_server:sendto("make a player", cl.ip, cl.port)
end
end
end
end
local data = messenger:receive()
if data ~= nil then
if string.find(data, "server available") then
local address = string.sub(data, 17, #data)
parameter.action(address, function() joinServer(address) end)
end
end
for i,c in pairs(clients) do
local data = c:receive()
if data ~= nil then
if data == "make player" then
makePlayer(vec3(0, 0, 10), c)
end
end
end
end
@Creator27 Only 1 player was on each iPad.
@dave1707, I think I figured out why it isn’t working. I need to broadcast the message to every connected iPad and in order to do that I need to send my message via the broadcast address or 255.255.255.255. I’ve edited my code so that it does exactly that.
function setup()
scene = craft.scene()
craft.scene.main = scene
socket = require("socket")
messenger = socket.udp()
messenger:setoption("broadcast", true)
messenger:settimeout(0)
parameter.text("Server Name", "")
parameter.action("Host", createServer)
client_data = {}
clients = {}
entities = {}
servers = {}
my_client = nil
my_entity = nil
my_server = nil
server_name = ""
connected = false
-- Something to land on so the clients dont fall endlessly into the void
ground = scene:entity()
ground.model = craft.model(asset.builtin.Primitives.RoundedCube)
ground.position = vec3(0, -2, 10)
ground.scale = vec3(10, 0.1, 10)
gbody = ground:add(craft.rigidbody, STATIC)
ground:add(craft.shape.model, ground.model)
-- Setup camera
scene.camera.position = vec3(0, 8, -10)
scene.camera.rotation = quat.eulerAngles(25, 0, 0)
end
function joinServer(ip)
if my_client == nil then
local client = socket.udp()
client:setpeername(ip, "14285")
client:settimeout(0)
table.insert(clients, client)
makePlayer(vec3(0, 0, 10), client)
positions = {x = entity.position.x, y = entity.position.y, z = entity.position.z}
my_client = client
client:send("join")
end
end
function createServer()
if my_server == nil then
server = socket.udp()
server:setsockname("*", 14285)
server:setoption("broadcast", true)
server:settimeout(0)
my_server = server
server_name = Server_Name
end
end
function makePlayer(pos, client)
if not entities[entity] then
entity = scene:entity()
entity.model = craft.model(asset.builtin.Primitives.Sphere)
entity.position = pos
body = entity:add(craft.rigidbody, DYNAMIC)
entity:add(craft.shape.sphere, 1)
entity.material = craft.material(asset.builtin.Materials.Specular)
entity.material.diffuse = color(math.random(0, 255), math.random(0, 255), math.random(0, 255))
body.linearDamping = 0.3
my_entity = entity
if client ~= nil then
entity.master = client
end
table.insert(entities, entity)
end
end
function touched(touch)
if touch.state == MOVING then
if touch.deltaX > 0 then
for i,e in pairs(entities) do
if e == my_entity then
e:get(craft.rigidbody):applyForce(vec3(-30, 0, 0))
end
end
elseif touch.deltaX < 0 then
for i,e in pairs(entities) do
if e == my_entity then
e:get(craft.rigidbody):applyForce(vec3(30, 0, 0))
end
end
elseif touch.deltaY > 0 then
for i,e in pairs(entities) do
if e == my_entity then
e:get(craft.rigidbody):applyForce(vec3(0, 0, 30))
end
end
elseif touch.deltaY < 0 then
for i,e in pairs(entities) do
if e == my_entity then
e:get(craft.rigidbody):applyForce(vec3(0, 0, -30))
end
end
end
end
end
function draw()
messenger:sendto("checking for servers", "255.255.255.255", "14285")
if my_server ~= nil then
local data, ip, port = my_server:receivefrom()
if data == "checking for servers" then
my_server:sendto("server available"..my_server:getsockname(), ip, tostring(port))
elseif data ~= nil then
if data == "join" then
print("A client has successfully joined!")
local uid = {ip = ip, port = port}
if not client_data[uid] then
table.insert(client_data, uid)
end
my_server:sendto("new", ip, port)
end
end
end
local data = messenger:receive()
if data ~= nil then
if string.find(data, "server available") then
local address = string.sub(data, 17, #data)
parameter.action(address, function() joinServer(address) end)
end
end
for i,c in pairs(clients) do
local data = c:receive()
if data ~= nil then
if data == "make player" then
makePlayer(vec3(0, 0, 10), c)
for i,e in pairs(entities) do
local tab = {x = e.position.x, y = e.position.y, z = e.position.z}
my_server:sendto(json.encode(tab).."entity position"..tostring(e), "255.255.255.255", "14285")
end
elseif data == "new" then
my_server:sendto("make player", "255.255.255.255", "14285")
elseif string.find(data, "entity position") then
local tab = json.decode(data)
for i,e in pairs(entities) do
if string.find(data, tostring(e)) then
e.position = vec3(tab.x, tab.y, tab.z)
end
end
end
end
end
end
@Creator27 Nothing changed. Only one sphere on each iPad. Maybe you need to wait until you can use a second iPad, that would make it a lot easier.
The image is the same as the one above.
@dave1707, I’ll do some more research and see if I can find anything about syncing players across devices.
@dave1707, I really don’t know what else to do, but I’ve edited the code again.
function setup()
scene = craft.scene()
craft.scene.main = scene
socket = require("socket")
messenger = socket.udp()
messenger:setoption("broadcast", true)
messenger:settimeout(0)
parameter.text("Server Name", "")
parameter.action("Host", createServer)
client_data = {}
clients = {}
entities = {}
servers = {}
my_client = nil
my_entity = nil
my_server = nil
server_name = ""
connected = false
-- Something to land on so the clients dont fall endlessly into the void
ground = scene:entity()
ground.model = craft.model(asset.builtin.Primitives.RoundedCube)
ground.position = vec3(0, -2, 10)
ground.scale = vec3(10, 0.1, 10)
gbody = ground:add(craft.rigidbody, STATIC)
ground:add(craft.shape.model, ground.model)
-- Setup camera
scene.camera.position = vec3(0, 8, -10)
scene.camera.rotation = quat.eulerAngles(25, 0, 0)
end
function joinServer(ip)
if my_client == nil then
local client = socket.udp()
client:setpeername(ip, 14285)
client:setoption("broadcast", true)
client:settimeout(0)
table.insert(clients, client)
my_client = client
client:send("join", "255.255.255.255", 14285)
end
end
function createServer()
if my_server == nil then
server = socket.udp()
server:setsockname("*", 14285)
server:setoption("broadcast", true)
server:settimeout(0)
my_server = server
server_name = Server_Name
end
end
function makePlayer(pos, client)
if not entities[entity] then
entity = scene:entity()
entity.model = craft.model(asset.builtin.Primitives.Sphere)
entity.position = pos
body = entity:add(craft.rigidbody, DYNAMIC)
entity:add(craft.shape.sphere, 1)
entity.material = craft.material(asset.builtin.Materials.Specular)
entity.material.diffuse = color(math.random(0, 255), math.random(0, 255), math.random(0, 255))
body.linearDamping = 0.3
my_entity = entity
if client ~= nil then
entity.master = client
end
table.insert(entities, entity)
end
end
function touched(touch)
if touch.state == MOVING then
if touch.deltaX > 0 then
for i,e in pairs(entities) do
if e == my_entity then
e:get(craft.rigidbody):applyForce(vec3(-30, 0, 0))
end
end
elseif touch.deltaX < 0 then
for i,e in pairs(entities) do
if e == my_entity then
e:get(craft.rigidbody):applyForce(vec3(30, 0, 0))
end
end
elseif touch.deltaY > 0 then
for i,e in pairs(entities) do
if e == my_entity then
e:get(craft.rigidbody):applyForce(vec3(0, 0, 30))
end
end
elseif touch.deltaY < 0 then
for i,e in pairs(entities) do
if e == my_entity then
e:get(craft.rigidbody):applyForce(vec3(0, 0, -30))
end
end
end
end
end
function draw()
messenger:sendto("checking for servers", "255.255.255.255", "14285")
if my_server ~= nil then
local data, ip, port = my_server:receivefrom()
if data == "checking for servers" then
my_server:sendto("server available"..server:getsockname(), ip, tostring(port))
elseif data ~= nil then
if data == "join" then
print("A client has successfully joined!")
local uid = {ip = ip, port = port}
if not client_data[uid] then
table.insert(client_data, uid)
end
makePlayer(vec3(0, 0, 10))
end
end
end
local data, ip, port = messenger:receivefrom()
if data ~= nil then
if string.find(data, "server available") then
local address = string.sub(data, 17, #data)
parameter.action(address, function() joinServer(address) end)
local tab = {ip = ip, port = port}
for i,c in pairs(clients) do
table.insert(tab, tostring(c))
end
end
end
end
@Creator27 Same thing, only 1 sphere per iPad.
@dave1707, I just can’t seem to figure out how to broadcast the “make player” message using 255.255.255.255 because connected UDP objects (clients) can only receive messages from the server, and I’ve tried broadcasting it from the server but that didn’t work either.
@dave1707, I’ve rewritten the code so that it broadcasts a message across the network using 255.255.255.255 to every server that says “make a player” with the specified client that joined attached to the end of the message. If the server receives the message, it will go through every connected client and see if it has its name in it. If it does, it will make a player.
function setup()
scene = craft.scene()
craft.scene.main = scene
socket = require("socket")
messenger = socket.udp()
messenger:setoption("broadcast", true)
messenger:settimeout(0)
parameter.text("Server Name", "")
parameter.action("Host", createServer)
client_data = {}
clients = {}
entities = {}
servers = {}
my_client = nil
my_entity = nil
my_server = nil
server_name = ""
connected = false
allowed_to_host = true
-- Something to land on so the clients dont fall endlessly into the void
ground = scene:entity()
ground.model = craft.model(asset.builtin.Primitives.RoundedCube)
ground.position = vec3(0, -2, 10)
ground.scale = vec3(10, 0.1, 10)
gbody = ground:add(craft.rigidbody, STATIC)
ground:add(craft.shape.model, ground.model)
-- Setup camera
scene.camera.position = vec3(0, 8, -10)
scene.camera.rotation = quat.eulerAngles(25, 0, 0)
end
function joinServer(ip)
if my_client == nil then
local client = socket.udp()
client:setpeername(ip, 14285)
client:settimeout(0)
table.insert(clients, client)
my_client = client
client:send("join")
local ip, port, type = my_server:getsockname()
local bytes, err = messenger:sendto("make a player"..tostring(client)..tostring(my_server), "255.255.255.255", port)
end
end
function createServer()
if my_server == nil then
server = socket.udp()
server:setsockname("*", 14285)
server:setoption("broadcast", true)
server:settimeout(0)
my_server = server
server_name = Server_Name
end
end
function stopServer()
if my_server ~= nil then
server:close()
end
end
function makePlayer(pos, client)
if not entities[entity] then
entity = scene:entity()
entity.model = craft.model(asset.builtin.Primitives.Sphere)
entity.position = pos
body = entity:add(craft.rigidbody, DYNAMIC)
entity:add(craft.shape.sphere, 1)
entity.material = craft.material(asset.builtin.Materials.Specular)
entity.material.diffuse = color(math.random(0, 255), math.random(0, 255), math.random(0, 255))
body.linearDamping = 0.3
my_entity = entity
if client ~= nil then
entity.master = client
end
table.insert(entities, entity)
end
end
function touched(touch)
if touch.state == MOVING then
if touch.deltaX > 0 then
for i,e in pairs(entities) do
if e == my_entity then
e:get(craft.rigidbody):applyForce(vec3(-30, 0, 0))
end
end
elseif touch.deltaX < 0 then
for i,e in pairs(entities) do
if e == my_entity then
e:get(craft.rigidbody):applyForce(vec3(30, 0, 0))
end
end
elseif touch.deltaY > 0 then
for i,e in pairs(entities) do
if e == my_entity then
e:get(craft.rigidbody):applyForce(vec3(0, 0, 30))
end
end
elseif touch.deltaY < 0 then
for i,e in pairs(entities) do
if e == my_entity then
e:get(craft.rigidbody):applyForce(vec3(0, 0, -30))
end
end
end
end
end
function draw()
if my_client == nil then
messenger:sendto("checking for servers", "255.255.255.255", "14285")
end
if my_server ~= nil then
local data, ip, port = my_server:receivefrom()
if data == "checking for servers" then
my_server:sendto("server available"..server:getsockname(), ip, tostring(port))
elseif data ~= nil then
if data == "join" then
print("A client has successfully joined!")
local uid = {ip = ip, port = port}
if not client_data[uid] then
table.insert(client_data, uid)
end
elseif string.find(data, "make a player") then
for i,c in pairs(clients) do
if string.find(data, tostring(c)) then
makePlayer(vec3(0, 0, 10), c)
else
if string.find(data, tostring(my_server)) then
makePlayer(vec3(0, 0, 10))
end
end
end
end
end
end
local data, ip, port = messenger:receivefrom()
if data ~= nil then
if string.find(data, "server available") then
if allowed_to_host == true then
local address = string.sub(data, 17, #data)
parameter.action(Server_Name.." - Join", function() joinServer(address) end)
local tab = {ip = ip, port = port}
for i,c in pairs(clients) do
table.insert(tab, tostring(c))
end
allowed_to_host = false
end
end
end
for i,c in pairs(clients) do
local data = c:receive()
if data == "make a player" then
makePlayer(vec3(0, 0, 10), c)
end
end
end
@Creator27 Same thing, Only 1 sphere per iPad.
Maybe you should re-edit all of the above posts and remove the code. This is getting long with a lot of non working code.
@dave1707, good idea. I will do just that.
@dave1707, can you check to see if both iPads print “make a player”. I need to know to broadcasting across devices is working.
@Creator27 Here something I found among my projects. I think this is supposed to send to everyone.
function setup()
myAddress()
end
function myAddress()
local socket = require("socket")
local s = socket.udp()
s:setsockname("*",0)
s:setoption("broadcast", true)
local ip,port,typ = s:getsockname()
print("ip "..ip,port,typ)
local bytes,err = s:sendto("hello","255.255.255.255",port)
if not err then
s:settimeout(3)
local msg,myIP,myPort = s:receivefrom()
print("myIp "..myIP)
print("myPort "..myPort)
print("msg "..msg)
else
print("PROBLEM: "..err)
end
end
@Creator27 I didn’t see “make a player” on either iPad. Just successfully joined.
@dave1707, that’s what I tried to do. It’s just not working and it’s getting really annoying!
@Creator27 Normally I would try to help figure out what’s wrong, but at the moment I’m not too interested in coding. For the past few days I’ve been battling the side effects of BA-5 Covid. I feel like I have the worst cold I’ve ever had and almost non stop coughing. So I’ll keep testing your code, but that’s about as far as my interest goes at the moment.
@dave1707, I’m so sorry that’s happening. In fact if I’m being perfectly honest with you, I’m so grateful that you’re even testing this for me so thank you. Um, I just changed the code above slightly and hopefully that works!
@Creator27 Same thing, one sphere per iPad with the joined successfully message.
@dave1707, I’m currently experimenting with my code seeing how I can get it to sync new and existing players, and I decided to try and make 2 clients join at once. You’ll only need to use one iPad for this, but you can try and use 2 iPads if you want.
function setup()
scene = craft.scene()
craft.scene.main = scene
socket = require("socket")
messenger = socket.udp()
messenger:setoption("broadcast", true)
messenger:settimeout(0)
parameter.text("Server Name", "")
parameter.action("Host", createServer)
client_data = {}
clients = {}
client_count = 0
entities = {}
servers = {}
my_client = nil
my_entity = nil
my_server = nil
server_name = ""
connected = false
allowed_to_host = true
-- Something to land on so the clients dont fall endlessly into the void
ground = scene:entity()
ground.model = craft.model(asset.builtin.Primitives.RoundedCube)
ground.position = vec3(0, -2, 10)
ground.scale = vec3(10, 0.1, 10)
gbody = ground:add(craft.rigidbody, STATIC)
ground:add(craft.shape.model, ground.model)
-- Setup camera
scene.camera.position = vec3(0, 8, -10)
scene.camera.rotation = quat.eulerAngles(25, 0, 0)
end
function joinServer(ip)
if my_client == nil then
local client = socket.udp()
client:setpeername(ip, 14285)
client:settimeout(0)
table.insert(clients, client)
my_client = client
client:send("join")
local client2 = socket.udp()
client2:setpeername(ip, 14285)
client2:settimeout(0)
table.insert(clients, client2)
client2:send("join")
end
end
function createServer()
if my_server == nil then
server = socket.udp()
server:setsockname("*", 14285)
server:setoption("broadcast", true)
server:settimeout(0)
my_server = server
server_name = Server_Name
end
end
function stopServer()
if my_server ~= nil then
server:close()
end
end
function makePlayer(pos, client)
if not entities[entity] then
entity = scene:entity()
entity.model = craft.model(asset.builtin.Primitives.Sphere)
entity.position = pos
body = entity:add(craft.rigidbody, DYNAMIC)
entity:add(craft.shape.sphere, 1)
entity.material = craft.material(asset.builtin.Materials.Specular)
entity.material.diffuse = color(math.random(0, 255), math.random(0, 255), math.random(0, 255))
body.linearDamping = 0.3
my_entity = entity
if client ~= nil then
entity.master = client
end
table.insert(entities, entity)
end
end
function touched(touch)
if touch.state == MOVING then
if touch.deltaX > 0 then
for i,e in pairs(entities) do
if e == my_entity then
e:get(craft.rigidbody):applyForce(vec3(-30, 0, 0))
end
end
elseif touch.deltaX < 0 then
for i,e in pairs(entities) do
if e == my_entity then
e:get(craft.rigidbody):applyForce(vec3(30, 0, 0))
end
end
elseif touch.deltaY > 0 then
for i,e in pairs(entities) do
if e == my_entity then
e:get(craft.rigidbody):applyForce(vec3(0, 0, 30))
end
end
elseif touch.deltaY < 0 then
for i,e in pairs(entities) do
if e == my_entity then
e:get(craft.rigidbody):applyForce(vec3(0, 0, -30))
end
end
end
end
end
function draw()
messenger:sendto("checking for servers", "255.255.255.255", "14285")
if my_server ~= nil then
local data, ip, port = my_server:receivefrom()
if data == "checking for servers" then
my_server:sendto("server available", ip, port)
elseif data == "join" then
local uid = {ip = ip, port = port}
if not client_data[uid] then
table.insert(client_data, uid)
end
my_server:sendto("update players", ip, port)
end
end
local data, ip, port = messenger:receivefrom()
if data == "server available" then
parameter.action(tostring(port).." - Join", function() joinServer(ip) end)
end
for i,c in pairs(clients) do
local data = c:receive()
if data ~= nil then
if string.find(data, "update players") then
makePlayer(vec3(0, 0, 10))
end
end
end
end