Jump to content

Peer-to-peer Networking in Leadwerks Game Engine 4.6

Josh

744 views

I'm wrapping up the new multiplayer capabilities for Leadwerks 4.6, and I am very excited about what this offers developers.

We saw previously how the lobby system is used to create or join games, and how to retrieve Steam IDs for messaging. Once we have joined a game we can start sending messages with the P2P::Send command, which includes a few overloads:

static bool P2P::Send(uint64 steamid, const int messageid, const int channel = 0, const int flags = 0);
static bool P2P::Send(uint64 steamid, const int messageid, std::string& data, const int channel = 0, const int flags = 0);
static bool P2P::Send(uint64 steamid, const int messageid, Bank* data, const int channel = 0, const int flags = 0);
static bool P2P::Send(uint64 steamid, const int messageid, Stream* data, const int channel = 0, const int flags = 0);
static bool P2P::Send(uint64 steamid, const int messageid, const void* data, const int size, const int channel = 0, const int flags = 0);

Each message has an ID and can be followed by additional data in the form of a string, bank, or stream. Voice chat is handled automatically, but the rest is up to you to decide what data the messages should contain. I provide examples for text chat, joining and leaving a game, and movement.

Receiving messages from other players is extremely simple:

static Message* P2P::Receive(const int channel = 0);

The message object has information contained within it:

class Message
{
public:
	int id;
	Stream* stream;
	uint64 userid
};

We can evaluate messages based on their ID. For example, here is a text chat message being received:

auto message = P2P::Receive()
if (message)
{
	if (message->id == MESSAGE_CHAT && message->stream != nullptr)
	{
		Print(message->stream->ReadString());
	}
}

A new multiplayer game template will be included, with out-of-the-box support for text and voice chat, public servers, and player movement.

Untitled2.thumb.png.fe53bb518c16a67f5e54a9a2c1c423a0.png

You can download the test app and try it out here:

Thanks to everyone who has helped me test this!

  • Like 1
  • Upvote 1


5 Comments


Recommended Comments

Really cool. Hopefully a network newbie like me can understand this.

Hopefully you can copy and paste this system into the new engine once this update goes live.

 

  • Upvote 1

Share this comment


Link to comment

In Turbo I think we can even add a general-purpose network update script like this:

function Entity:UpdateNetwork()
	local lobby = CurrentLobby()
	if lobby==nil then return end
	if lobby.owner ~= GetSteamID() then return end
	if self.lastupdatenetworktime==nil then
		self.lastupdatenetworktime=0
	end
	local tm = Time:Millisecs()
	if tm - self.lastupdatenetworktime > 1000/30 then
		self.lastupdatenetworktime = tm			
		local pos = self.entity:GetPosition(true)
		local rot = self.entity:GetQuaternion(true)
		local stream = BankStream:Create()
		if self.networkupdatetick==nil then self.networkupdatetick = 0 end
		stream:WriteInt(self.mapID)              
		self.networkupdatetick = self.networkupdatetick + 1
		stream:WriteInt(self.networkupdatetick)
		stream:WriteFloat(pos.x)
		stream:WriteFloat(pos.y)
		stream:WriteFloat(pos.z)
		stream:WriteFloat(rot.x)
		stream:WriteFloat(rot.y)
		stream:WriteFloat(rot.z)
		stream:WriteFloat(rot.w)
		Broadcast(MESSAGE_UPDATEENTITY,stream)
	end
end

And then entities would just automatically sync their orientations. Something like that.

  • Like 1

Share this comment


Link to comment

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Add a comment...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...