Adam's Lair Forum

game development and casual madness
It is currently 2019/09/17, 15:18

All times are UTC + 1 hour [ DST ]




Post new topic Reply to topic  [ 6 posts ] 
Author Message
 Post subject: Network Programming
PostPosted: 2014/02/08, 19:58 
Junior Member
Junior Member
User avatar

Joined: 2014/01/20, 04:07
Posts: 26
Role: Hobbyist
Yay!
I have successfully implemented basic UDP network programming into a Duality game. I can run a server (cmd line) on one computer, and a client (Duality) on the same computer and my other computer, and I can successfully move squares around and sync up positions.


The Big Problem and Solution
However, there is one major obstacle: Dualitor may break if you introduce any kind of network programming. That is to say, I don't know exactly what the problems are, but if you have a component that involves IPEndPoints, UdPClient, etc and you have it actively attached to any GameObject in Dualitor then it may throw warnings, and may just stop working all together. After lots of battling I didn't think networking would work with the current state of Duality. But I found a solution!

I explain the solution better in the code, so I will give the solution here in a nutshell:

You have to use a pair of components, Networking and NetworkingDummy. Start both empty, and attach the empty Networking component to whatever object needs it (in my case the Local player component). Never attach NetworkingDummy. Then you close Dualitor. Now, you write/develop/test your Networking code and only use DualityLauncher to test. You can not use Dualitor! However if you need Dualitor (maybe to add other components, setup scenes, etc) then you swap the class/file names of Networking and NetworkingDummy. This way, when you open Dualitor it never sees the networking code, it just see an empty Networking component, and the good stuff is hiding inside NetworkingDummy for the moment. Then close Dualitor and swap back when you need networking again. It may be a cheap trick, but it's the only way I found right now to get everything working.


Wtf!?
Strangely, I was having a lot of issues last night and earlier. But right now, when I tried to do a final check to see if I could consistently BREAK Dualitor,... well.. it... worked! Lol, wtf! Ugh.. this is actually worse, cause now it's harder to duplicate the error.

But I am consistently getting an error when I have Dualitor open, I have the real Networking component attached, and I do a Build. Then Dualitor throws one of the same errors I have been seeing:

Code:
[Core] Warning: Serializing object of Type 'UdpClient' which isn't [Serializable]
[Core] Warning: Serializing object of Type 'Socket' which isn't [Serializable]
[Core] Warning: Serializing object of Type 'SafeCloseSocket' which isn't [Serializable]
[Core] Warning: Serializing object of Type 'SafeCloseSocket.InnerSafeCloseSocket' which isn't [Serializable]
[Core] Warning: Serializing object of Type 'SocketAddress' which isn't [Serializable]
[Core] Warning: Serializing object of Type 'Networking.UdpState' which isn't [Serializable]
[Edit] Info:    Reloading core plugins...
[Core] Info:        Reloading core plugin 'Plugins\GamePlugin.core.dll'...
[Core] Info:            Assembly loaded: GamePlugin.core
[Edit] Info:        Analyzing Core Plugin: GamePlugin.core
[Edit] Info:    Restoring data...
[Core] ERROR:   Error reading object: NullReferenceException at Int32 IPEndPoint.GetHashCode(): Object reference not set to an instance of an object.
[Core]          CallStack:
[Core]             at System.Net.IPEndPoint.GetHashCode()
[Core]             at System.Collections.Generic.ObjectEqualityComparer`1.GetHashCode(T obj)
[Core]             at System.Collections.Generic.Dictionary`2.Insert(TKey key, TValue value, Boolean add)
[Core]             at Duality.Serialization.ObjectIdManager.Inject(Object obj, UInt32 id) in c:\Stuff\work\duality\master\Duality\Serialization\ObjectIdManager.cs:line 95
[Core]             at Duality.Serialization.XmlFormatter.ReadStruct() in c:\Stuff\work\duality\master\Duality\Serialization\XmlFormatter.cs:line 273
[Core]             at Duality.Serialization.XmlFormatter.ReadObjectBody(DataType dataType) in c:\Stuff\work\duality\master\Duality\Serialization\XmlFormatter.cs:line 183
[Core]             at Duality.Serialization.XmlFormatterBase.ReadObject(String& objName, Boolean& scopeChanged) in c:\Stuff\work\duality\master\Duality\Serialization\XmlFormatterBase.cs:line 200



But other than this, I am able to actually connect to the server in the Sandbox. And when I stop running the Sandbox it even connects to the server again, because (I think) Dualitor runs the OnInit function for all components (to reset the scene, I assume). This extra connect might actually be annoying when testing, but it's at least consistent with the way Dualitor naturally functions and is something I expected when I started doing Network programming with it.

But I cannot explain right now why Dualitor is working!! Maybe it has to do with my Networking component? Maybe I've written it in a way that behaves with Dualitor better? I swear the whole editor was exploding before! Crashes, etc.

Ugh...

Well Adam, I am posting this all because I hope if you have time/interest, then you can look things over, play with it, break it, and maybe fix it. I am sure in the long run you want Duality to allow for network programming, so here is a real life test case. Until I get your analysis, I am going to continue working on it using my name-swap hack (to be safe).




How to run the working demo
0. Download the following package... https://www.dropbox.com/sh/6shnfmt5at9kfoj/nyM2g0Odhk/ClientServer.zip

1. Run Server\Project1\bin\Debug\Project1.exe. Make sure to make Windows and your antivirus happy. (eg. Windows asks about security, and my antivirus checks the app for 15 seconds, and then I have the choice to "Continue Execution". After this anytime I run the Server I get no security questions.) You should see a cmd-line window, and some basic messages.

