Jump to content

Networking in LUA


Jazz
 Share

Recommended Posts

Just in case you feel it's to hard of a task to do yourself here is exactly how you do it. I actually just did this so thought I'd share.

 

 

1) Go http://leafo.net/lua-enet

2) Look for the Windows section and click the link to download the file

3) Place the DLL in your game's directory that has your game's exe file

4) Here's is the odd part. This requires lua dll but Leadwerks has it named lua51.dll but this enet dll needs it to be called lua5.1.dll so just make a copy of the existing dll and rename it which is in the same folder as your games exe.

5) In your project this is how you load the package and then everything else works the same as the link above in terms of usage:


-- load the networking library
assert(package.loadlib("enet.dll", "luaopen_enet"))()

  • Upvote 2
Link to comment
Share on other sites

I haven't gotten into enet that much but the thing I'm not liking so far is that it seems you just send string data. I'm more used to RakNet where I can send different types. I guess I would use a json string to send but that's probably bloating and wasting bytes over the wire. Not sure.

Link to comment
Share on other sites

I haven't gotten into enet that much but the thing I'm not liking so far is that it seems you just send string data.

 

It's pretty easy to make a few C++ classes over ENet that allow you to write data , then expose them with the LuaJit FFI api, or even toLua++ if you wanted. I did this with ENet and used FFI to allow for creation of these classes in Lua without the additional overhead, I don't really want to give my code otu til I get it a little further a long at least, but if anyone wants I could give a quick tutorial or description of how I made my system.

 

Minus all the back end systems, to use my Message/Reader system it writes like this:

Lua:

--Server
netmsg.Register("MsgOne") --If you forgot this part it would still work, but it'd give you a warning telling you it's faster to register this, because then the client downloads it on initial connection instead of while he's playing. (Except when sending messages from the client to the server 'message name' MUST be registered by the server.)
concommand.Register("testmsg", function() --concommand system unrelated to example.
netmsg.Start("MsgOne")
 netmsg.WriteInt16(12345)
 netmsg.WriteFloat(34.4536)
 netmsg.WriteString("Whatever")
 netmsg.WriteVec3(Vec3(12.3, 45.6, 78.9))
netmsg.Broadcast()
end)
--Client
netmsg.Listen("MsgOne", function()
 local int16 = netmsg.Readint16()
 local fl = netmsg.ReadFloat()
 local str = netmsg.ReadString()
 local vec = netmsg.ReadVec3()
System:Print("Message received!")
end)

 

C++:

//Server
Netwerks::Message::Register("MsgOne"); //Inside some sort of initialization function.

static void TestMsgCMD(int argc, char* args[]) { //Unrelated, part of con command system.
Netwerks::Message message("MsgOne");
message.WriteInt16(12345);
message.WriteFloat(34.4536);
message.WriteString("Whatever");
message.WriteVec3(new Vec3(12.3, 45.6, 78.9));
}

//Client
static void RecvTestMsg(Netwerks::Reader* reader) {
int16_t int16 = reader->ReadInt16();
float fl = reader->ReadFloat();
char str[MAX_MSG_STRING_LENGTH];
reader->ReadString(str, sizeof(str));
Leadwerks::Vec3* vec3 = reader->ReadVec3();
Leadwerks::System::Print("Message received!");
}

Netwerks::Handler::Register("MsgOne", &RecvTestMsg); //Also in some sort of initialization method.

 

But for entity variables I made a separate system (that uses this one) to keep certain variables synced.

When I get a little further into my project I'll most likely release a template or something, but for now best I can offer is helping anyone make a similar system.

 

But yeah if you don't want to do this extra work I'd use RakNet, like Rick said you can only send strings through ENet with Lua unless you do something like this.

Link to comment
Share on other sites

I haven't tried it with lua-enet but you can use lua-MessagePack to encode arbitrary data into a string. It isn't too space efficient but it should work if you don't have a large amount of things to synchronize.

 

http://fperrad.github.io/lua-MessagePack

 

Here is an example of how I encoded a couple Vec3s into a string to be sent via lua-enet (or whateva)

 

mp = require 'Scripts/Functions/MessagePack'

thing1 = Vec3()
thing1.x = 1.123
thing1.y = 2.234
thing1.z = 3.345

thing2 = Vec3()
thing2.x = 4.123
thing2.y = 5.234
thing2.z = 6.345

data = {{x=thing1.x, y=thing1.y, z=thing1.z}, {x=thing2.x, y=thing2.y, z=thing2.z}}

mp.set_number'float'
mp.set_array'with_hole'
mp.set_string'string'

mpac = mp.pack(data)

System:Print("Len="..string.len(mpac))

unpacked_data = mp.unpack(mpac)

System:Print("pos.x="..unpacked_data[1].x.."pos.y="..unpacked_data[1].y.."pos.z="..unpacked_data[1].z)
System:Print("pos.x="..unpacked_data[2].x.."pos.y="..unpacked_data[2].y.."pos.z="..unpacked_data[2].z)

 

Result

Len=45
pos.x=1.1230000257492pos.y=2.2339999675751pos.z=3.3450000286102
pos.x=4.1230001449585pos.y=5.2340002059937pos.z=6.3449997901917

45 bytes compared to 24 if it was raw c++. Not ideal but it'd work.

 

EDIT: I'm dumb, require works fine, no change required to MessagePack.lua

Edited by thehankinator
  • Upvote 1
Link to comment
Share on other sites

In your example if you print out mpac what does it show?

Prints out garbage because the format bytes are not always alpha numeric when printed as a character plus I don't think the floats are encoded in a way that is human readable when packed. Gotta print each character as a byte. To inspect the packed data I did:

str_mpac = ""
for i=1, string.len(mpac) do
  str_mpac = str_mpac..string.format('%02X', string.byte(string.sub(mpac,i,i)))
end
System:Print(str_mpac)

Which printed

9283A179CA400EF9DBA178CA3F8FBE77A17ACA4056147B83A179CA40A77CEEA178CA4083EF9EA17ACA40CB0A3D

Edited by thehankinator
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   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.

 Share

×
×
  • Create New...