herzbube / littlego

Little Go. An iOS application that lets you play the game of Go on the iPhone or iPad.
https://littlego.herzbube.ch/
Apache License 2.0
139 stars 54 forks source link

Add support for Game Center turn based matches #164

Open herzbube opened 11 years ago

herzbube commented 11 years ago

Feature requested in a customer review in the USA app store for 0.11.1.

herzbube commented 10 years ago

Research documents:

Basically, what this is about is an API by Apple that helps with finding other players, organize whose turn it is, and send game data from one device to the other (maximum of 64 KB). The Apple Game Center service takes the role of an intermediary between players.

There are already a number of Go servers (e.g. KGS) that could be used for finding other people to play with, so it's questionable whether this feature makes much sense. One advantage that turn-based gaming has over a server such as KGS is that turn-based gaming is asynchronous, i.e. players can take turns whenever they have time. However, there is already the Dragon Go Server (DGS) which fills this niche, and on iOS there is the app Dragon Go Client that lets people play turn-based matches on DGS.

puremourning commented 9 years ago

I think the key differences with Game Center are familiarity and simplicity. Case in point, I showed my mum (in her 60s) how to play go on her iPad and she loved it (she actually beat me in her second teaching game, albeit with a pretty hefty handicap). She'd love to play me more (I live a long way away), but KGS and IGS don't really offer the simple familiarity of a friends system and push notifications for invites etc; they generally present a sort of intimidating interface, particularly if you want to arrange a private game, just remotely. I haven't used dragon go, but again it requires some third party servers and registration. Explaining all this to my mum, and organising offline, eg via text message is a bit too much.

The apple 'ecosystem' for these sorts of things is based around the 'just-works' mentality, and I think little go could fill a gap in the market here. Since Boardz was removed and none of the paid aps I have come across seem to support a simple private pvp system, I think Game Center, with its familiarity and peer-to-peer nature could work nicely. The matchmaking could work too, but as you say the larger networks are likely to do that better. It's possible of course; a simple Elo go ranking system could work well, though I think achievements and friends and invitations and voice chat are probably more worthwhile than global leaderboards.

But anyway, I like little go and I think this is a good idea. So much so that I'm willing to implement it. The vision is mum can send me an invite, I get a push notification, can accept and we can start playing a game (eg of an evening), chat and review and save our games for the inevitable showing off next christmas! Maybe after 50 games I get the 'lose your first 50 games' achievement...

I have some ideas about how it could work which, if you're interested, we could discuss? There is a slight challenge with this in that to use Game Center in dev you need to enable it in get iTunes connect and set up provisioning profiles. I'm not sure exactly how to achieve this via a 'fork' but I'm willing to do the research, though I suspect I will require some input :)

Let me know if:

My credentials: 10 years as a c++ software engineer at a global organisation (no formal iOS experience, but hobbyist)

herzbube commented 9 years ago

I have no specific plans for the feature, I just know that it is one of the better ideas lurking in the issue queue. So if you are interested in getting this implemented, hey, welcome aboard!

I suggest you contact me via private mail under herzbube@herzbube.ch so that we can discuss more details.

puremourning commented 9 years ago

Just to let you know, in case you're wondering, I've been tinkering, reading and prototyping a bit. I've made some good progress on understanding what needs to be done. It's quite a lot of work and seems to end up being quite pervasive, as you can imagine. I'll send over a more detailed update soon, just wanted you to know that I haven't given up on this. I solved the game centre problem temporarily by changing the bundle id locally for testing and setting it up myself in iTunes connect.

I do have one quick question if you have time: what's the role of fuego in a human-vs-human game? I see that by default fuego thread uses 100% CPU after a handful of moves when i play human-vs-human. It seems to be the pondering. I think that due to the use of the "default" fuego profile set to maximum strength, the app uses lots of power/battery pondering, but i can't find a good reason for it to think so hard. I suspect there's a good reason fuego is busy even though it doesn't get to play, such as in case the user hits the "computer play" button, but i thought i would check. (in game centre match, i expect to hide the computer play button - no cheating!)

herzbube commented 9 years ago

Since you didn't contact me I have been wondering a bit :-) Good to hear that you were successful in setting up the project - it's always been a bit of a worry to me whether the whole build process would be intelligible to anyone but me.

Re your question: You have guessed correctly, Fuego is pondering in the background mainly so that it can provide good suggestions when the user taps "computer play". It's also useful when the user wants to see "Player influence" - more pondering time translates into better accuracy of the influence estimates.

