robreuss / VirtualGameController

Software-based game controllers for iOS, tvOS, OS X and watchOS in Swift 4.2.
MIT License
462 stars 44 forks source link

hardware controller reconnect question #34

Closed phil-m closed 5 years ago

phil-m commented 6 years ago

Hi Rob, glad to see this project is still going, I'm just getting back into game dev & have been looking into local multi-player on iOS & tvOS recently, VGC is working great so far, thanks for all the great work!

Although this is a hardware controller question, I was hoping you, or someone here may be able to shed some light on an issue I'm seeing (this is running via VGC). Or maybe I'm going a little mad...

I have a SteelSeries Stratus (the smaller one) hardware controller (with latest fw) for testing, alongside VGC peripherals, they all connect & work as expected. Mainly working against tvOS 11 for this at the moment. I'm now trying to handle possible controller re-connections, e.g. if the controller goes to sleep after being inactive for a few minutes, & am seeing the following on the stratus controller:

Is this expected behaviour, & if so, is there a way to re-map the re-connected controller back to the player/playerIndex some other way? Maybe I'm missing something obvious?

Or is my stratus controller possibly playing up with the different hash values? (I know regular BLE devices on iOS/tvOS have the BLE id masked with a random value, so it can change between connections, if the deviceHash is based off that it might explain it, although it seems the controller sends it through manually which should avoid that).

I only have the one hardware controller to test with currently, will look to get a 2nd different controller to compare against soon, I'm mainly asking for sanity sake, if this is what others are seeing & have to work around, or if this is unexpected.

robreuss commented 6 years ago

I've reproduced what you are describing using a SteelSeries Stratus XL. This is a surprise to me because I assumed the device hash was a static, hardwired ID number like an ethernet MAC address. Do you know if the device hash gets refreshed when a controller goes to sleep (as opposed to our testing where we cycled the power)? My guess is that the device identifier is retained when the device sleeps and then wakes from sleep. Perhaps the assumption behind this design is that if a controller is powered off, the player has explicitly left the game and their player identity should be released, but if it just sleeps it should be retained?

Without a unique identifier for the controller, I'm having trouble thinking of a way you could map the controller back to the player identity. Perhaps if you have players enter a name prior to the game beginning, then if a controller disappears and reappears, you could pop up a selector window to offer the option of re-connecting to an existing player identity or creating a new one.

FYI, I'm working on a new version of VGC that incorporates the old functionality, but adds a Swift-based server component, to support multiplayer over the Internet using TCP/UDP. Is that something you would be interested in? If so, I'd love to hear about your potential use case so I could perhaps address it in the design. It will run on Linux, and supports a local team (i.e. multiple players on an Apple TV) playing against teams or individuals over the Internet. I don't really have the resources/skills to make it scale or perform for FPS or MMO, but it should be good for more basic games. Trying to figure out what should be in the framework and what should be left for the developer to implement.

phil-m commented 6 years ago

Hi Rob, wow what a fast response, thanks! Also thanks for testing it your end & confirming I'm not going mad with what I'm seeing ;)

I've also pondered the same thing re sleep vs a power cycle. Have just tested it & unfortunately it seems to change as well. Damn.

Your idea on entering player names could work, although adds to the start up time getting users to each enter a name. I had otherwise wondered if manually comparing all the other device info fields to make a best guess if its the same controller as before, with some sort of fallback (like your name prompt idea) if more than 1 of the same controller is detected in a session. But thats a lot of code to write & time to debug, not ideal, quite surprised Apple didn't require some sort of consistent id for this exact reason, or perhaps they intended it to be consistent, & these controllers don't. Perhaps I'll try emailing SteelSeries support, see if this is expected. On a BLE hardware product I worked on for a while, we kept & sent a custom unique id on the hardware device over to the client apps because iOS's masks the real UUID, I do wonder if this is semi-related.

Hah, I did spot & have a quick poke about your new repo's the other day & was intrigued! I actually did a brief review of online game servers a few weeks ago, just to get an idea of whats involved, complexity, likely running costs etc. Although I was mainly focusing on nodejs based ones, as I have some experience with it & so could learn, tinker & extend if needed. Hadn't even considered swift server side! As a 1 man band (currently taking a break from contract work), I've decided its likely too time consuming to focus on online multi-player, at least initially for real-time (even simple) games, turn-based might not be so bad. Although I would love to be able to incorporate online in my current game concept(s)! I was considering whether I could at least try & design the input & game state/updates with online in mind, so it could be extended to support it at a later date without a major re-write.

