Matchmaking Innovation & Best Practices with Unity (GDC '19)



welcome I'm brandy house I am the product manager for connected games at unity and I'm joined today by three of my friends and colleagues from Google cloud and unity today we're going to share a little bit more about what we mean by connected games and how matchmaking fits into that overall problem space then Joseph will walk us through an open match demo and where the open source project is today then Caleb will do a demonstration of custom match functions and why we believe these will open up new kinds of innovation and matchmaking today and then Micah will finish us off with an overview of the Google cloud ecosystem for games so what do we mean by connected games a few of you may have seen me and Micah talk about this before you know it could be single-player games that are more dynamic because they're connected through cloud features and it could be all the way through to MMO spaces you know persistent games that are always online and the way we think about this space the further down the chart you go the more cumulative the problem space is so you have more technology and more design problems that you have to solve to be able to make those kinds of games it just doesn't get easier it only gets harder as you go down and what we've been hearing from game does is that the real-time multiplayer space and the and the persistent world spaces are still too hard and too expensive and too difficult to build especially and really the entire space is something that more and more devs want to get to connected to so today we're focused primarily on the real-time multiplayer stack and from what we've learned to make them successful to get the latency Security scale goals that your game needs the tech stack really needs to be a dedicated game server to Paulo G which means that you have an entire stack from the client runtime the networking code all the way up to the game server hosting and management and all of your services and how you connect all of those pieces together so we've been collaborating with our Google Cloud friends to create new services and new opportunities for how we glue this entire ecosystem together and specifically today we want to talk more about matchmaking we've heard from many developers that this is actually still one of the hardest unsolved problems for games you know at its fundamental level you really just need to take players that are coming in to play your game form you know quote unquote good groups and then connect them to a game server it seems relatively simple but from what we've seen that that definition of good is actually quite subjective and it changes game to game you know if it's a more casual game you may care about social graph distance if it's a hyper-competitive game you may care more and more about skill matching and so being able to define what good means for your game is a surprisingly hard problem and there's not been a ton of innovation in the space because so much of it is still about how do I run a scalable technology as opposed to how do I make this a game design problem so from here I'm going to hand off to Joseph who will give an update about open match and the progress of the open source collaboration we've been working on thank you brandy can we switch over to the demo computer great alright so today I'd like to briefly highlight some of the recent things that we've been doing an open match in the open source version give you a little bit of a preview of upcoming features so what you're looking at right now is some metrics I have a proof-of-concept matchmaker that's running in kubernetes on Google cloud I've seeded that with about 60,000 random players or so this is pretty similar to the demo that we gave at unite Berlin last year if any of you have seen that it is on YouTube I highly recommend you watch it this one is a little bit different it's sending four requests at a time instead of one request at a time you can see it's churning through about ten loops per minute four requests per loop ten or eleven loops so it's getting about forty five matchmaker matchmaking loops going per minute that's the bottom left-hand the top right-hand is approximately how many players are getting matched for a minute sorry top left top right is roughly how long each request that's going up against open match is taking you can see here they're taking a little less than two seconds and the bottom right sort of shows you how many of the requests are actually finding a match you can see there's a red line at the bottom showing that like nothing is not finding a match right now so for requests at a time is not particularly high by open match standards what we really want is to be able to get a lot of concurrent processing done simultaneously so let me bump this up from four to about 400 and we're gonna see what happens to the graphs hopefully everything should scale out smoothly the idea here is we're gonna slice up the parts of the player pool that we're looking at into smaller and smaller pieces and look for a match within each one of those all at the same time concurrently across lots of processes in a kubernetes cluster so some recent work that you nnedi has finished and then contributed the design back to the open source project for making matchmaking functions stay alive in the kubernetes cluster or not spin down in between cycles so that you get much lower latency matching is really helping us bring this to life right now so unfortunately my Griffin instance is set to only refresh every 30 seconds so we're gonna have to be slightly patient to see the big numbers come up but hopefully as you can see here like we're able to run a few hundred sometimes this will get up over a thousand matchmaking functions per minute and that's able to put you know tens of thousands of players through the system per minute finding matches for them this is kind of more about going wide caleb is gonna talk a little bit later about customizing the way that you're looking for players and trying to make each search that you're doing go faster this is more about kicking off as many searches as you can at a time so the last thing I'd bring your attention to in the bottom right you can see the red line is starting to creep up now so what that signifies is in certain parts of the player population we've found every available match there so when we're looking in that part of the player population for example if you think of like a tiered game like a competitive shooter like overwatch or something like that this red in the bottom corner is representing like your grandmasters or your very low bronze players like we have found all the potential matches for that there's not enough players in the pool to make anymore matches at that part of the population so that's what that's showing in the bottom can we go back to the slides great so now I'm gonna pass it over to Caleb and he's going to talk about customizing those matchmaking functions Thank You Joseph my name's Caleb I'm technical lead on matchmaking at unity and we've been working with Google on open match from the beginning you know we want to solve technically challenging problems for game developers and make those solutions generally available to game developers at large in this case as Joseph was showing some of these innovations are coming in the form of services infrastructure for matchmaking and so what makes open match here's clicker such a good fit for this problem is that it's court has this highly customizable component called match functions so we've been talking a little bit about match functions but there's some examples on the repository but not really a cohesive guide for how to author one so over the next couple minutes I wanted to try and demystify match functions a little bit for you it helps to start with this a little bit of a simplified services model for how to think about matchmaking services so on the left you'll have your game client with your players they'll broadcast to the service a type of intent this could be thought of as like a game mode some quality of service data it's a regional game service where your game servers are hosted these will go through a front door which will provide the secure data from some type of persistent database think like skill history inventory these are things that you don't really want the game client to be trusted to submit at this point the service will package those up and send those into the open match front door no per match front door is really good at indexing that data making it highly available to through a query API for the actual match functions we'll get more on the match functions in a second that's the blocks of these blue blobs here what's nice is open match takes care of kind of activating those functions handling the cadence of those functions kind of as Joseph was showing we can achieve this high breadth of distributed processing and so you only have to worry about this little atomic component in that the end results of a match function is that it produces a couple like proposals you can think of them open match resolves the collision of proposals so if players appear in more than one proposal it is a distributed system after all open match will actually give you a the ability to D collide those and out the backend come matches and so there's kind of two pieces to this one is understanding the player data and then the other side is the actual authoring of the match functions and so we'll start with player data skill is kind of the super common candidate for talking about this it's something we all have a rudimentary sense for and while we're not gonna talk about skill specifically this is kind of just an example of some distributed data that you might have in your distribution of data you would have in your matchmaking system at any given time and so from a match function perspective we're talking about segmentation so we're going to look at this when your match function activates you're gonna want to take like a slice of this data and not like the full you know like the middle one is super tall there's a lot of players in there so you would even take a smaller slice of that and the match function is mostly gonna focus on taking those 10 200 you know 10 200 players or so if you put those together arguably that would be possibly a close match if it's a pretty comprehensive skill system and so if we move a little further back we can start to identify kind of the core set of player data you're gonna need to be worried about for like a basic matchmaking experience and so on the top right here we have skill blow that is wait time which is kind of an interesting one from a match function perspective for this particular metric you might want to have a match function for example that is going to specifically focus on the right side of this chart find players that have been waiting a long time for matches and then specifically target those players with proposals that have a higher urgency or priority to provide those back to open match open match provides this evaluator concept that allows you to use that priority to prefer those matches over other matches that players might be appearing in so this helps solve for I don't have a deterministic way to understand why players aren't getting matches quickly now if you've worked in a dedicated game server architecture on the top left you'll recognize some of these numbers so these are going to be round-trip times to regional data centers where your game servers can be ran this is super important for matchmaking because you want to take these players that have an actual like location on earth they have that last mile they have to be concerned about and so you can find that common node that they're all gonna connect to to get that tight low latency gameplay that you want in your game so for a match function I could say give me players that have less than 120 millisecond ping to us West's with this slice of skill with an average wait time and if that produced you know 8 or 80 matches as proposals those would possibly be like basic ideal matches but of course this and this doesn't even scratch the surface you have tens hundreds thousands of data points that you care about when you're doing your matchmaking because good really does depend on what you're trying to do with your game whether it's a social experience or a super competitive experience so level reputation attached inventory one of my personal favorites is current win streak so if I go into a game I've won nine games I'm gonna go against a set of players possibly who have also won nine games in a row and so that's really what open match is trying to solve is taking away some of the technical difficulties of running a matchmaking service and provide that sandbox for creating a powerful custom way to bring your players together that's not talked about actually writing match functions this is by no means like a prescriptive way to do this if you first get started though I have a suspicion they'll mostly look in this form so step 0 is to describe your data make your data and design it anything that you can preempt as an index going into open match that's definitely going to be preferable to trying to build that on run time out of segmentations that you've been creating then once you're in the actual function you've been activated you want to build and run this query when you get back your tickets you'll want to do some type of optimization most algorithms between two and three it's kind of whatever you'd like to do a lot of algorithms will have you like build hash maps and do normalization on the pool that you're actually working with so you can kind of create that richer algorithm 3 put the players together an example that I'm going to show I just use a bucket cessation mechanism where if the ticket fits into a bucket you go in the bucket and if there's not room in the bucket you go in the next bucket and so it seems kind of rudimentary but it actually choose a pretty interesting result and the last thing you can do inside of your match function is you have an opportunity to put a little extra data in there so if the players asked or have preferences for the map they're going to be on now might be a time that you would want to like roll a die and actually assign what map they're going to play on so the server when it gets that information it's already configured and so with this completely bespoke approach it really opens a lot of options that are sometimes difficult to achieve with a configuration or rules based matchmaker for instance I mentioned well like dye combining your data or making decisions based on the population you're working with inside of that query so for example I were here for skill but the confidence of that skill isn't very good for the players I got back it's a new game I shipped a new mode I don't know how good they are at that point I could technically switch to relying on another metric to try and figure out whether or not those players should play together and I can do that inside of the same match function this is also a good opportunity to inject something like a social graph so if you have your own social graph you could make a highly performant off box call has to be pretty quick we could try and resolve interesting connections that you can form out the population you're working with there we go all right so if we can switch over to the demo laptop so showing code on stage is always an interesting challenge I do my best not to like show just a huge mess of spaghetti that's hard to grok so I apologize if some of these functions seem very helper e but I think they kind of highlight the life cycle of what a function might look like and so when you're writing your match function you'll likely be working in something like a harness open match we're working on providing a whole suite of harnesses for different languages you're working with in this case a lot of folks who use unity no C sharp and net so we have a harness we're working with dotnet in this case it's this configurable match function and as you can see it has this execute function this is your entrance to your match function we will receive a kind of context object from open match this will contain some interesting information about how I was activated some filters that the backend created I have a query interface for accessing my ticket data and executing those queries on those index as I mentioned and then we have this custom piece of configuration that I've know submitted through a dev dashboard in the backend and so this will mostly follow what we I was showing you a second ago we're going to submit this query as I said the context contains these filters that I've made on the back end I will collect my tickets and then these two functions which are those he'll pre-function cells talking about place tickets on teams is just going to take a bucket if you fit you go in the bucket and then I'm going to basically expand a major make a whole bunch of buckets for the the second one here place teams on proposals my match function is actually configurable and that's what this is up here so depending on the number of teams I want in this game it will then take as many buckets as I need and collapse those into a proposal so if I need 20 it'll take 20 buckets to put them together now opportunity for customization before I put a ticket on a team there's an interesting gameplay design that I want to introduce my game is very creative collaborative game I like it when players have an opportunity to interact with people that they like interacting with but in this particular case it's a very collaborative environment so I also want them to identify folks that they might not want to keep playing with from session to session and so into my party concept I've introduced this idea of a list of other parties that I'd like to not continue matchmaking with so in other words I was playing I had a great group going we were all talking and it's not that someone wasn't collaborating they just weren't talking so I want to play with more people who like talking so what I've done here is I've introduced a hash map of those party IDs and I simply D collide for these two here am I avoided so does the party team I'm trying to matchmake into do they have players that don't wanna play me and do I avoid them so these will be are there parties inside that team that I have elected not to want to play with and then we will take note of some interesting metrics when we actually run this function and just to clarify this concept isn't quite like reputation I'm not identifying people in my community who are going to quote bad or poisonous this is kind of just a self elected mechanism that your players can use to avoid players that they just don't want to play with and so because this is just a function and I'm using this I'm writing this right next to my own game logic I can write unit tests for this I can mock my data layer I can verify that when I change something I don't regress and so this is a very powerful way to test your like matchmaking logic so here I've mocked my ticket interface with some memory data I have this function that I'm calling that just generates traffic in this case I'm generating 10,000 tickets of randomly one to four players on each ticket now in addition to that I'm also generating one to ten random other parties that each ticket is trying to avoid and so there's a whole bunch of players self electing into this interesting game mechanic now here's that custom config I mentioned in this case I'm having 16 to 20 players on a team and there are four teams per match and with this I can actually run this function and we can see how quickly execute and how it does everyone can see that okay great so as you can see there were 20,000 players that were currently matchmaking in this pool now I have a filter here for us West good ping so in other words I'm only gonna get players that are near my us West data center 4,000 tickets about technically qualified it looks like only one ticket wasn't able to fit into a given match and I actually was able to avoid eight matchups that if I hadn't done anything those players would have been stuck playing with players they didn't want to play with again well this doesn't seem like a high number this compounds over the course of your your game cycle if I'm able to avoid eight every single loop or 16 every single loop we're talking about thousands of improved matches that day so the end results of this was 400 proposals which are potential matches to open match which is quite a few and this only took 148 milliseconds to run now there are some optimizations that I could make around my bucketing it's pretty not a particularly advanced bucketing system but as long as you you know keep your performance between here and like a second or so you're looking at a pretty quick matchmaking turnover especially once you get distributed so that seemed to the code if I get back to the demo slides awesome and so multiplayer matchmaking built on open match we've been working on this handy service that helps bring dedicated game server developments and scaling but with that super powerful and accessible experience you've come to expect from unity we've developed this new multiplayer matchmaking system so it fully integrates with multi plays phenomenal world scaling technology it's still open match at the core so you still get access to the same customizable components like custom match functions and custom configuration alongside that tooling and lifecycle management experience that will be coming to the unity ecosystem of course it's a hosted service that means don't worry about operations scaling monitoring and because it's a service it's also engine agnostic so no matter where you're coming from whether it's unity or something else you can get started with multiplayer right away great with that I will let Micah talk more about the cloud gaming ecosystem with GCP Thank You Caleb that was an awesome demo it's been fun watching the evolution of open match over the past year in Google cloud we really believe strongly in being engine agnostic platform agnostic so part of our vision for for gaming is to make sure that you can get your service is running and reach as many players as possible so you may have seen the announcement for stadia yesterday which works really well with Google cloud but we're not only powering stadia we can power any games we're really ready to scale up whatever workloads are thrown at us if it's stadia we're on the same private network as those stadia instances which is great because you can have predictably low latency really great value with no internet egress and great data security because that data never gets onto the internet but having that infrastructure hosted on Google cloud also enables you to power the other platforms that you're targeting for your game we also have solutions around data and analytics figuring out player insights like which players are going to pay or not pay in the next seven days which players are going to leave your game in the next seven days lots of great opportunities to figure out how to optimize your your game and make a better experience we have a great relationship with unity and we really appreciate our efforts together and our friends at multi play have done some really amazing work over the past 20 years we're excited to see what they can do next so I thank you very much for joining us I'm waiting for my slide to advance sorry there we go if you want to get involved in our community please jump into open match it's an open source community it's easy to get involved maybe you just want to ask some questions join the slack channel there's an email list if you're just kind of poking around if you want to be a contributor we are more than welcome to join in and grab some issues we're excited to see what the community wants to do with this project and finally a part of our vision for Google in general is to connect to create connect and scale your games and so we're bringing the best of Google together and this is something you're gonna see a lot more from us coming forward thank you [Applause]

Be First to Comment

Leave a Reply

Your email address will not be published. Required fields are marked *