2. Run Client\DualityLauncher.exe. As it starts up, you should see activity in the Server window. It should identify that the client connected.

You should now be able to move around a square (arrow keys). There will also be a square that does not move. This represents some other Remote client. It will only move if certain information comes from the Server.

Now, you can press spacebar at anytime. This sends your current position to the Server. The Server will then disperse this information to all clients. (Note: it'd normally be all other clients, but for easy testing it sends to yourself too).

So, you sent your position to the server, the server gets it and basically bounces it back. As soon as you get the information from the Server the "Remote" square will move. In this case, it will move to whatever Pos you were at when you hit spacebar.

And that's it, in terms of the demo. I have successfully tested this using just one computer (running server and client). But also it worked using two computers, on my LAN, one running Server&Client, the other running just a Client.

I plan to test over the internet (probably needing Hamachi to simulate a LAN), as soon as my friends are available. But the point is, this setup is definitely working and can be easily expanded to include other types of data sent at different events/rates.

I am still learning all the trick to network programming. I am going to continue developing this out. I can't process a nice user friendly library for others to use, but I promise to share code when possible for those willing to play with it.


Lots of information, but I hope people find this interesting and helpful. Thanks.


Top
 Profile  
 
 Post subject: Re: Network Programming
PostPosted: 2014/02/08, 20:34 
Site Admin
Site Admin
User avatar

Joined: 2013/05/11, 22:30
Posts: 2073
Location: Germany
Role: Professional
Actually, nothing in Duality inherently prevents network programming. You've simply run into an error of attempting to serialize objects that are not designed to be serialized. This kind of warning should always ring some bells:

Quote:
[Core] Warning: Serializing object of Type 'UdpClient' which isn't [Serializable]


Serialization is the process of transforming runtime data into a form that can be easily saved to file, loaded from file, or stored otherwise. It's all about saving and loading. By default, all the fields of a Component are serialized automatically, so you don't have to worry about this. But there are actually some fields, which cannot be serialized! Like, for example, runtime data that only makes sense during runtime, such as an open UDP connection. When attempting to serialize those fields, you'll run into undefined behavior and probably even errors caused by the results of faulty serialization!

To solve this, add the [NonSerialized] attribute in front of all the fields that cause this warning or are otherwise bound to be runtime-only. This should fix most of your Duality-related problems - I suspect most of them are followup errors of that serialization stuff :)

Anyway, it's great to see someone experimenting with multiplayer games in Duality. Definitely interesting stuff!

_________________
Blog | GitHub | Twitter (@Adams_Lair)


Top
 Profile  
 
 Post subject: Re: Network Programming
PostPosted: 2014/02/08, 20:49 
Site Admin
Site Admin
User avatar

Joined: 2013/05/11, 22:30
Posts: 2073
Location: Germany
Role: Professional
I've tested your prototype, but it didn't quite seem to work: Both programs appear to run, but there is no server activity when I start the client. I deactivated my antivirus program and allowed your server application to communicate with the network, but still - nothing. I've attached a screenshot of the results, and checked the logfile, but it didn't contain any useful information and no error or warning.

_________________
Blog | GitHub | Twitter (@Adams_Lair)


Top
 Profile  
 
 Post subject: Re: Network Programming
PostPosted: 2014/02/08, 20:57 
Junior Member
Junior Member
User avatar

Joined: 2014/01/20, 04:07
Posts: 26
Role: Hobbyist
I have to run, won't be back until at least Sunday, but I forgot one thing:

The Networking component has a hard-coded IP. You will need to figure out your own local IP and change it. Or worst case, make it 127.0.0.1. The IP of the server should be hard-coded into the host variable.

A simple ipconfig in the windows cmd line will tell you. Find the IPv4 one.

For example, mine is 10.0.0.2, and my laptop comes up as 10.0.0.4 usually.

SORRY!

THANKS FOR LOOKING ADAM.


Top
 Profile  
 
 Post subject: Re: Network Programming
PostPosted: 2014/02/08, 21:04 
Site Admin
Site Admin
User avatar

Joined: 2013/05/11, 22:30
Posts: 2073
Location: Germany
Role: Professional
charles wrote:
The Networking component has a hard-coded IP. You will need to figure out your own local IP and change it. Or worst case, make it 127.0.0.1. The IP of the server should be hard-coded into the host variable.


Ah, that explains it. I've checked again and it works now :)

_________________
Blog | GitHub | Twitter (@Adams_Lair)


Top
 Profile  
 
 Post subject: Re: Network Programming
PostPosted: 2014/02/09, 23:44 
Junior Member
Junior Member
User avatar

Joined: 2014/01/20, 04:07
Posts: 26
Role: Hobbyist
Adam wrote:
To solve this, add the [NonSerialized] attribute in front of all the fields that cause this warning or are otherwise bound to be runtime-only. This should fix most of your Duality-related problems - I suspect most of them are followup errors of that serialization stuff :)



Awesome! I did actually look into this, but I did not fully understand what Serialization meant. So I felt like I was stabbing in the dark. Thanks for the explanation.

I'll give that a try, and I'll continue development, and I'll post updates as I go.


Thanks, Adam.


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 6 posts ] 

All times are UTC + 1 hour [ DST ]


Who is online

Users browsing this forum: No registered users and 2 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Jump to:  
cron
Powered by phpBB® Forum Software © phpBB Group