GameKit: sending reliable NSData to other players? - iphone

Okay, I managed to create a match between two players. Now I will do a little test about sending data to a player.
I didn't quite get the explanation about NSData. Essentially, what is it? How do I send a, dunno, array to another player?
Apple mentioned data packets could be lost. But there was a "reliable" mode to prevent that. But I couldn't find about such.
Any ideas?

Yes, you have to make your OWN protocol. "making a protocol" is something you do yourself. Something like...Essentially on the server end
// the message arrives and you then do this...
[data getBytes:&getMe length:sizeof(CommsProt)];
whereas on the client end to send messages, you do this...
NSData * data = [NSData dataWithBytes:&sendMe length:sizeof(CommsProt)];
// ...now send that data using GameKit or whatever system you end up with
and you define your protocol - at least the chunks of data - like this:
typedef struct _CommsProt
{
BOOL happyThing;
someThings wotJustHappened;
float happyValue;
float anotherHappyValue;
// etc
}
CommsProt;
If you are new to GK, be aware of this critical tip ...
Client/Server GKSessions
This could also help...
Most effective way to do networking on Mac/iPhone?
Some helpful notes...
(i) "client" and "server" mean nothing. You will be able to send the handbags of information (such as "CommsProt" above) in either direction. If you want to think of, and refer to one, end as a server (particularly if you have a hub-type arrangement), that's fine. But it's only in your head. (By the way, commonly you might use a different data structure in each direction, that's perfectly fine.)
(ii) Regarding sockets. If you get heavily in to networking, you will have to deal with sockets and write your own sockets code. However it is very likely you can choose a networking layer where you never even have to say the word "sockets"! GameKit + Bonjour, for example, completely take care of handling sockets for you, AND that combination takes care of the other incredibly difficult issue which is FINDING one of your client/servers. If you are new I recommend you completely set aside sockets for now, and use a system such as GameKit (or whatever is equivalent on Windows) for your networking layer.
(iii) Indeed AT FIRST just use something incredibly simple like GameKit, while you figure out your protocol and all the other headaches. Later, if necessary you can rewrite the networking layer, or, switch to some other package that you hear about. Happily everything up to the code examples above will be unchanged, only the networking layer will change.
(iv) Regarding WiFi. GameKit and most convenience packages, are completely agnostic to the physical layer: they take care of it for you. GK will work fine however the phones are connected -- bluetooth, ethernet, whatever! Indeed you "won't know" what physical layer is being used. (It's sometimes annoying you can't control this: let it go, users couldn't care less.)

Related

One time Internet Connection Check swift

I need to check the internet connection of a user for one time.
I thought of something like Device.isConnectedToTheInternet but I didn't find something similar...
Every solution that if found was like an internet monitor over time, but that's not exactly what I need.
Someone ideas?
Thanks, Boothosh
As Rob Napier mentioned, it looks like the only thing readily available is the NWPathMonitor, which you can use to check the 'connectivity' to a certain location, like www.google.com, or something else that would be relatively trustworthy to be available 24/7, or just the URL you are about to try and use. Here is a short HackingWithSwift tutorial for NWPathMonitor.
I know this isn't exactly your current situation, but in my projects (and a lot of peoples projects) using an API like AlamoFire is pretty common, and has a ton of usefulness for creating GET/PUT/POST/DELETE requests and of course, has a NetworkReachabilityManager which can be used to make a convenient global function for a simple true/false result for 'isConnectedToInternet' like this:
/*
Connectivity
Struct
Utilizes AlamoFire to check for network availability.
isConnectedToInternet should return true in all cases the phone has access (Cellular, No cellular + wifi, Cellular + wifi, wifi)
*/
struct Connectivity {
static let sharedInstance = NetworkReachabilityManager()!
static var isConnectedToInternet:Bool {
let connected = self.sharedInstance.isReachable
return connected
}
}//end Connectivity
See NWPathMonitor().currentPath. It will tell you the current path. This is only occasionally useful, since "connected to the internet" is not a meaningful condition. There is not concrete definition of "the internet." But you can use the NWPath to answer some questions you probably are looking for. The fact that there is an NSPath available does not mean that you can actually connect to something on "the internet." The only way to know that is to send a packet and get a packet back. So if your real question is "can I connect to a specific host," then you're going to need to send packets to that host (and that still won't prove that you can send packets to the host in the future).
All that said, there is a little UI-level usefulness to asking "if I tried to connect, would it certainly fail?" And currentPath can help you answer that. It just can't tell you if it would succeed.

Read from a serial port in Swift 4 using ORSSerialPort

I've been wanting to make an app that sends instructions over serial to my LED controller. For this to work, I need to read what the controller sends back after sending it a command. I found the following function in ORSSerialPort:
func serialPort(_ serialPort: ORSSerialPort, didReceive data: Data) {
// Do things
}
However, is there something like ORSSerialPort.read()?
I don't think ORSSerialPort.read() is a good idea. I know some other serial libraries are written that way, but the only way for that to work is for read() to block (possibly with a timeout) until a byte comes in on the port. Blocking I/O makes it a lot harder to write a good, responsive app, and I want to guide developers using ORSSerialPort away from that approach.
Instead, you should indeed implement serialPort(_:, didReceive:) in your ORSSerialPort delegate. When data is received by the serial port, that method will be called with the received data and you can do whatever you'd like with it.
That said, if your device communicates using a command/response type protocol (ie. every time you send a command, the device sends some response), you ought to look at ORSSerialPort's request/response API. It allows you to explicitly define the format of expected responses to commands, and ORSSerialPort itself will handle asynchronously waiting for, parsing, and validating responses. See the documentation for more info about this part of ORSSerialPort. The library also includes a sample project, RequestResponseDemo, that demonstrates using this API. Both Swift and Objective-C versions are included.
The ORSSerialPort library is popular and generally good. However, I'd found that it didn't work well with TTY serial devices. This was primarily because of its use of IOKit to discover serial ports -- it would only discover physical devices.
This is likely OK in your case but where you want to test your code but don't want to connect to a physical device, it falls over. Good code always needs a testing framwork. So, check out https://github.com/kpishere/POSIXSerialPort for a very simple serial interface API it is just what you need to write and respond to incoming data and also works with physical or virtual devices (as Unix was originally envisoned!).
To your question though, you don't want to call read() directly. You get into understanding whether or not, "is it a blocking read?" Then you get into dealing with threads. Both of the suggested APIs insulate you from that and allow you to think in terms of an event driven model -- this makes for much simpler code.

Unity - trading card game architecture

I'm trying to develop a TCG(trading card game) in Unity(I'm Unity newbie) and currently stuck on the architecture of the project and the card effects in particular. Coming from web development background for me all the logic and card effects should be on the server but going through some tutorials for Unity I think the logic should be on the client and I should use a simple room-based server to notify for player actions. Is that correct?
To summarize - where the game logic should be(e.g. card effects, rounds etc)? On the client or on the server?
I actually worked on one of the major TCG's out now for iOS/droid, so this is coming from experience. You definitely want all game logic and rules to be on the server. Do not trust your client to be the source of truth for any game outcomes etc. People will be able to hack that by tampering with the data sent back to the server. They don't have to decompile the game to do that, it can be done merely by sniffing the net traffic.
That said, you may end up with some duplicated logic on both client and server, only so that you can enforce game rules and display the outcomes without always hitting the server. However, your server is always the source of truth and the client is just there to accept input and display outcomes.
The general flow was the client would send a message requesting a new game to the server. The server would respond with the cards for each side and the opening move for the first player. Then the client would simply parse each move and display the outcome. On the cards objects we had methods for many of the actions, such as DrainHealth() and BuffAttack(). When called, these methods would trigger things like particle effects and sound fx attached to the card script.
Yeah the effects should be on the client, I assume your game will be turn based right? You might want to take a look at photon then:
https://doc.photonengine.com/en-us/realtime/current/getting-started/realtime-intro
They have a loot of good tutorials about their API and it's well documented :)
Hope that helps you,
good luck