At the beginning of the game no pondering is going on probably because the moves still match Fuego's opening book. I guess pondering starts as soon as the actual moves start to deviate from the opening book moves. Whether or not the "default" profile should be set to maximum strength is, of course, debatable. The user can change the strength, but I suspect that not many people will find those settings, so it might be worthwile to think about changing the "default" profile to strength 4 (i.e. no pondering). I'll have to think about this...

Hiding the computer play button in game centre matches sounds reasonable. Of course, given a sufficiently high developed urge to cheat, this will not stop someone from getting help elsewhere, but let's not tempt them unnecessarily :-) Do you think the button should be hidden in local human vs. human games as well? I must admit that I have never really thought about it being used to cheat, I kind of assumed that people would use it to let Fuego show them alternatives when they discuss their games.

One more thing before I shut down: I noticed you have forked the repo, so I assume that you have seen the stuff I did to update the project to Xcode 6 and iOS 8.

puremourning commented 9 years ago

Well, i'm not going to lie - the build process took me some work to get going on my system. But you have documented most of it in human-friendly format and the scripts are simple enough to understand, so most of the effort (for me) was that I didn't have enough disk space on my mac to download earlier SDK versions (SSD was a great idea, except... limited) so i had to upgrade the project to iOS 8.1 just to build it.

Thanks for the explanation on pondering. Changing the strength to 4 with no pondering will likely save valuable resources on the devices. We also have the option of just not pondering of course.

One option with the computer play is perhaps to change it to computer "hint". Other go games like SmartGo have this sort of feature - it's still "cheating" but it allows you to decide if the computer move is in any way better than the one you've been reading for the last minute or so :) I think for any human-turn where computer-play is initiated, it might make sense to have a confirmation dialog. In a local human-vs-human game it is less easy to cheat because you have the risk of a punch in the face, whereas in the local-human-vs-remote-human the remote player won't know.

Yes i forked the repo. I'm new to this github lark, so I have been doing the development in my clone of the base repo. I will add my repo as an upstream and pull across from the main repo. And yes, i noticed you also upgraded the project to iOS 8 and did a much more thorough job than I did.

Finally from me for tonight, a progress update. I have a working* prototype turn-based game. For some definition of working. You can start a game, invite a player and play alternate moves in the game. Brief summary is that i'm using the "backup" sgf file as the game data (the game state stored in Game Center) and using the LoadGameCommand to load it when it is the local player's turn. This is quite slow on the iPad 2, but works lovely on the iPhone 5s and iPad Air 2. I suspect this will require more thought, but it has been a very enlightening experience in terms of the foibles of Game Center and has given me a pretty good idea of what is needed (with less hacking than in my current prototype). I have found your excellent documentation and code comments invaluable in getting to this stage, so thanks - it's something quite rare, even in the professional world! I'm still working on a complete specification/design which is starting to look more in focus now that I can see the game mechanics in action.

herzbube commented 9 years ago
  1. There already was an old feature request for "computer hint" (issue #28). You've made me think about this again, and I must admit that when I take all the implementation details into account the feature suddenly seems quite attractive. I've added my thoughts to the issue and promoted its prio a bit. Thanks for giving me these jolts! :-)
  2. Coordinating our work: I'm pretty new myself to GitHub's collaboration features, so let me quickly write down the process that I think should yield the best results. My ideas are based on my understanding of how pull requests work, after reading the GitHub help pages in the section "Collaborating".
    • You fork my repo on GitHub (you already did this).
    • You then clone your forked repo to your local machine and work on the local clone. Make sure that you work in a newly created topic/task branch. The topic branch must branch off of "develop" (because that's where I finally want to integrate your changes).
    • You push your local changes to your GitHub repo.
    • You create a pull request that I can use to integrate your changes. When you create the pull request, make sure to select the branch "game-center-164" in my repo to receive the pull request. This is a topic branch I just created, based on "develop" but without any commits. I plan to integrate your changes via my own topic branch because I expect this to be a fairly large and possibly long-winded process, and I want to keep my "develop" branch in a clean state that allows me to create an App Store release at any time. Having my own topic branch also allows us to sync intermediate steps of your work.
    • To minimize the risk of huge conflicts when it is time for the final integration merge, I suggest that you sync your repo (and especially your topic branch) from time to time with the changes in the "develop" branch in my repo. I am aware that this adds the burden of resolving conflicts to your work, so I will try to refrain from making any sweeping changes :-)
  3. Your prototype: That description sounds deceptively simple :-) Earlier you wrote that changes were pervasive, can you provide a hint or two about that? Don't let me push you, though, I'm just curious. Regarding using the .sgf file as the Game Center data: My thoughts went into the same direction, it's quite an ideal vehicle for the pure game data. The only thing that we need to be sure about is that the .sgf file does not grow larger than the maximum size allowed by Game Center (I believe I once read something like 64KB?). Maybe check out how the file looks if a game has 500 turns? But then I guess we can always solve the problem by sending the file zip-compressed.
