You might find useful the 39DLLzge, a DLL which is a ZGE-specific variant of the 39DLL, originally developed for GameMaker. The purpose of 39DLLzge is to provide networking and buffered file access features to ZGE applications. You can easily create multiplayer games and other network-aware applications with ZGE now.
Technically, 39DLLzge is a wrapper for windows networking libraries (Winsock 2, WinINet, etc.) with simpler interfaces based on integers, floats and strings. Because the original 39DLL is not compatible with ZGE (incompatible types used in the DLL interface cause access violation errors), I had to customize it for ZGE data types. I also made the following changes and extensions:
- Removed useless buffer functions incompatible with ZGE data types. Size of the DLL has also been reduced.
- Changed the udpconnect function, now enabling to bind sockets to specific ports.
- Added the getbroadcastaddress function used for obtaining a broadcast address.
- Fixed some minor implementation/compiling problems.
The DLL is accessible from an external library adaptor (ZExternalLibrary component) which also provides description for each function in its comments.
Problem: If ZGE variables or component properties directly refer to the string values returned by the library (implemented as static *char) ZGE causes access violation error when the DLL is being unloaded. It seems that ZGE releases DLLs before variables or components are accessed for the last time. It would be nice if ZGE releases DLLs as one of the final steps in process termination procedure. Anyway, to overcome this unpleasant behavior, I created a library of "safe" variants of 39DLLzge functions which return strings. If you use these safe variants in your applications, the returned strings are not referred directly and no access violation errors occur.
The attached zip file contains the DLL (39DLLzge.dll), an empty ZGE project with the external library adaptor and the library of safe functions (EmptyNetworkingProject.zgeproj), and an example of how to use the library (MultiplayerExample1.zgeproj).
The example shows how two different applications running on the same or different network nodes placed in one subnet can discover each other and exchange data. In this case the exchanged data is position of a local model controlled by MouseModelController. The local model is drawn in green, the remote model is drawn in yellow. The best way how to test the application is to compile it to an EXE file and run it several times on the same or different machines. Due to dynamic assignments of ports, the example can run several times on the same machine, however, the best way how to demonstrate real possibilities is to use different machines. If you run the application more than three times, you can see how different pairs of applications are being connected. You can also exit one application and see how its previous peer tries to find another one to connect.
Please terminate the application only by Esc key. If you just press the 'X' button on the window, the application does not send the termination message and the connected peer does not know about it. BTW ZGE should allow execution of the OnClose and OnLeave sections before actual termination of the process also after pressing the 'X' button.
The example shows several useful mechanisms of a network-aware application, namely: automatic discovery of communicating nodes (a simplified version of a leader election algorithm), broadcasting, dynamic assignments of ports to sockets, stateful communication over UDP, implementation of message types, sending and receiving of application-specific data (positions of models in this case), etc.
Remark: I created also a more generic version of this example with full implementation of a leader election algorithm which enables to connect many nodes, not just two. However, it is too complex and not so easy to understand.
39DLLzge provides also a buffered style of accessing files, more flexible than is provided by the File and FileAction components. The main reason why like 39DLLzge more is that file operations can be accessed from expressions.
Note: I realize that the current implementation is not optimal and can be improved. In addition, it has not been tested on real project up to now, so I expect some bug fixes and improvements in future.
So have a look at 39DLLzge and have fun!
Any comments are welcome.
Networking with 39DLLzge
Moderator: Moderators
Networking with 39DLLzge
- Attachments
-
- 39DLLzge.zip
- 39DLLzge.dll, empty networking project template and example.
- (27.53 KiB) Downloaded 845 times
Last edited by Rado1 on Sat Nov 12, 2011 3:22 pm, edited 1 time in total.
Hi Rado1,
This is great stuff and thanks for sharing! Multiplayer looks real easy with this library.
Nice workaround for the string functions. Strings are notoriously difficult to get working between DLLs and applications because it is not clear who owns the memory occupied by the string. If the DLL itself owns the memory of the strings it is returning (as I suspect happens in this case) it will collide with the ZGE string garbage collector that frees memory when any expression or component no longer references the string. Will you be sharing the source of the DLL too?
Can you clarify what you mean about pressing "X". Is the OnClose event not executed when the quit() function is called? I'll see if I can fix that.
This is great stuff and thanks for sharing! Multiplayer looks real easy with this library.
Nice workaround for the string functions. Strings are notoriously difficult to get working between DLLs and applications because it is not clear who owns the memory occupied by the string. If the DLL itself owns the memory of the strings it is returning (as I suspect happens in this case) it will collide with the ZGE string garbage collector that frees memory when any expression or component no longer references the string. Will you be sharing the source of the DLL too?
Can you clarify what you mean about pressing "X". Is the OnClose event not executed when the quit() function is called? I'll see if I can fix that.
Hi Ville,
by 'X' I meant the window close button (usually placed in upper right corner). The OnClose and OnLeave sections are executed correctly after the quit() function is called (that's why the example captures Esc pressing explicitly and uses the quit() function). Pressing the close button ('X') does call neither OnClose nor OnLeave sections.
Attached you can find the source files. I used CodeBlocks IDE and MinGW compiler.
by 'X' I meant the window close button (usually placed in upper right corner). The OnClose and OnLeave sections are executed correctly after the quit() function is called (that's why the example captures Esc pressing explicitly and uses the quit() function). Pressing the close button ('X') does call neither OnClose nor OnLeave sections.
Attached you can find the source files. I used CodeBlocks IDE and MinGW compiler.
- Attachments
-
- src.zip
- Source files
- (15.07 KiB) Downloaded 837 times