Can an NXT brick really be programmed with Enchanting and adaption of Scratch?

I want my students to use Enchanting a derivative of Scratch to program Mindstorm NXT robots to drive a pre-programmed course, follow a line and avoid obstacles. (Two state, five state and proportional line following.) Is Enchanting developed enough for middle school students to program these behaviors?
I'm the lead developer on Enchanting, and the answer is: Yes, definitely.
The video demoing Enchanting 0.0.4 shows how to make a proportional line follower (and you could extend it to use a PID controller, if you wish). If you download the latest version, 0.2.2, it includes a sample showing a two-state line follower (and you can see a video and download code here). You, or with some instruction / playing around, a middle-schooler, can readily create a program to do n-states, and, especially if you follow a behaviour-oriented approach, you can avoid obstacles at the same time.
As far as I know, yes and no.
What Scratch does with its sensor board, Lego Wedo, and the S4A - Scratch for Arduino - version as well as, I believe, with NXT is basically use its remote sensor protocol - it exchanges messages on TCP port 42001.
A client written to interface that port with an external system allows communication of messages and sensor data. Scratch can pick up sensor state and pass info to actuators, every 75ms according to the S4A discussion.
But that isn't the same as programming the controller - we control the system remotely, which is already very nice, but we're not downloading a program in the controller (the NXT brick) that your robot can use to act independently when it is disconnected.
Have you looked into 12blocks? http://12blocks.com/ I have been using it for Propeller and it's great and it has the NXT option (I have not tested)
It's an old post, but I'll answer anyway.
Enchanting looks interesting, and seems to be still an active project.
I would actually take the original Scratch (1.4), as it's is more familiar and reliable.
It's easy to interface hardware with Scratch using the remote sensor protocol. I use a simple serial interface (over a USB-adapter) which provides 3 digital inputs and 3 digital outputs. With that, it's possible to implement projects such as traffic lite, light/water/heat-sensors, using only lets, resistors, reed-contacts, photo-transistors, switches, PTSs.
The costs are < 5$
For some motor-based projects like factory belts, elevator, etc. There is not much more required, a battery and a couple of transistors/relais/motor driver.