puremourning commented 9 years ago

1, no problem :)

  1. Yep, that approach looks great and is roughly exactly the github model. i just recently learned it by contributing to the (quite wonderful) YouCompleteMe vim plugin.
  2. The best designs are deceptively simple, right ? :) Yes it is slightly more complicated than that, but not fundamentally. It's pervasive in that there are tendrils, the complexity of the actual logic isn't very high though. Let me try and give a quick summary of the approach so far, and what my thoughts are going forward.

Lots of the below is just brain-dump notes, so forgive me if it isn't totally coherent. A lot of the way the prototype works came about from ignorance of the game centre mechanics and the littlego architecture/mechanics, so I think now is the time to decide the approach rather than hacking much further @)

Game Center overview

The Game Center programmer's guide contains most of the information below, but I have summarised what is relevant to littlego.

Game Center players:

Game center matches

Game Center has 2 types of match which are interesting to us (i think we can ignore writing our own comms and running our own servers!) :

Turn-based matches

Real-time match

What i've done so far

Players

Then we need some way to integrate Game Center players into littlego’s Player classes

Starting a game manually (new game command)

I think this needs more thought and i suspect the use-case should go something like:

Playing a move

Game representation, GameKit data, and communication protocol

Receiving a turn event

Ending the game

Viewing existing games, resigning and multiple simultaneous games

puremourning commented 9 years ago

FWIW if you're curious, i have pushed the hack prototype to my repo as game-center topic branch: https://github.com/puremourning/littlego/tree/game-center. Like i said it's very hacky for now.

herzbube commented 9 years ago

Ben, thanks very much for your outline! I just wanted to let you know that I've read through it and made some preliminary notes myself. I am very curious about what you have there, and will take a look at your topic branch ASAP. Please give me a few days, though, the next week could be a bit stressful work-wise - and I'm also in the middle of cobbling together the new UI for the iPhone 6 Plus. I don't work on Fridays, so I should have time then at the latest.

One final thing: This issue is getting a bit long... what do you think of moving our communication somewhere else? I don't know what the best alternative would be, though. I am used to mailing lists, but this may be too old-fashioned. Or if you like we could try GitHub's wiki feature? Any other suggestions?

herzbube commented 9 years ago

This was a really cool experience: Clone your repo, build everything, run, it works. Great!

I must admit, though, that I haven't taken the time yet to set up the app configuration with game center capabilities, so I haven't been able to fully test your prototype. Also, I still need to read through the Game Center Programming Guide.

I have reviewed your code changes, and for a prototype this has certainly been neat work! Even if there are some hacks - hey it is a prototype, so no need to be shy. For the same reason (it being a prototype), I think it doesn't make much sense if I am nitpicky about any details. The only thing that I would like to mention is: Do we really need a new game type? Game Center games have two humans playing against each other, so IMHO GoGameTypeHumanVsHuman is still appropriate. Maybe we could give GoGame a new attribute "isGameCenterGame"? We would also have to create a new enumeration that directs the logic in NewGameController and NewGameCommand (e.g. something like NewGameType).

Instead of moaning about code details, I have decided to write down some details how I imagine things should work. This includes design guidelines and use cases that (I hope) should cover game setup, match making, and turn play - all except the end game, which I haven't thought through yet. You can find everything on this wiki page. Some notes:

My next steps

And some final stuff that didn't really fit in above:

puremourning commented 9 years ago

Wow! Thanks for all the input. I will consume it greedily.

Do we really need a new game type?

Probably not - it just seemed natural as i was shoehorning the whole thing into the NewGame* stuff :)

You may not have noticed it, but assert() does not work

I didn't notice, no. Thanks for the tip! I'll use something else

And I hope it wasn't too much of a problem that the project does not use ARC.

No problem at all. I'm a c++ developer by trade so manual memory management is very natural to me. Objective-C's and in particular cocoa's approach is different, but not so scary: the rules are simple. I've never actually used ARC.

I must admit, though, that I haven't taken the time yet to set up the app configuration with game center capabilities, so I haven't been able to fully test your prototype

My experience with the Game Center sandbox has so far been that it is a bit of a nightmare. I have managed to set up 3 test user accounts in iTunes connect, and after a lot of pain managed to get 2 of them to be friends. It might make sense if you're going to test my build for me to pass you the details of the test accounts rather than you having to jump through the iTunes connect hoops. There may be some shinanigans required with the team provisioning profile, but i'm certainly open to adding your id to whatever is required.

