I’ve been doing a lot of reading on how different people implement socket.io in their multiplayer games so that I can use it in mine. Granted, I’m a noob with the networking layer for this and I desperately need to learn.
Code Context:
-Using Phaser3
-Multiplayer game
-Load all existing players
-Broadcast player joined
-Update player position <— My issue derives from here
Issue:
-Seems to only update position of the newest socket that joins and broadcasts it
-Might not be important but incoming socket.id seems to replace the last socket.id it was set to as id, and I think this since the argument for “run this if incoming socket is not equal to your socket” does not run
-In general, not updating the state of other players in game (not moving the others)
server.js:
const http = require('http'); const cors = require('cors'); const express = require('express'); const app = express(); const server = http.createServer(app); const io = require('socket.io')(server,{cors:{origin:'http://localhost:8080',methods:['POST','GET']}}); const universe = {0:{},1:{},2:{},3:{},4:{},5:{},6:{},7:{},8:{},9:{}} io.on('connection',(socket)=> { console.log(`${socket.id} joined the universe!`); universe['0'][socket.id] = {playerID:socket.id}; console.log(`Online players: ${JSON.stringify(universe['0'])}`) io.emit('join',socket.id, null); //sending to all clients and client socket.emit('loadUniverse', universe['0']); //sending to client only socket.on('updatePos',(player,vx,vy)=> { socket.broadcast.emit("updatePos1", player,vx,vy); }) socket.on('disconnect',()=> { delete universe['0'][socket.id] //emit a delete event console.log(`${socket.id}player left the universe!`) }) }) server.listen(3000,()=>{console.log('listening on port 3000')})
relevant client:
scene.socket.on('connect',()=> //needs to chain from the connect { this.scene.socket.emit('join',this.socketID) console.log(`connected`); }) scene.socket.on('updatePos1',(socketID1,vx,vy)=> { //this is a callback console.log(`Message Recieved: ${socketID1}: ${vx} ${vy}`) console.log(`players: ${JSON.stringify(this.scene.gameHandler.players)}`) if(this.socketID!==socketID1) { console.log('socket was not yours!'); this.scene.gameHandler.players[socketID1].sprite.body.setVelocity(vx,vy); } }) scene.socket.on('join',(socketID0,skin)=> { console.log(`Player ${socketID0} joined`); this.socketID = socketID0; this.scene.gameHandler.loadPlayer(socketID0,skin); }) scene.socket.on('loadUniverse',(universe)=> { for(const property in universe) { console.log(`propery:${property}`); this.scene.gameHandler.loadPlayer(property,null);//make this dynamic } }) updatePos() { console.log(`${this.socketID} for updatePos()`) this.scene.socket.emit( 'updatePos',this.socketID, //might have to do with how broadcasted this.scene.gameHandler.players[this.socketID].sprite.body.velocity.x, //not updating individual position this.scene.gameHandler.players[this.socketID].sprite.body.velocity.y, ) }
in game.js update() function (standard event loop for phaser3 library) I am updating client position with the “updatePos()” function above.
question:
What is it that I am doing wrong? And why is it wrong?
Advertisement
Answer
In this handler in the client where the client is being notified that another client has joined:
scene.socket.on('join',(socketID0,skin)=> { console.log(`Player ${socketID0} joined`); this.socketID = socketID0; this.scene.gameHandler.loadPlayer(socketID0,skin); })
You are setting this.socketID = socketID0
. I don’t think you want to be doing that because you’re overwriting your own socketID with the id of the last client that joined. That will mess up all future notifications from your client because you will be pretending to have the socketID of the last player to join. I think you should just remove that line entirely.
If you need to initialize your own this.socketID
somewhere, then you will need to do that in some other place where it’s only your own socketID and only done once upon connection.