Xojo Network Card Games

I’ve never don anything with Networking before so this is all new to me. Getting 2 copies of my game to communicate with one another is the next step I’m just not sure where to start. I never asked someone to write the program for me. I want to learn. I’m just asking for help on where I should start. The Chat example doesn’t help me understand how to start a connection when there is no open Window. It keeps a Window open which is not what I want. Basically in the LAN Play Window I have it where you enter a user name and then you would click “Connect” and the other player would do the same and then they can Duel together in the Duel Window after the LAN connect windows closes.

Also there are so many options in Xojo with Communication and I have no idea what I should use in my case, AutoDiscovery, UDPSockert, TCPSocket, Client/Sever approach, etc. Since I can’t find any Xojo examples for a Networking Card Game or something similar, I’m just not sure how to implement it.

As a point of background info on me, I started with BASIC well over 20 years ago and even took a course in school on it which I did very well in.

Start with a simple CHAT program as has been suggested numerous times… This will show you all the basics required to communicate between various devices…

Yup… most all of those will be involved at some point…

But isn’t this exactly what you want? That open window is where you will be displaying your cards.

Actually, none of the above. This is a web app. It maintains a list of active sessions (all the other people who are connected to your website). Communication is simply a matter of sending a message to all the other sessions. No sockets, etc., involved. See the app.SendMessageToAllClients method. Very simple. You can adjust the content of that message as you see fit.

I am not writing a web app. I am writing a Desktop App.

The connection is started in the LAN Play Window which then opens the Select Deck Window which then opens the Rock, Paper, Scissors Window which then opens the actual Duel Window.

All that is being sent are the contents of the various variables so each player can see the other player’s field. When a player plays a card from their hand, that info is sent to the other player and the game updates both player’s windows. I believe a simple JSON string would be enough. I’m just trying to figure out how to have an open connection through the various Windows that precede the actual Duel Window.

At the risk of risky things, let me add this snippet which might help.

If something is for one window only, make it a property of the window.
if something has to be used by many windows, make it a property of the app, or a global property in a module.

Add a module, call it “sharedstuff
Add connection, integer, string, whatever…
eg FavoriteColor as Color

Then from any window you can talk to/read from the same variable, and it wont die or go out of scope until the app closes.
From any window, you can use it as sharedstuff.FavoriteColor

Think of the module as a massive class, or a special kind of control or window, but there will only ever be one of it.

That explains why the Chat example didn’t help. If you want something to exist between windows, move it from the window to a module, like Jeff said. It doesn’t change the code much.

If I use AutoDiscovery, do I set it as a property, class, class interface, etc? I tried setting it as a Class with Super as AutoDiscovery but I get syntax errors saying “This item doesn’t exist” when I try setting a port number using the following code:

ADController.Bind(9097)

In the Xojo examples, Internet/Communication, there is an ‘Autodiscovery’ example
Which I guess you must have found, since the name of the control it uses is ADController

Since it shows the class as being on a window, with event handlers, the best way to deal with this is to have a single window that holds the control, with implicit instantiation turned on, so that there is one and one only instance of the window.

So take the example, strip it back to bare bones (or not… make it invisible if you like until you are comfortable with what it does), and use the one and only instance of the window as your network controller.

If it is called wndController, show it once at startup. (doesnt even have to be visible)

wndController.show

not

[quote]w = new wndController
w.show[/quote]

After that, events will fire on that window.
It can store data into global variables, and properties of the wndController window can be accessed from any other window by referring to it by name

eg

wndController.player1name

I must be doing something wrong as the instances of the app do not seem to see each other. I set up a separate windows called:

frmNetworkConnection

I added a UDPSocket with a Super of AutoDiscovery and added a Method of RecievedMessage to it and added code to let me know that a message is being received from the app on the other computer.

I also added code to the App.Open Event:

frmNetworkConnection.ADController.Bind( 9097 ) If frmNetworkConnection.ADController.LastErrorCode <> 0 Then MsgBox("Error binding port.") Quit End If frmNetworkConnection.ADController.Register("yugiohds") frmNetworkConnection.ADController.UpdateMemberList
Which is similar to the code from the AutoDiscovery example.

I have a button which sends the message so I can check to make sure they see each other:

frmNetworkConnection.ADController.SendMessageToGroup(0 , "Testing, 123." )

But only the sending app can receive the message. I’m sure it’s something so simple I am not doing correctly.

In the frmNetworkConnection I have a lists identical to the one in AutoDiscovery example so I can see for sure that messages are being sent and received.

The AutoDiscovery example works no problem with my setup which is a MacBook Pro and a Virtual Machine with Windows 10 in bridged mode so the Virtual Machine is on the same Network as the host machine.

I am at a complete loss as to why this isn’t working in my game. I literally copy and pasted the COMPLETE AutoDiscovery Window and its contents into my game and set it as the opening Window. The 2 apps for whatever reason won’t see each other. Yet if I use the example file, it works great.

I even tried 2 separate computers, my MacBook Pro and a regular Windows 10 PC. No dice.

I finally figured out this issue which I don’t think makes any sense. The Mac version was being debugged as a 64-bit app while the Windows version was being debugged as a 32-bit since the Windows IDE won’t run a 64-bit app.

Once I set the Mac version to 32-bit it all worked. Really frustrating.

The one thing I can’t figure out is why a message sent to the Mac OS version gets doubled.

Is there an easier way of sending variables to and from the apps? Something where I can send an entire class object. I could use a JSON string but certain variables would be simpler to send if I could send the whole class of variables.

Store your data in a new framework dictionary. You can easily convert this to & from json (http://developer.xojo.com/xojo-data$ParseJSON). Use computed properties to reference the data in the dictionary so you’re not always looking up key value pairs (and don’t have to rewrite your code).

Quick question: How do I tell when 2 players are connected in the same group so the game can move on to the next screen?

have a unique UUID created for each new game and that unique ID can be shared when players connect. that way you know when two+ players are grouped together.

I already use a Group ID but I can’t seem to figure out how to tell when an instance of the game actually connect to the group. Also I’ve noticed that for some reason when a Mac version receives a message it’s doubled. Even the AutoDiscovery example does this but only when a Mac version receives a message.

Edit: I take it partially back both Windows and Mac double the messages while using the AutoDiscovery example code.

I’m still having issues figuring out how to actually connect to another instance of the app. They can see each other but I’m at a loss on how to actually complete the connection so no one else can try to connect. Should I do a Host/Guest setup or something else. I need some direction as this is all new to me.

I directly imported the AutoDiscovery Window into my game and use that to start the connection but I still can’t figure out how to tell if another instance of the app has connected to the group.

How do I get the IP Address of the other player? Do I have to send it manually or is there an easier way to do it?

It should just be the address property of the TCPSocket for that player…

So I have to manually send a player’s IP Address to the other player?