Some advice on Game Center Sandbox:

If you want to set it up independently, here's the short version of the instructions

Finally, the sandbox is just notoriously horrible. Check the game centre forums on developer.apple.com, for example:

 Elo rating

How does ELO rating work? Where is this rating done? Where is it stored? In Game Center?

http://en.wikipedia.org/wiki/Elo_rating_system

I actually wrote a very simple Elo rating system for my friends and i. The short answer is that is really a style of rating system that adjusts both players' scores based on the result and the relative strengths of the players involved. If a weak player beats a very strong player, the weak player's rating is increased (and the strong player's rating decreased) in proportion to the difference between their initial ratings. The basics are very simple, but the cleverness comes in how the various coefficients are calculated and how you map a score (an integer) to the various kyu/dan levels. Different servers and different go associations all seem to use something different. I implemented the simple algorithm from wikipedia(http://en.wikipedia.org/wiki/Elo_rating_system), and the coefficients from sensei go (http://senseis.xmp.net/?EGFRatingSystem). The rating is stored in game centre, updated by the app when a game ends. The fiddly part is players with no rating - typically a player who hasn't played enough games shouldn't affect the opponent's score while their real rating is determined (imaging a dan player just joining the system - they need to play a few games to get their rating correct, but they shouldn't be allowed to affect their opponents because their rating is so skewed). TBH i'm not sure how to solve this, without knowing how many games the opponent has played. Might require an honour system!

I'll respond to some more of the points directly on the wiki page after i've processed everything.

herzbube commented 9 years ago

FYI: I just merged a branch with a lot of changes into develop. I recommend you merge all that stuff into your cloned repo before you continue. If you run the iPhone 6 Plus simulator you can admire :-) the new layout.

Design/Implementation of the new layout have kept me busy for the past month. I am currently excited by "one more thing" :-) that I urgently want to implement before I finally turn my attention back to Game Center. You have not been forgotten.

herzbube commented 9 years ago

OK, so I got everything working here on my side, with 2 sandbox test accounts that are friends of each other. Thanks to your warning I first read through Apple's docs before I jumped in and configured everything. If you do everything exactly as they tell you, it works pretty well - for me the only thing that didn't work out of the box was the two accounts becoming friends. I had to log in 2 or 3 times until I was finally able to receive the friend request. I must admit though, that it seems much too easy to shoot yourself in the foot: One login with the test account on the production environment and the account is trash. I just hope that it's not that easy the other way around...

Anyway, I was able to start a new game and to go through the matchmaking process. When black played the first move, white correctly received the invitation. Great! The next thing I will do is step through the code, just to familiarize myself a bit more with the game center API, and to maybe add a few more notes to the wiki page. From then on, though, it will be your call again to make the next move :-) while I will switch back to implement the last feature for the 1.2.0 release (AGA rules).

Cheers, Patrick

puremourning commented 9 years ago

Great to hear!!

Sorry i have been distracted with other things lately so haven't made much progress. I have merged in your latest changes (magnifying glass is ace!) and am ready to make progress again.

herzbube commented 9 years ago

During the last month I spent a lot of time on implementing support for AGA rules (issue #221) and IGS rules (issue #223). The main problems to solve were:

  1. Everything in Little Go assumed that a game always progresses with strict alternating play.
  2. A game always ends with 2 consecutive pass moves.
  3. Once a game ends, play cannot be resumed without discarding the last pass move.

These limitations are now gone, hopefully without introducing too many new bugs :-) Especially interesting is that if, during scoring, players do not agree on the life & death status of stone groups, it is now possible for them to resume play and continue to play out the dispute. While this is of limited use in a computer vs. human game, I think it is an essential feature for human vs. human games, and thus will turn out to be something we will want to integrate into the Game Center "workflow".

While working on all that life & death dispute settling stuff, it was natural to think some more about Game Center integration. I also had some notes left over from studying Apple's "Game Center Programming Guide", so I ended up dumping all that stuff into a new section at the bottom of the wiki page.

Finally, a warning: When you merge my stuff into your Game Center branch you will probably get conflicts in NewGameController and NewGameModel. The reason is that I had to somewhat redesign the "New Game" screen, because there are 3 new end-of-game rules, and with those new rules the screen started to turn into a real rule-selection monster. So I simplified the screen, throwing almost all the rules out into a separate "Advanced New Game" screen. I also attempted to simplify the internal controller logic - many of those ugly nested switch/if blocks are now gone. I hope you won't be too angry at me for breaking my promise not to making any sweeping changes. It's for the greater good, you know :-)