I'm still quite early on in the dev cycle, have a couple of small game prototypes worked-up from a few months ago, & have since spent most of my time focusing on building a base game engine/foundation that can be used across most of my ideas, learnt about & implemented an ECS, basic in-app game level editor with server side data syncing etc. (as some friends are interested in helping with level design & game play, but aren't coders). I finally got to controller support this week, so might be able to actually focus on some game play implementation at long last in the coming days/weeks!

I'm purposely trying to keep the initial game ideas small in the hope I have enough time to actually complete & release something before I likely have to ramp back up on contract work. They are mostly arcade/real-time based, but nothing like an FPS/MMO, think more 80s tile based type games like bomberman level of control/movement. My current plan, time allowing, is to get the original prototypes working under this new setup in the coming weeks & then decide which to focus on based on some play tests.

I would be more than happy to at least give your new server setup a go whenever you think its in a semi usable state (even if very beta & fragile), & give feedback etc. if you wanted. I'd like to learn more about that side of game dev anyway, & this could force me to think about how the server<->client data & interaction could/would work. Look forward to hearing more about it ;)

robreuss commented 6 years ago

That's so strange the the ID gets recycled on sleep. What is the point of that ID at all? Seems to be kind of useless for the purpose of developing functionality around it.

The choice of server-side Swift is a bit risky for me and for any developer that adopts it. Who knows if it will ultimately gain enough traction in the marketplace to have long-term viability. I'm betting it will, and besides that, I just through it would be an interesting thing to learn! It was quite a rush when I got VGC running on Linux for the first time.

I'm at a disadvantage with designing it because I'm not a game developer. I'm looking at existing server-side frameworks - if you could point me to one or two of those you were considering, that would be great.

Are most or all of your games targeting the Apple TV?

phil-m commented 6 years ago

Yep, totally agree! I do wonder if its just the Stratus firmware. When I get some time I'll try & get a couple of different controllers to compare against, & do some more detailed testing across all of them. It just doesn't make sense why they'd expose it otherwise. For the time being, I've moved onto other challenges while I mull on options on how to handle the disconnects if that really is a limitation of game controllers.

Very intrigued by swift on the server. I'm using my current small game project(s) as a way to learn swift in more depth, as my last couple of years work has kept me in either objective-c or on other platforms & languages entirely, so I've had very little real-world experience with it until recently, really enjoying it now I seem to have the hang of the basics. Swift seems to have so much traction on apple platforms & now beyond, it seems a relatively safe bet, even for server side & other platforms, I can't see interest dropping off with the number of iOS dev's out there, the ability to port easier to other platforms in the future seems a nice possibility. Part of the draw of node js, for me at least, is the possibility of writing server & client code in a single language, less to mentally juggle & jump between (something I seem to appreciate more as I get older), but I still prefer native apps vs web ui's, so have come back to swift with node backends for the time being.

I also lack much game dev experience, but am learning & enjoying the process! I didn't get as far as running any of the server frameworks I was looking up yet, but a few of the ones that jumped out & might be worth a peak were:

There's some nice documentation scattered about in the wiki's of those github projects, e.g: https://github.com/NetEase/pomelo/wiki/Pomelo-design-motivation https://github.com/NetEase/pomelo/wiki/Backend-server

These were also interesting (although mostly basics): https://gafferongames.com/post/what_every_programmer_needs_to_know_about_game_networking/ https://stackoverflow.com/questions/9033166/multiplayer-javascript-game-built-with-node-js-separating-players

Trying to find a good article I read on extrapolation & interpolation, might of been on one of the wiki's above, but can't seem to find it. Explained the 2 quite nicely, why one or the other is likely needed for most games & the trade offs of both. Even if you weren't aiming to go that far, it may be worth considering ways to allow it to be handled by the dev. Although it was after reading that I realised just how much was involved, & I've backed off for the time being, but if your tinkering in that area, I'd happily try & help out if/where I could.

And yep to targeting Apple TV, its actually my main target platform for these local multi-player game ideas, although I'm also trying to keep them usable on iOS as its obviously a much much larger user base. I've not done a tvOS release before, so its been quite a learning curve (the Apple DemoBots example has been a real help).

Your mention of a 'local team' further up is very interesting, hadn't even considered a local team, vs a remote team, opens up some nice possible game ideas...

phil-m commented 6 years ago

ah just found the link on extrapolation etc. in the documentation for another engine I'd forgotten to bookmark before: http://lance.gg http://docs.lance.gg/r1.0.8/tutorial-introduction.html http://docs.lance.gg/r1.0.8/tutorial-guide_syncinterpolation.html http://docs.lance.gg/r1.0.8/tutorial-guide_syncextrapolation.html