Jump to content
  • Advertisement

David Xicota

Member
  • Content Count

    0
  • Joined

  • Last visited

Community Reputation

644 Good

About David Xicota

  • Rank
    Newbie

Personal Information

  1. One of the recurring questions I get is how to exactly make a turn-based game that has a coherent data structure. Because you're already great coding features for your games, all you may need is a little guidance on how to organize your design to make the things you want actually work. When you see the following example, you'll see how easy it is. Stuff needed to build a turn-based game To keep things simple, let's say you want to build a classic tic-tac-toe game. What features should be expected from a game like this? Multiple simultaneous games. Players should be able to have multiple games with different opponents taking place at the same time. Different game status. Every game should have a status that indicates what to expect. Waiting, created, running, finished or cancelled. Play with listed friends. You could have the option to challenge your friends to a game or add new friends to the list. Play with random users. You may want to play with people you don't know. Play same skill users. You might want to play against random players that have a similar skill as you do. Luckily, making a game with all these features is quite easy! All you need to know is how to lay out the features to make them work like you want. Here are a few questions you should be able to answer. #1 How are you going to store data? In this case, I assume a NoSQL database. There, game data is stored in collections, which is like a table in an SQL database. There are some differences though. In a collection you store objects with a similar concept, but they don't need to have the same number of "columns". In fact, in a collection, objects have attributes instead of columns. How many collections does the tic-tac-toe game need? What information should we store in every object? How does every process work inside the game? To know these, first we have to determine the data structure of a game (match). Designing the game structure Our "games" will be objects stored inside a collection we can name GAMES. Every "game" object has these features: It is shared by two (or more) players Allows players to make moves only on their turns It has a winning condition It has a winner All players in it can update the "game" object We'll store all these features in GAMES collection, which must be readable and writeable by any player so they can work properly. #2 How will the game structure look like? Obviously it will depend on the kind of game you'd like to make, but in the tic-tac-toe example we're doing you'll need: Users. Players involved in each game. Status. Whether it is a waiting, created, running, finished or cancelled "game". Current turn. In tic-tac-toe, there will be a maximum of six turns between both players. Current user. Which player has the active turn and can make a move. Movements. List every move, which must be ordered by turn and has to contain the information about: User who made the move Position occupied on the board {x,y} when the move is made This is how the structure of a turn based game looks like. Most games will have a more elaborate board than we're dealing with in this example, so you'll need a complex matrix of coordinates, and so on. But for this example, the board can be represented by a simple array of positions. Let's see our board of coordinates so we can represent movements in the "game". 0,2 1,2 2,2 0,1 1,1 2,1 0,0 1,0 2,0 The format of the objects used here is JSON, so every "game" will have this structure: { 'users':{ // 'user1': id_of_user1 '1': 55448343d3655, '2': 33129821c1233 }, 'status': 'running', 'currentturn': 3, 'currentuser': '1', 'movements': { '1': {'user': 55448343d3655, 'position':[0,0]}, '2': {'user': 33129821c1233, 'position':[0,1]} }, } #3 How will you manage the users? Regardless of the method any user starts a session with (email, Facebook, silent) he or she will always need a profile. Every user has to be assigned a unique user id for the profile, where you can store any additional info you need. Important notice. This profile is public for every other user that asks for it. You should create a collection for "Users", and store there all their profile information for your game. User public information In the user profile we are going to store the following information that can be seen by the rest of users: Nickname. The name the user wants to be listed as. Avatar. The name of the image she is using as avatar. The fastest method is referencing an image already in the game package. The alternatives are URL of the file, or ID of the downloadable file in you storage. Friend list. The list of user id's that are in the friend list. Adding new users to the friend list We'll have to create a screen flow that allows the players to search for other players in the game and add them to their friend list. The best way to add a new user to the friend list would be to store the user id of the entity, not the nickname, not the avatar, or any other concepts. Important notice. Every object stored should have been assigned a unique id, which is what you should use to look for the whole entity information when you need to challenge friends. #4 How to play with random users of same skill? Players will be able to play with random players around the world. Or, to be precise, players in your game database. Now you know all these you're ready to create any asynchronous game you want. How can we make two players find each other and play a game? The most common solution would be to create a collection named "random", or "randomqueue" and make it readable and writeable by all users: Own(er) users and Other users. When a user wants to play with a random opponent we will need him to create an object on that collection indicating he is "waiting" for another user to join. Besides, we'll need to store specific data that lets the user who wants to join the game decipher whether she is an opponent of same skill. This is what you should store for this tic-tac-toe example: User id. Object id of the waiting user because the opponent must be able to download the whole profile if needed. Nickname. So it can be shown on screen easily. Avatar. To have the picture shown on screen easily. Skill. To find the right opponent and offer a balanced gameplay. Should we create a new object every time a user wants to play random opponents? Not really! The algorithm to implement should be something like this: Make a search on the "random queue" collection looking for a user that is not me, and whose skill is close to my skill rating If the result is empty, create my own object on the queue for which I will be waiting If there are results: pick one create a game send a notification to the opponent via server script Calculate the user skill rating In order to foster a balanced matchmaking system, it might be a good idea to have players of similar skill play each other. One way to calculate the skill level of a user is to design a system similar to an Elo rating system. With a system like this, you can have a more balanced gameplay. #5 How to notify users about their turn? There are different ways to create a notification mechanism to alert users it is their turn to move or any other game event. Our preferred method are push notifications, though you may want to have an alternative mechanism just in case push are blocked by the user. Push notifications To let users know it's their turn, we'll create a server hook post-save script for the collection GAMES. This means every time a user creates or modifies a "game" object the script will run on the server side to send that notification. The script we'll add does a very simple thing: If the match status is waiting: Pick the current user id Send the user a push saying "It's your turn" If the match status is created: Pick the user who doesn't Own (didn't create) the match Send the user a push saying "Mary is challenging you" Alternatives to notify users How can you notify users it's their turn if they blocked push notifications? One option you have is to create a pulling system. This is how it'd work: If your game detects push notifications are blocked, you can ask the server about your "games" status with an established frequency. You can do this by searching the GAMES collection or by creating a custom script that returns the information you need. If changes to the "game" are found, you can update the scene, and if there aren't the player can continue playing. To sum up You have to determine a few key things to build your turn-based game: How to store data How to structure a game How to manage users Now you know all these you're ready to create any basic asynchronous game you want. Are you using the same techniques to make your own turn-based games? Or something entirely different? Please, post questions or your techniques in the comments section! This was originally posted in Gamedonia blog.
  2. Good stuff is bound to be spread!
  3.   EDI, I'm glad you chimed in, because your solution is very clean. Congrats!
  4. One key to video game success is to be constantly releasing small updates. This alone might be a compelling reason to develop expandable games. There are a plethora of reasons why games are successful, but what's for sure is that players want to feel their favorite games are alive. They demand you to solve annoying bugs that affect gameplay, they like to have extra content to play through, and they love to see when you are able to introduce community proposals into the game! This ideal situation means: You are going to be dealing with the app stores very frequently, which will delay your updates. This will impact your ability to appropriately schedule updates, limiting your marketing strategy. It's not all bad news though. There are ways to add new content to your game and having control of when new updates are launched at the same time, so you can keep your customers happy and make reliable marketing campaigns. What are expandable games used for Imagine you are creating a game with lots of levels, say a match-three game, such as Candy Crush. You'll have to design a lot of levels. Developing triple digit levels takes a lot of time, and you still have to figure out the kind of levels that are going to work best with your audience. Should you spend all your efforts, money and brains designing all levels for the very first game version? You could do all of them at once, but luckily, you don't have to. You can set a system that allows you to publish new levels independently of when new versions are published to the stores. When well structured, using a downloadable content system will help you free your team from publishing all the small tweaks and updates to the stores. Following I'll detail how you can expand your game using DLC. First steps to develop expandable games and bypass stores This is the basic outline you should consider to expand your games. I'll stick to the match-three example I started with, but it can be applied to any kind of game you're developing. Step One Use a mechanism to define your levels with an XML file or JSON document. It could be the complete level definition, or just a meta description and a binary file to be downloaded and imported into your game. You could include any information you need: Name Difficulty Level order in a map Images shown to the user Price in virtual coins (when needed) Publish date (for extra control) Version of the content Step Two Make your game check for new content every time it's executed. Either from the splash screen or the map screen. In case the new levels are premium content, you could check while players are at the in-game shop. Step Three Download new or updated content when it is found, and import it into your game. This is where DLC comes into play. Step Four Let the user know that new content is available. Automatically scroll the map screen to show the new levels, whether they're locked or unlocked. Set a "New" badge, or banner notification on the content category that got updated in your shop. Now that you know the mechanism, publishing new content should be easy: Create the new content Create the XML file or JSON document that defines it Make it available on the content server By doing this, all your active players will have access to new content automatically. What can you make of this mechanism The advantages of developing your match-three game (or any game) in small pieces of downloadable content are plenty! You get a more flexible game that can adapt faster to make players happier about the game. Let's dive into some scenarios in which it is beneficial for you as well. Scenario #1 Difficulty adjustment Let's say your analytics reveal your game has a severe player drop at level 6, indicating that maybe this level is too difficult for most players. You don't want to have a majority of frustrated players, because they could decide to cop out of the game. You could address this player drop rate by adjusting some key parameters in the level. In a matter of hours, all players in all devices would have the updated level 6, avoiding all store delays. Having a quick reaction to player behavior is really important to optimize your business model. Scenario #2 Bug fixing Some bugs, especially in the first versions of the game, are unavoidable. Imagine you have a bunch of players complaining about an annoying bug that happens only in certain levels. If the bug is easy to fix, you could have the error free level up and running as soon as you solve it. It makes your players happier, and hopefully, more loyal to the game they like playing. Scenario #3 Game extension As mentioned before, you don't have to release the complete package of levels at once. You could launch with a fraction of the total, and make your game download follwing levels according to the player's progression. What are the upsides? Your game is smaller, meaning it's easy to download and test. Win-win situation. Your game is ligther on the device because it simply takes the minimum necessary space. In case a player needs to free disk space to install new games or apps, your game will appear at the bottom of the disk-usage list, and will be more likely to live another day. Once again, a winning situation. Your game is updated and players will have downloaded the levels only when needed. They will always have the latest version, which is bugfixed, and with the latest additions to keep them loving the game. Player engagement is also a winning situation. Once you get the hang of the technique, I'm sure you'll be able to implement more complex solutions and deliver players a better gaming experience. That's all for now! I hope this introduction on how to expand your games got you thinking of new interesting ways of using DLC and server code in your games. How do plan to use this? Please, leave a comment. This was originally posted in Gamedonia blog.
  5. Hi all! From your responses, there are a couple of issues you’re concerned with.   Costs and timeout issues.   Yes @LoneDwarf, I have used this technique in a couple of games back in the day. Disclaimer alert, so have many of my customers. The trick here is finding a solution or service that lets you cut costs, because setting up all these in-house, if you aren’t that big of a studio, might not be very profitable. So yeah, I’m with you here.   Maybe I wasn’t clear enough in the article @jwezorek. Timeouts wouldn’t be a problem the way I’d make the game. Firstly, when a player downloads a game, he or she should be able to play it as soon as the download ends. Please, don’t make them wait longer for extra download of assets, it’s just bad user experience. Which leads me to the second point. I would never consider not including in the app store download (ipa or apk) the necessary content for a complete first gameplay session.   What I suggested was to download extra content that is beyond the first game experience, or to expand its levels.   That said, what I could see working is serving new bug fixed versions of the game through the server, so you’re able to offer a better user experience, thus less player churn. When this bug fixed version has been tested live, you could submit it to the app stores so it actually becomes the original download package from the store.   The same could work to add new levels, or to adjust difficulty parameters for instance.   This would reduce your costs, but at the same time give you the possibility to react fast introducing bug-free “patches”, or testing “versions” to see which one works best for your goals.   I have another article up my sleeve addressing exactly (for Android) what @jwezorek suggests :-)   Sure! @tnovelli is spot on using a CDN. Serving content from the closest point is really important if your game can be downloaded worldwide.
  6.   Good!   It'd be really interesting to hear how is (has) the technique working for you when you actually use it in your game.   Drop by again when you've got any data, please? :-)
  7. High scores might be a concern. You might want to consider this though: Is high score consistency more important for your game than providing a more enjoyable experience for a wider player base? Food for thought.
  8. Picture this. After you've fought hard to release your game and you're lucky enough to get a pretty decent number of users downloading your game, they get tangled up in Level #8 and can't manage to get past it. According to your analytics service, they seemed to be enjoying the game so far, but now the users are logging in at a lower rate. You're losing active users. What's going on? There's no question they like your game. Why would they play up to Level #8 if they didn't? The thing is maybe you overestimated the user's ability to reach enough proficiency in the game to advance to further levels. Level #8 might be too difficult for most users and that's why they are no longer logging in to the game. Thus, you're losing users. There are many solutions to the problem. You could reduce the number of enemy waves, add player stamina, change the timing of the game or add more game levels before they get to Level #8, allowing users to be more game-savvy by then. You do what you have to do Ok, you decide to modify the game's parameters to ease it on your users so they keep on enjoying the game and choose to stay. Say you're a programming beast and that you're able to swiftly adjust the code and successfully test the game mechanics in one day. That's good and all but you still need Google Play or the App Store to approve it and publish it - a day for the former and a whopping 7 days for the latter. The lack of control over the response time for the in-game modifications hampers your ability to make the game progress. I don't want to be a bummer, but you're still losing users. Having passed the period of time for the changes to go live - which seemed longer than you care to admit - users still have to accept to download the latest version of the game. Some of them do it right away, some might do it at a later time... or never at all. After all that rush to get the newest version active, it is still up to your game users having the latest version if you want to see whether the fixes have a positive effect. Right, you continue losing users. It's really hard to get good feedback from the users - and react accordingly - when not all of them are running the latest version. You can turn it around The use of external servers to store game mechanics data is a rapidly increasing tendency among game developers. Offering flexibility and a quick response is key to be adaptable to the needs of your users. Imagine a service that cuts your response time to a minimum, gives uninterrupted game play to your users and lets you test different approaches at the same time. Why store parameters in an external server #1 Never let others dictate your response time Your response time shouldn't be much longer than what you spend on tweaking your code. Fixing it to have the changes go live barely at the same time, you'll be able to deliver a quicker response to your users' needs and keep them engaged. Getting user data faster allows you to decide if the changes came to effect or if you need another iteration of changes. #2 Don't annoy users with a game update download Having your users experience the updated game on-the-go releases their need to download any game updates manually. They'll always play the latest version of the game so you'll get very reliable user data because there won't be different versions running at the same time. #3 Find solutions on-the-go Upload different solutions to the same problem to simultaneously test which one performs better among users. Split testing subtle code differences will return twice as many data, which means reducing the time you spend to find the best adjustments for the game. Server side scripts allow maximum configurability Take this as an example. You could create a config collection in the server side to keep a simple config JSON. This would be the code for it. { "levels": { "1": { "difficulty": 1, "time": 60 }, "2": { "difficulty": 3, "time": 70 }, "3": { "difficulty": 5, "time": 80 }, "4": { "difficulty": 7, "time": 90 }, "5": { "difficulty": 9, "time": 100 }, }, "adsplatform": "iads", "coinseveryday": { "1": 10, "2": 20, "3":30, "4": 60, "5": 100 } } Every time a user opens a new game session you can check if this config has been changed or not. If it has, it'll start the download of the new game's config and will start using them right away. Besides, you can also implement A/B testing with one custom script very easily. Create two or three JSON config samples in the collection. Define a custom script - new server function - called getGameParameters. Call this function every time a user logs in to your game. This function will be a simple Javascript - using a round robin technique - that will decide what JSON has to be sent: A, B or C. This way the decision point is on server side, can be easily changed and you will be able to test different simultaneous configurations to get better results. Now you know you can improve user experience storing game mechanics in the server side, what other situations do you think you could use this for your game? I'd like to know! Leave a comment. This was originally posted in Gamedonia blog.
  9. Spot on! I should've included this tip in the article, because I think it's an essential best practice.     This is really up to you, but I personally wouldn't notice the player. Though, it could be very useful for you to store the info of what game version works best for you (and the players!) to make better design decisions moving forward.
  10. Are you using server scripts in some way to iterate your game, or plan to? I'd like to know if anyone is actually doing it.
  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!