Wrapping RackNet in BlitzMax

BlitzMax Forums/BlitzMax Programming/Wrapping RackNet in BlitzMax

RepeatUntil(Posted 2006) [#1]
Kurix implemented a very nice wrapper of the RackNet library (http://www.rakkarsoft.com) for Blitz3D. It appeared to me that the wrapper he did could be also used for BlitzMax.

We discussed that in this thread: http://www.blitzmax.com/Community/posts.php?topic=50546 , but since it's in the Blitz3D section, it's maybe a good idea to move the discussion here. You could see the 10-15 last posts of this thread to have an idea of the discussion. But here is my summary.

- RackNet is a library written in C++ and is cross-platform, and the source is available
- The idea would be to include directly the C/C++ source into BlitzMax, so that we keep the fact that it's cross-platform
(- Another solution would be to use a dll, but then it would be only for windows :-( )
- It's not possible to include C++ source directly into BlitzMax, because BlitzMax needs virtual methods, and the methods in RackNet are not virtual.
- So the idea would be to write a wrapper in C, which wrap each C++ method and transform it into a C function
- This is were it's interesting since Kurix already did such a wrapper for Blitz3D (C++ -> C conversion)
- It occurs to me (but I am not certain) that we could use the wrapper of Kurix, with no modification
- Then we will import this C code into BlitzMax, and create an "Extern .. End Extern" block with the function pointers into a racknet.bmx
- And that would be it!!

So, it seems to me that this work could be pretty simple, like a couple of hours...... But I am sure a lot of issues will arise, and that won't be so simple... I am really not an expert on C and interface with BlitzMax, so maybe some of my points are wrong??

In fact we could even go further: wrap in BlitzMax the C function to use BlitzMax type to have object orientation!! But that's another level of complexity, and I am not sure it would be useful!

Also you could check out the help file from BlitzMax: "Language -> Advanced topics" to have some idea on the wrapping.

But there is maybe an issue with multithreading. RackNet use threads. There is an interesting quote from the RackNet site:

Use the source or a DLL?

RakNet includes the source and a pre-made DLL, along with sample projects to make a DLL, use a DLL, and use the source. You may use either in your game. During development, you will probably want to use the source so you can trace into the code for better control. During release, you will probably want to use a DLL so you don't have to make your game multithreaded, and for easier patching.

But then I am worried by the fact that including the source means that the game will be multithreaded!! Is it compatible with BlitzMax?? If BlitzMax is not tread-safe, is it not a show-stopper??

So now I need some input from you:
- do you think it's feasible as I described?
- do you think the multithread could be something really bad?
- is any C/C++ expert candidate to work on this?

Dreamora(Posted 2006) [#2]
Multithreading will only cause problems if the BM side and C++ side access the same data. As BM is not able to use the C++ objects, this shouldn't be a problem, as you will need to create a "procedural" layer in between to let them communicate.

This layer then could handle the syncronisation as well.
So this should be doable ...

PS: I know that you theoretically can use C++ objects, but this would mean a rewrite of all classes as BM only accepts virtual functions in types. As well you would need to create the constructor / destructor functions in non OO.
So in the end, you could as well create a whole procedural wrapper especially because of the threading.

Chris C(Posted 2006) [#3]
tho be warned when I used portAudio (which is threaded) it can play merry hell with the max debugger!!

AntonyWells(Posted 2006) [#4]
Where's this raknet wrapper for b3d you speak of?
I've been wanting to port raknet to max so I'll gladly take a look.

Might even release it for free.(grin)

RepeatUntil(Posted 2006) [#5]
The racknet wrapper was done by Kurix. All details in this thread: www.blitzmax.com/Community/posts.php?topic=50546
As I said (but I am not sure), I think we can use the source of his wrapper with no modification, and no reprogramming. If I understand correctly, the only thing to do is to add an extern..End extern block with the function pointers (that you can copy from the Blitz3D decls).
If multithreading is not a problem, then this would be very cool!

Note: the source code of the wrapper of Kurix costs 20 Euros.

AntonyWells(Posted 2006) [#6]
Yeah shame the source costs money, would have been much better to base a new wrapper for max and statically link to it for cross platform. Saying that is raknet even cross platform?

RepeatUntil(Posted 2006) [#7]
Yes, RackNet is cross platform for Win, Linux, Mac and even more!
The source costs money, but that would save lots of hours of work for the guy who will wrap RackNet for BlitzMax...

Tibit(Posted 2006) [#8]
Have you heard about TNet? It is a network library for both UDP and TCP for Blitzmax. I'm not sure if it can send 60,000 messages per second but I say that it is very easy to use, along with a very nice packing system. And it is free.

Read more here

Soon TNet-Advanced will come and then it will have reliabe UDP and more.

AdrianT(Posted 2006) [#9]
OpenTNL is supposed to be a lot better than Raknet, but is quite costly.

RepeatUntil(Posted 2006) [#10]
Yes, OpenTNL is 295$ for indie and per programmer. Racknet is 100$ IF you release and sell your game.
But why do you say that openTnl is much better than RackNet. Do you know any limitation to Racknet.

Wave, I also recommend (and am a user) of TNet. Waiting desperately for TNet Advanced ;-) But having TNet and RackNet couldn't hurt...

Dreamora(Posted 2006) [#11]
perhaps because OpenTNL bases torque network library ... the only network library known so far supporting 256 Player shooter battles on regular connections with acceptable latency. (not even BF2 is capable of that)

Tibit(Posted 2006) [#12]
But having TNet and RackNet couldn't hurt...

Of course not ;)
And my replay was not to you in person, more in general to advertice some for TNet.

the only network library known so far supporting 256 Player shooter battles on regular connections with acceptable latency

Where have you heard/know that from?
Do you perhaps refer to Tribes?
To me it appears that the most difficult thing with a lag-free 256 player shooter is to actually get 256 players to connect, all which have low latency to the server. And if a lot of security checks are made then the server can not be to bad either.
I might be missing the point but I fail to see how any network library could help with that?

Stu_ovine(Posted 2006) [#13]
Has anyone a completed Wrapper for Racknet ?

Ive been using KNET - but random errors crashing the DLL are forcing me to look at alternatives. (KNET no longer supported)

RepeatUntil(Posted 2006) [#14]
I am working on this right now, for 2 weeks. The RakNet wrapper is working in BlitzMax, but I have a few problems that you can see here and here:

Despite these problems, I will finish wrapping RakNet, especially because I need it for my game ;-)
I wanted to do it for multi-platforms, but due to the first problem, I will be probably obliged to do with a dll instead of source code, so if I have no more ideas/progress on this problem, the wrapper will be a DLL, and windows only :-(

Expect something in ~2 weeks...

Stu_ovine(Posted 2006) [#15]
Good stuff. if you need a tester give me a shout.

KuRiX(Posted 2006) [#16]
Hey RepeatUntil... you say you need to use a DLL for the wrapper, but can you use a lib in .a format? Perhaps we can make a lib instead of the dll, and this will work on every platform?.

If you use the DLL,do you have the same problems in debug mode???

EDITED: Mmm, i think i am in a mistake, in a lib we cannot wrap the functions... or can we?

Dreamora(Posted 2006) [#17]
Thats not the problem.
Main reason he pointed out is the need for asynchron running code which might need a DLL (or not)

RepeatUntil(Posted 2006) [#18]
I tried to use a .a lib and include it directly but that fails miserably ;-)
In principle, if I understood correctly, the fact of using a DLL solve the problem of multithreading since complete different part of the memory are used for the 2 processes (DLL and main program). So that's why I am talking about using a DLL. However, I didn't do the test since I have to modify the .bmx file first (and this needs some work).

By the way, I want to thank Kurix because the wrapper is based on his work he did for Blitz3D!! So thanks Kurix. However, I will use the latest RakNet version with compatible commands with RakNet 3.0, so the commands will be slightly different from the Blitz3D wrapper...

KuRiX(Posted 2006) [#19]
Well, if i can help, please let me know ;)

RepeatUntil(Posted 2006) [#20]
Could a few of you test a simple example of the wrapper:
Just run test.bmx in normal or debug mode.

I have very strange behaviour. This program is very instable and crash with no error message after 10-15 seconds (release or debug mode) if I press the space bar to send a message. I am not sure if this is my BlitzMax setup, or if this is general.
So could you try and report:
- if it crashes without message
- or if it runs normally

I really don't understand because I am using the dll of Kurix which is working perfectly in Blitz3D. So thanks for testing!

Stu_ovine(Posted 2006) [#21]
Server crashes after 15 seconds without pressing the SPACE bar

Client crashes after entering the ip address

RepeatUntil(Posted 2006) [#22]
Thanks Ovine!
One more person to confirm this, please, and I will send a bug report.
Please confirm also that this is silently crashing!

Stu_ovine(Posted 2006) [#23]
Investigated a bit more.

Memory is being eaten up after

packet = RN_ServerReceive(Server)

and CPU usage is too. Program crashes silently


REDi(Posted 2006) [#24]
Silent crash here, but if I comment out (as server, and rem'd out client stuff)
format_code('packet = RN_ServerReceive(Server)')
then no crash happens.

BTW ID_CHAT isn't defined, so its sending the message starting with a null character.

*EDIT* beat me to it :)

Stu_ovine(Posted 2006) [#25]
yea but you formatted yours properly :)


RepeatUntil(Posted 2006) [#26]
OK, thanks for testing!
I have added ID_CHAT (which was forgotten).
I have added a text to display the memory used, and the memory increase all the time, and the program crashes silently after 64000.
I have also extremly simplified the code to see only important things, and you are right, packet = RN_ServerReceive(Server) seems to be a culprit here!

But the SAME DLL is working perfectly in Blitz3D and was used in Blitz3D games (Granada racer). So there is something strange going on. I will have a closer look at the wrapper, and if I found nothing obvious, I post this bug...

Simplified code is here: http://repeatuntil.free.fr/RakNetWrapper.rar

Stu_ovine(Posted 2006) [#27]
If you set GCSetMode(2) and do a manual GCCollect(), crashes instantly- but with a unhandled memory exception.

RepeatUntil(Posted 2006) [#28]
Yes, either something is wrong with the wrapper (but works on Blitz3D), or something is wrong with BlitzMax. I will explore a wrapper failure first...

Stu_ovine(Posted 2006) [#29]
Strangely - if you take out all the Racknet calls but leave RN_ServerReceive(Server) in - memory is still eaten up.

Strange you would think that RackNet would just return Null if the "server" var is not set. (and indeed the server not started)

Replace the RN_ServerReceive with ANY racknet call and the memory is easten. Just try with "RN_GetTime()"

Dreamora(Posted 2006) [#30]
I would somehow bet that it has to do with the $z stuff. Sure that it needs ASCII Strings, not UTF?

(I wrapped the Client - Server example but it behaves exactly the same)

REDi(Posted 2006) [#31]
AH-HA, to stop the crashing and memory leak, add "win32" at the end of the functions, like this...
format_code('Global RN_ServerReceive%(rakServerInterface%)"win32" = GetProcAddress(lib, "_RN_ServerReceive@4")'):D

Its not the first time this "win32" thing has done this to me, I cant believe I didnt think of it earlier.

RepeatUntil(Posted 2006) [#32]
You are my hero, REDi!!! Great, Thanks!!!! This is now working!! The wrapper will go forward now...

(I am impressed how awesome is this community!)

REDi(Posted 2006) [#33]
my pleasure RepeatUntil, looking forward to using it myself ;)

RepeatUntil(Posted 2006) [#34]
Dreamora wrote:

I would somehow bet that it has to do with the $z stuff. Sure that it needs ASCII Strings, not UTF?

I know how to get rid of the $z (using Byte Ptr and FromCString and such). But what is the difference between using $z and Byte Ptr? In which case I use which?? Thanks for the clarification, the documentation is pretty useless on that...

REDi(Posted 2006) [#35]
I think your right to use $z, IIRC its for external use, the ToCString is for internal bmax usage.

Dirk Krause(Posted 2007) [#36]
Is there any news on this? Also, is there something downloadable?

AdrianT(Posted 2007) [#37]
I'd like to see Racknet working with Bmax too. Seems to be a really nice reasonably priced network library thats easy to use.

Chroma(Posted 2007) [#38]
Anyone know what games have used RakNet?

Stu_ovine(Posted 2007) [#39]

Id love to see a wrapper for the latest version of RakNet tho. JSW online uses 2.x.

Dirk Krause(Posted 2007) [#40]
@ovine: could you provide a link to the wrapper? the link above doesn't work anymore.

deps(Posted 2007) [#41]
The link works great for me.

Dirk Krause(Posted 2007) [#42]
The link to the games from ovine works great, yes. But not to the wrapper above:


Or am I missing something?

Rene Albrecht(Posted 2007) [#43]
Link is broken.

Chroma(Posted 2007) [#44]
I'm interested in this wrapper too. Any news on it?

Stu_ovine(Posted 2007) [#45]
I can post the version I use, its the wrapper by KURI for Blitz3d, but converted to use MAX.

Heres the link to the Blitz3D version :- http://www.lcuriel.arrakis.es/raknet/

I'll post once I get chance (no source here)

Dirk Krause(Posted 2007) [#46]

RepeatUntil(Posted 2007) [#47]
Hi guys,

happy to see some interest in a RakNet wrapper! During this summer, I worked on the RakNet wrapper for a while and was able to wrap RakNet 3.0 within BlitzMax! However, this is not yet finished, it needs some more days of work. Since you give me some pressure, I can try to go a bit more quickly! I will report here as soon as possible.

This wrapper will be completely free of course (in fact I use a large part of the Kurix wrapper) and will be open source so that anyone could improve it (to add RakNet functions for example).l

Another thing: it uses a RakNet dll, so that it's only for windows :-( It is unfortunately not possible to wrap it directly with the source due to multithreading...

More news later (in one week?).

UnderwoodNullium(Posted 2007) [#48]
NOWAY!! I am going to die right here!! Omg!!

This is the s***! I love RakNet I am definitely downloading this!

Dirk Krause(Posted 2007) [#49]
cool, thanks!

SofaKng(Posted 2007) [#50]
I'm definitey looking forward to this!

Do you have any links to your old version so I can fool around with RakNet now?

RepeatUntil(Posted 2007) [#51]
No, no old link. But don't be too excited yet. I am programming less and less these days, and so the wrapper won't be 100% complete and tested. I am still doing a few tests right now, and will release this version as open source, so that anyone can improve it if needed.
I will try to have something in one or two weeks...

RepeatUntil(Posted 2007) [#52]
Please have a look here.

Filax(Posted 2007) [#53]
Very good job!, and clear code! repeat :)

Dirk Krause(Posted 2007) [#54]
what Filax says! great and thank you!

watusimoto(Posted 2007) [#55]
I have a quick question about the DLL wrapping. I understand that will work in Windows only, but the wrapper itself is pretty simple.

Are there Linux/Mac equivalents of DLLs that could be used in a similar way with a similarly simple wrapper? If so, perhaps we could distribute DLLs/equivalents for each platform, and use a compiler directive to compile in the appropriate wrapper.

Could this work?

RepeatUntil(Posted 2007) [#56]
Good question, although I think I know the (negative) answer.
I don't know if there are equivalents to dll on other platform, I don't think it works the same way...

watusimoto(Posted 2007) [#57]
RepeatUntil --

you wrote earlier that he tried to use a linux .a file to include RakNet functionality on Linux, but that it failed because of the common memory space. Did you try a .so file?

My very basic understanding of things is that the .so files are dynamically linked at runtime (like DLLs), rather than static linked at compile time (as .a files are). It may well be that the dynamic linking will use a separate memory space as the DLLs do on windows.

Read this for more info:

RepeatUntil(Posted 2007) [#58]
No, I didn't try a .so file. I think I tried a .a file because I found somewhere that it could work in some occasions (although it was a long time ago, and my memory could fail!).

I read quickly your link, but I let other people try to do that in Linux!!