Client/Server GKSessions

I have an application that is set up so that if the user selects the device to be a server it creates a GKSession in server mode, and if it selects cient it create a GKSession in client mode.
Whats happening at the moment is the server is sending out the data fine, which is just a string containing the time of the server.
The problem starts however, when I have one client already connected to the server and I then connect another client .. the problem is: the second connected client connects also to the first client for some reason.
I want to be able to not connect to other clients and just connect to the server. Any help would be great
You've hit the nail on the head:
Strangely enough, GK allows an "any to any" model.
This is a truly impressive achievement, technologically, by Apple
BUT !!! ........it is very important to realise that this is a very unusual option. In networking - for games - you almost always want a "normal" client-server model.
Over some 30 years, a huge amount of science has become established, regarding doing networking using a normal client-server "spoke" model. And indeed, for game programming, 99% of the time you definitely need, and want, a standard client-server "spoke" model.
This bears repeating:
(1) Apple created a highly unusual "peer to peer" mode when they made GK.
(2) That is technologically astounding, but,
(3) this novel P2P technology would not, actually, be used in very typical networking programming for games.
(4) Very confusingly: all the documentation talks about the P2P mode. This is confusing because: if you are new to networking programming, it would make you think that is "normal". In fact, it is very likely you will never use the P2P mode at all, when making real normal games.
To repeat!
If you are new to networking, when you see all the mentions of P2P mode in Apple's doco, it's important to realise that the (amazing) P2P feature is more of a novelty. In fact, for essentially all game networking, you will definitely need normal "everyday" client-server "spoke style" networking.
Just to ne crystal-clear .. it is much, much, much !! easier to do real-life networking using a normal client-server "spoke" model.
The P2P mode is "really clever" and you could definitely spend some time experimenting with it. For instance, it is fine for just "sending chat around" to every device connected.
But again (if you're a new networking programmer) you should realise it is rather a novelty. You will have to program using a normal, everyday, client-server model.
So ......................
given that you are going to program in a normal everyday client-server model.
Your first job becomes, strangely enough, "disabling" the P2P aspect!!!!!
This is easy enough if you know how. Here's precisely how to do it...
sessionMode:GKSessionModeServer .. on the server.
sessionMode:GKSessionModeClient .. on the client.
So, for normal client-server programming, don't use GKSessionModePeer anywhere.
Secondly, don't forget in your clients, simply do not implement didReceiveConnectionRequestFromPeer:
Finally if all that doesn't work! In your clients, in peer:didChangeState:, you need to do this ...
// so this is in the CLIENT...
-(void)session:(GKSession *)session peer:(NSString *)peerID
didChangeState:(GKPeerConnectionState)state
{
switch (state)
{
case GKPeerStateAvailable:
// you have found the server!!
// [session displayNameForPeer:peerID]
self.theServerWeAreConnectedToPeerID = peerID;
// you will definitely need to save that
[session connectToPeer:theServerWeAreConnectedToPeerID
withTimeout:0];
break;
case GKPeerStateConnected:
// MAKE SURE it's our server
// not just some bizarre peers, etc etc.
if ( [theServerWeAreConnectedToPeerID isEqualToString:peerID] )
{
// you are connected - launch your tick or whatever
}
else
{
// completely ignore this!
}
break;
case GKPeerStateDisconnected:
if ( [theServerWeAreConnectedToPeerID isEqualToString:peerID] )
{
// you have been disconnected from the server!!
}
else
{
// weirdly this is telling you that one of your sister
// clients, has been disconnected from the server. IGNORE
}
break;
// GKPeerStateUnavailable .. likely not relevant
case GKPeerStateUnavailable:
// do nothing, ignore
break;
// from the modern doco..
// "The delegate should ignore GKPeerStateConnecting changes
// and implement the session:didReceiveConnectionRequestFromPeer:
// method instead." .. blah blah .. for us that comment only
// applies TO OUR SERVER, NOT here in the client.
case GKPeerStateConnecting:
// do nothing, ignore
break;
}
}
Just to repeat. It is very likely you will want to NOT-use the P2P model: so, all of the above explains "how to DISABLE the P2P stuff."
Once again to repeat for absolute clarity:
GK (surpriginsly) contains a P2P mode. This is technologically amazing. You can, of course, use P2P mode for simple networking problems (notably chat-like problems). In practice, all the typical networking needs of any real game (whether an FPS, sports game, or whatever) must be done in ordinary client-server paradigm. (It would be staggeringly difficult to use P2P mode.)
Thus, it's necessary as a "first step" to know how to "not use" the P2P system in GK -- that is explained above in length.
(If you DO want to use the P2P system - you're all set, go for it !!)
GK is fantastic if you can figure out all the subtleties. With GK and ASIHttpRequest, you can basically do anything between computers at least in a basic way.
This question has hit the nail on the head ........ GK has a (highly unusual) P2P mode, and the documentation focusses on the P2P mode, which can be confusing to newcomers. Again P2P is incredibly clever, but as a rule you do not want the P2P mode. You want a normal clients-with-server spoke model, which is incedibly easier to program. Hope it helps!