Jump to content
  • Advertisement

GameDev.net

Admin
  • Content Count

    517
  • Joined

  • Last visited

  • Days Won

    2

GameDev.net last won the day on July 13

GameDev.net had the most liked content!

Community Reputation

311 Neutral

2 Followers

About GameDev.net

  • Rank
    Administrator

Personal Information

  • Role
    DevOps
  • Interests
    Art
    Audio
    Business
    Design
    DevOps
    Education
    Production
    Programming
    QA

Recent Profile Visitors

The recent visitors block is disabled and is not being shown to other users.

  1. I have been working in the VFX industry for twenty years and as an artist, I've always found it difficult to work with the technical tools, especially for environment creation, so over the years I have developed a lot of art-friendly tools to make my job easier. I started porting some of my tools over to real-time engines and my young daughter was watching me paint some trees on a landscape and was fascinated and wanted to have a go, a few hours later she was still painting, and I wondered if there was a market for something like this. Lesson 1: Everything takes twice as long as you think it will I sketched a quick GDD in November last year and thought it would take a month to build a simple diorama creator. While I got the basic framework happening in a few weeks it actually took a little over 2 months to get it to a polished state and in January it was ready and I released on itch. Lesson 2: You need external sales to make it on itch With no social media followers or any previous announcements, sales were dismal on the first day, so I simply posted the trailer to various subs on Reddit and sold a few thousand copies in the first month. I was pretty happy about that as I have had a ton of people tell me releasing on itch was pointless, which would be true if all you did was release it there, but it turns out that if you get a bunch of copies sold outside of itch, you will be at the top of your tags where you can catch their traffic organically and then also get featured by them as they see you selling and the potential in your game. Lesson 3: If you keep updating you will keep selling I could have left it at that, but I had a lot of suggestions from my users and spent the next 7 months updating it regularly and getting ready for a steam release. Overall I had 4 major updates including adding castles, more assets to build with, Landscaping tools and the ability to import your own models. With every update I would get more sales as I had another trailer to share on Reddit, more sales would also mean a bump back up to the top of your chosen tags on itch. Lesson 4: Find your audience In the beginning I was sharing trailers with the usual indie game subs but soon found a hungry group within worldbuilding and dungeons and dragons, so made sure that I gave them tools like map makers that would help them with their uses, and every update would gather thousands of upvotes on those subreddits and also a lot of sales. So make sure you find interested groups outside of just the usual gaming subs. Lesson 5: You can advertise to Reddit but very carefully Reddit is a fickle beast, you can do really well on it or fail miserably, the key I have found is to offer something useful. I had success with the D&D crowd as I was making things they wanted, I made a couple of iama's that did well not by saying "check out my game" but by letting them ask questions about how to get into game dev. Both Mac and Linux subreddits are more than happy to see your game or app as there seems to be very little software for them so I recommend building to that if you can, one of the rare subreddits where you can freely advertise. Some of the bigger gaming subs are hard due to the number of posts they get but providing you are sharing something fun and catchy, you can have a lot of success there, but I warn you its a matter of timing and luck. One gif I posted got downvoted immediately, so I delete it and waited a few hours and posted again, and boom front page. I don't know what the formula is lol but you have to experiment, and it seems that a failed post might not be your fault but just posted at the wrong time and or day or even just caught a bunch of grumpy Redditors lol. For me what has worked is posting a few hours before the US wakes up, during mid-week, possibly after sacrificing a chicken on your keyboard Lesson 6: You need fans or marketing before going to steam In August I set up a Steam page, people were still abusing the wishlist system by changing their release dates and I hardly got any myself due to that until 3 days before I released when they finally fixed it and my wishlists finally got up to a few thousand. I really needed to get as much of my previous users to buy again on steam so that I had enough launch sales for the algorithm, and luckily I had enough loyal fans through Twitter, Reddit, Youtube and Discord to make that happen. Launch went very well and I stayed on the new and trending page for a week. If I had just launched there, it would have been buried with all the other apps and I would be writing a very different postmortem. So please don't just release on steam, have fans or a marketing plan first! you need a certain number of sales before the algorithm decides you are worthy of the front page. Lesson 7: Keep updating even on steam I often hear that after launch day sales will drastically slow down, but I have been updating every few weeks and sales are still going great. Keep your users happy and they will keep recommending your game. Lesson 8: Localize I noticed strong sales happening in China and Japan, so I added a simple localization that I got translated on fiver for 50 bucks to the UI and that has helped with sales over there tremendously. I have a girl now that I pay 100 a week to look after the social media over there and answer questions for the users and that has been a great help. Lesson 9: Pirates can be your friends When I was on itch I noticed pirated copies being sold and sales numbers increased when that happened, I posted about that on r/gamedev before and the same happened a few days later after the steam launch. This time I decided to post on one of the pirate sites and the responses were great. While I don't know how many pirates I converted, there were plenty of good reasons given as to why they pirated, and I often get users tell me that they initially pirated my game but eventually bought it to support. My personal conclusion is that piracy is not a lost sale, but actually help sales. There you go that's my 9 lessons learnt, so far I have sold 10k units on itch and 25k units on steam with both platforms still selling way better every week than any 9 to 5 job in the VFX industry I no longer work in. I will probably keep updating and then eventually start on a new thing or finish one of my many many prototypes lol Hopefully, this will help you with your game. Got any questions? Fire away! --- Check out FlowScape on itch.io or on Steam. This article was originally published on Reddit and is reproduced here with the kind permission of the author.
  2. Last month Survios (the studio behind Raw Data and Creed: Rise to Glory) released the naval combat VR game, Battlewake on PlayStation VR, SteamVR, Oculus Home and Viveport. Since the early summer announcement fans have been anticipating the title, and after reading a lot of the reviews Survios did not disappoint. Battlewake turns players into “super-powered pirate lords embarking on a larger-than-life nautical war for the ages”. Players control an upgradeable warship armed with a collection of thirteen different ship-based weapons inspired by real and imagined naval battles including flak cannons, ballistae, and axe throwers. Each of the four playable pirate lords also has their own ancient magic to drawn from to unleash special and ultimate attacks like tsunamis, maelstroms, and kraken. The game’s score by composer Jeremy Nathan Tisser is also worth mentioning, as it does a great job of heightening the player’s high seas experience. In the below exclusive interview, Nathan discusses his process for scoring the game. A lot of reviewers are saying the multiplayer version of Battlewake is where the game really shines. How does the score change when there are multiple players? I would say the biggest difference between multiplayer and story mode is interactivity. When you’re playing in story mode, you want the story to grow and evolve with the player. Whereas in a multiplayer setting, you’re basically just battling it out with a bunch of different people, so the music doesn’t need to shift or evolve quite as much. What was your inspiration for the Battlewake score? I pulled inspiration from a myriad of different musical stylings and culture. Primarily, however, I drew on my backgrounds in heavy metal as well as traditional orchestration. We wanted a big “larger than life” style orchestral score, like you’d get in a pirate film, but we wanted it to be exciting and unique. We decided that a heavy metal twist on an orchestral pirate score was the right vibe for the game. We also looked at different cultures from around the world, and how they interpret music, be it through instrumentation, through rhythm, etc. So we used a wide variety of ethnic percussion instruments, including the African talking drum, Japanese taikos, Djun Djun, congas, various shakers, and much more. We also hired an anthropologist, with whom I also study Kung Fu, to act as a cultural consultant. We wanted to add an element that portrays some of the Voodoo cultures of Haiti. As it turns out, there’s almost no written information on the Voodoo and Vodou cultures, because to have any information in the hands of those wishing to cause harm to others could in fact be catastrophic to not just the intended target, but to innocent bystanders as well. So we found a couple of war chants that would be used for the purpose of intimidation instead, and incorporated those in the form of chants over the orchestra. Take a listen to the track “Jade and Steel” on the soundtrack when it comes out later this month! Were there any obstacles you had to overcome, musically, while working on this game? The biggest challenge of this game came down to how early I was brought in. I began writing music for Battlewake in December of 2017, when all that was available to me was a basic demo of the gameplay mechanics, a well-developed backstory, and a series of concept art for the various environments. Nothing was set in stone yet, and the storyline of the game itself was unknown. I had some ideas in my head, but it really took me about 8 more months to nail it down. The game itself had also grown and evolved, and was constantly changing form throughout that time, and that kept changing how the music would function within the game. Is there a type of game you haven’t scored yet that you would like to? I would honestly love to score a Star Trek game or a Doctor Who game. Or perhaps even a World War 2 style game. Something where I can get a little more nostalgic, and maybe write something beautiful, yet still maintain some sort of edginess to it. Personally, I just love the idea of storytelling, and I try to make that come through in my music for games as well, as opposed to just writing basic loops or standard “epic” music. There are four Pirate Lords in the game. Which was your favorite one to score? With Battlewake, I actually ended up scoring the 4 different environment types rather than the characters. The reason for this goes back to how early I was brought in. The story wasn’t set in stone just yet, but they still needed music. If you have a chance to play it, you’ll see how integral the music is to the “fun” experience of it. That being said, I absolutely loved scoring the arctic environments and the volcanic environments. I’ve been dying to write a big ol’ heavy metal polyrhythm into one of my scores, and Battlewake allowed the opportunity for me! The arctic level was more of my opportunity to write something that sort of follows a “song form”, so it feels like a track that could really be performed in a major concert environment. But it’s also just super fun to listen to and blow things up to! Do you have a favorite sequence in Battlewake? Personally, I really love when you get to release the Kraken! How many times have you watched Pirates of the Caribbean and thought “man, I’d love to get to say ‘Release the Kraken!’ in a video game…”? Well, now you can! And it is SUPER satisfying. How much music did you create for this game? Are you going to be releasing the game’s score? I wrote around 45 minutes of music or so, but it’s all layered and stemmed and divided into loops, so it can be turned into a few hours worth of music. As for the soundtrack, Notefornote Music has is putting out the soundtrack very soon! It’ll be available on all digital platforms around early-mid October, and then a few weeks later it will be available on a limited-edition CD print! There also may or may not be one additional release, so keep an eye out on my twitter page for that (@jeremytisser). Are you a gamer yourself? If so, what are some of your favorite games to play? I’m actually not much of a gamer. Growing up, I wasn’t allowed to have a Playstation or any of those like my friends, so I grew up playing games like NHL 97, Tony Hawk Pro Skater, Sonic the Hedgehog, and more on Sega Genesis, Nintendo 64, and then Gamecube. Every time I’d go to a friend’s house to play Mortal Kombat on Playstation, I’d just get whooped because they were playing every day, and I couldn’t. So I never got excited about games. However, I was ALWAYS big into VR. I used to get so fascinated by those big VR machines you’d see in the arcades, or in Las Vegas. And I always loved seeing those 3D IMAX films at the museums. When I got to graduate school in 2011 at USC, I had the opportunity to work on some really cool and advanced VR projects, so that’s what really sparked my passion. All that to say… Mike Tyson Boxing, Crazy Taxi, and Tony Hawk Pro Skater rule!
  3. Link: https://docs.imgtec.com/PBR_with_IBL_for_PVR/topics/pbr_ibl_introduction.html Excerpt: Read more at https://docs.imgtec.com/PBR_with_IBL_for_PVR/topics/pbr_ibl_introduction.html
  4. Link: https://www.imgtec.com/blog/physically-based-rendering-with-powervr-part-2/ Excerpt: Read the full article at https://www.imgtec.com/blog/physically-based-rendering-with-powervr-part-2/
  5. Sid Meier, the creator of the popular Civilization video game series, goes behind the scenes of the development of the franchise's first entry. Sid explains some of the challenges they came across while transitioning the game from real-time to turn-based strategy.
  6. This was for a Dungeon Explorer home project I was working on. When researching labyrinth, maze, or dungeon generation algorithms I found many that would create hub or tree-style dungeons, but none that would 'loop back' on themselves. I created this algorithm with the intention of designers or artists still having full control over the look and contents of rooms and corridors. As long as certain rules are followed (e.g. attachpoints are assigned to rooms and snapped to a grid, rooms have a 'footprint' object that bounds their size) rooms and corridors can be any size or shape desired. This video demonstrates the process, which is also outlined below: giphy.mp4 I did go on to make a small game using this algorithm and bar some silly behaviour (like making corridors to from a room to itself), it's worked great! A short excerpt about the algorithm, for those that might like to re-create it! Steps Randomly Place rooms within the defined area Attempt to connect all rooms together in a large 'chain' Starting with random rooms, make smaller 'chains' of rooms within the network Prune room connections from rooms that have more connections than attach points Go through all room connections and connect actual attach points Use A* pathing to create corridors between the attach points Mark all of the corridors onto the grid Actually place straight, corner, T-Junction, and crossroad corridors oriented in the correct way There's a whole bunch more complexity in each of these steps, but that's the basic breakdown! The objects you see in the gif are 3d rooms complete with art and stuff inside them, but the camera is top down and lighting set to make the gif easier to see! Each room is a prefab game object. They have their own scripts that manage the stuff contained within them, in this case flickering torches, furnaces, and other puzzles. Each room has attach points that are defined by me (in this case acting as the designer), and the dungeon generator is given a list of all rooms it should use to generate, again defined by the designer. The rooms provide information like their size, shape, available attach points etc that the generator uses to position and connect them. There are different corridor types, straight, t junction, crossroad, and corners. Each has a different setup of walls. The algorithm places them just after the steps seen in the gif, choosing which to place base on what's adjacent to each grid position and orients them. Again these are prefab game objects with other things in them (e.g. Torches). I've just used debug lines to draw out the connections for the purpose of showing it in gif format, the original version doesn't do this at all! Another example but with 200 rooms rather than 50, at increased speed: giphy2.mp4 And another 200 room demo, with no speed increase: giphy3.mp4 Note: This article was originally shared via Reddit, and is recreated here with the kind permission of the author.
  7. GameDev.net

    Building a Discord

    Discord is one of the most popular communication platforms for gamers. In this article, we'll be going over our journey of building up our community through the popular social app, Discord. We'll be discussing how to build a Discord server, the various features, and why you should even make a server in the first place, as well as the process on how we decided to build and tailor the server to fit the needs of our studio and community. For those unaware: Discord is a hugely popular communication app, especially in the gaming community. It allows users to join a server (Like ours!), and connect with other users to chat via voice and text, as well as video chat in private groups. According to Statista, Discord has over 200 Million registered users as of December 2018, and that number has surely grown in the time since. Discord has many different, unique features that help users interact with each other. Users are able to join many different types of servers at a time. They can organize these however they would like based on their own preferences. In addition, those who run servers are able to customize them however they'd like by adding various channels, bots, user roles, and more. The Benefits of Discord As mentioned before, the ever-growing popularity and vast Userbase of Discord within the gaming community makes it the perfect place for developers to bring their fans together. Discord's various methods of communication allow for developers and users to interact seamlessly and quickly with one another. A common feature in servers centered around a specific game and/or studio are channels dedicated to feedback and/or bug reporting. These channels allow users who are playing or testing a game to very quickly give feedback on what they like or not about a game, and also allows them to report bugs they encounter during gameplay. The beauty of this is that these issues tend to get reported and fixed much faster, and developers are able to communicate back to the Userbase in real-time. Another feature of Discord that is great for developers is the @everyone feature, which allows someone to notify (or "ping") everyone in the server when something important comes up. Typically with a game-oriented server, announcements include things like updates/patch note releases, beta sign up opportunities, server maintenance times, and much more. The feature is a great way to get information out to everyone in the community quickly, efficiently, and effectively. Having a community helps news about a studio's game get out faster, and is a great way to spread news about the game through word of mouth. Users can create server invites whenever they would like, simply by clicking on an invite link. As a result, inviting friends to a server is extremely simple, so users that particularly enjoy a game or even just the game's community can have their friends join and find out more about it. Similarly, the announcement and feedback features in a server can have a huge impact on the development of a game. As an example, Behavior Interactive's Deathgarden experienced a lot of negative feedback on its initial launch, much of which was communicated through their Discord server. The feedback allowed Behavior to work with the community, figure out what wasn't quite working with the game, and as of this past month, Behavior successfully relaunched the game as Deathgarden: Bloodharvest. Before the days of Discord, games were often dead in the water if they weren't well received on launch, which typically would lead to poor sales and ultimately layoffs at studios. Without a dedicated community surrounding a studio, it can be much harder to interact with users and really figure out what does and doesn't work with a game. It's more important now to build a solid community surrounding your game or studio than ever before! Join Up Over the course of this article (originally published as a series), we’ll be going on our community-building journey. This series is designed to share tips and insights to help others build up a loyal fanbase and dedicated group of followers. Learn what works - and what doesn’t work - from our experiences. If you’d like to be a bigger part of our quest, please join our server! Action Plans - Why, What, and How? An action plan is exactly what it sounds like - it’s a roadmap of the tasks you need to perform. In this case, that roadmap leads to a thriving Discord server. But why do you need an action plan? There are several reasons. First and foremost, it helps put everything in perspective. Organization is key when it comes to setting up large scale projects such as this, so it’s important to make sure your objectives are crystal clear and carefully thought out. Action plans also create a clear timetable for when tasks need to be completed, and who needs to complete them. In some cases it may be necessary to break tasks up among multiple people, depending on their specific skill set or area of expertise. For example, one member of your team may be great at finding ways to promote your game through various marketing efforts, whereas another member may excel at using the Discord app itself. Creating your action plan is also a great time for brainstorming. Your peers may have ideas that you may not have thought of. If they are valuable enough, they can be added to the action plan as tasks. An Action Plan... In Action Your action plan should include a multitude of things, namely: questions that need answers, existing implemented features that could be improved, and a table for things that need to be done, as well as who will be in charge of completing said tasks. Below is an example of how the table can be set up, listed with tasks and who is assigned with completing them. Here, we can see a list of several names: Kyle, Bobby, Nate F, and James. Each of these members have a different skillset and have thus been given tasks that pertain to them. Kyle is skilled at using the Discord app, so has been charged with tasks that specifically involve setting up the server itself. Bobby is great at things like wikis, so he has been tasked with setting up two wikis for our game. Nate is a coder, so he’s been assigned with getting Rich Presence up and running in the server. James is our marketing guy, so he’s in charge of setting up a giveaway as well as setting up any other outside marketing to get people into the server. Action plans will vary from server-to-server. A server based on a whole studio with many games will have a different action plan than a server centered around a single game, for example. In our server, we have channels set up for each of our games, and different tasks pertaining to each one. A server for a single game will have different needs, and all tasks will end up pertaining to that game. Plan To Win Having a well-thought-out action plan will greatly increase your chances of success in creating your server. Once everything is clearly laid out and planned, it will give you and other members of your team a much clearer perspective on what needs to be done, and who needs to complete the tasks. Although an action plan is vital to making sure everything that’s necessary for setting up your server is completed, it’s just the beginning - the first piece in an otherwise much larger project. Think of your action plan as the box of a jigsaw puzzle, whereas setting up your server is the jigsaw puzzle itself. The box shows you exactly what it’s supposed to look like in the end, but it’s still up to you and your team to put the pieces together to complete the puzzle. Without the box, you have no idea what your puzzle is supposed to look like, and it’s only after you’ve begun putting it together that you’re able to figure out whether or not you’re missing any pieces. Hopefully, in the end, your puzzle will match the box. Steps for Styling It’s the little details and extra effort that will make your server appear more professional. This is especially important if you are running your server for a game or studio. Appearing unprofessional gives the impression that the studio doesn’t care, about their game or their community. Beyond improving presentation, polishing the server can also make it more eye-catching. Polishing your server involves multiple steps, but the end result should be that your server appears more organized, visually appealing, and functional: Step 1: Get Organized Before you begin polishing, take a step back and make sure everything is ready to go. Do you have the necessary channels? Do you have your user roles set up? Have you written out the rules and FAQ and given them a channel (or channels, if you split them)? If not, make sure you have that down before you worry about polishing. Step 2: Add Custom Emojis One thing you can do to add some flair to your server is adding emojis to channel names or even the category names. This isn’t necessary, and you may or may not like the look, but it’s certainly an option. We don’t use them in our server, but that’s simply a matter of preference. Plenty of servers use them to good effect. Step 3: Personalize The Artwork Another common way to add a personal, custom touch to your server is adding custom artwork themed to the game or studio to post rules and FAQ. This will help users actually see and (hopefully) read them. People respond much better to visuals, so if you have some nice looking graphics, people will be more inclined to engage with them. Step 4: Color Code Your Server One more thing you can do for adding some more visual appeal and organization is to color code the various roles in your server. Discord allows server admins to organize and color code the different roles, as well as have each role separated by the role hierarchy (roles are organized from top to bottom based on your list of roles in your server). This not only adds some color and personality to your server, but it gives users an immediate visual cue as to who’s who in the community. If you make all of your Mods or Staff blue, for example, community members immediately know that when they see a blue name, they are a mod. Not only does color coding look better and more organized, but it creates an important distinction between users. If everyone in the server has the same white color, users don’t know if they’re speaking to the server owner or some other random member of the community. Do It For The Fans Taking the time to make sure your server is looking and functioning well is one of the biggest differences between Discord amateurs and veterans. Having everything in its proper place, keeping it all organized, and color coding improves the visual appeal and enhances the server’s organization. It’s perfectly possible to run a server without going through all of these steps, but taking that extra step shows that you care about your server, your product, and most importantly, your community. Attack of The Bots So, what exactly are “Bots”? Aren’t they those things that people use in RuneScape to level up automatically? Well, yes, but not in this case. In terms of Discord, a Bot is a sort of plugin you can use for your server to perform many different functions that a normal user cannot (at least not easily). They are typically maintained and deployed through user commands or pre-set through a configuration page. Bots can be programmed to do almost anything on Discord, and as such, there are many, many different bots that all do different things. For example, bots can do things like keep track of user stats/metrics, award points based on activity in a server (or even a specific channel), hand out user roles, play music through a voice channel, auto-moderate your chat, and so much more. In fact, there are bots for almost any purpose and function. To avoid overload, the first thing you should do is narrow down which bots you should consider using in your server. A Robot Army Now that you have at least a vague understanding of what Bots are, here are some that are particularly useful across most types of servers: MEE6 MEE6 (yes, it is a reference to Mr. Meeseeks from Adult Swim’s Rick & Morty) is probably the most popular Discord bot. You’ll find it on many different servers, mostly because of its multipurpose nature and ease of use. It doesn’t require any commands to use (though you can set them up if you’d like), and it can do a multitude of different things, all of which it does very well. It can moderate your server through word filters, notify you when users go live on Twitch or upload a YouTube video, post messages on a timer, and award points based on user activity across the whole server, or in specific channels. There is a caveat, however. Certain features of MEE6 (and parts of some of the free ones) are only available if you purchase MEE6 Premium, the most significant being the previously free Role Reward feature. It can be pretty pricey, but depending on your budget and how badly you want to use the features, it can be worth it. ARCANE A MEE6 alternative that will level up users and award roles for free. Arcane’s description actually takes a bit of a jab at MEE6, saying “We will never charge a dime for our core features, ever. Levels with rewards, auto moderation, music. Dyno, Rythm, and MEE6 combined!” But seriously, if you’re looking for a Level and Role Reward bot but don’t feel like shelling out for MEE6 Premium, Arcane may be the bot you’re looking for. NIGHTBOT If you’re at all familiar with Twitch.tv, you’ve likely seen Nightbot in a few channels before. If you’re a streamer, you should definitely consider adding Nightbot to your Discord server as well. Commands are cross-compatible with the Twitch version, so users can use the same commands in both places. It also features auto-moderation, which can be handy if your server becomes quite large. CUSTOM BOTS While there are many, many different bots already out there for users to download for free, sometimes there isn’t one that can do what you’d like it to do. Maybe you have a specific need that isn’t covered by another Bot. In this case, it may be worth it to create your own (or hire someone to make it for you). For example, The Messenger Discord server (discord.gg/themessenger) has a couple of unique custom bots, one of which is the Clockwork Concierge, which awards Time Shards upon people “joining the #dojo”. If you have a specific need or theme to your server, a custom bot may be the way to go. The Tip of The Botberg There are many other types of bots, like economy bots, team-finding bots like Guilded, and music bots like Rythm. Rest assured, there are plenty of options for you to tailor your server to your needs. They can add a ton of personality and functionality to a server, which can play a big part in getting users to stick around longer and stay active… Speaking of which, that’s exactly what we’ll be covering in the finale of Building A Discord. Check out and follow our blog, and stay tuned for our final blog in which we’ll talk about how to get people into your server, and more importantly, how to get them to be active and stay in your server. If you enjoyed this article, check out our website, our blog where you'll find more great articles, or join our Discord. Note: This article was originally published as a multipart series on the Mega Cat Studios blog, and is republished here with the kind permission of the original author. Links to the original parts of the series are below. A firth part (not included above - go check it out!) will also be published covering how to build and maintain an active community. Part 1: What is Discord and why should you use it? Part 2: Creating an action plan for building and developing your server Part 3: How to add polish and flare Part 4: Adding bots to your Discord server
  8. This thread on Navigation Meshes in Sunset Overdrive was posted by Jonathan Adamczewski (@twoscomplement on Twitter). You can view the full original thread at https://twitter.com/twoscomplement/status/1119362111556083712 Navigation mesh encodes where in the game world an agent can stand, and where it can go. (here "agent" means bot, actor, enemy, NPC, etc). At runtime, the main thing navigation mesh is used for is to find paths between points using an algorithm like A* https://en.wikipedia.org/wiki/A*_search_algorithm. In Insomniac's engine, navigation mesh is made of triangles. Triangle edge midpoints define a connected graph for pathfinding purposes. In addition to triangles, we have off-mesh links ("Custom Nav Clues" in Insomniac parlance) that describe movement that isn't across the ground. These are used to represent any kind of off-mesh connection - could be jumping over a car or railing, climbing up to a rooftop, climbing down a ladder, etc. Exactly what it means for a particular type of bot is handled by clue markup and game code. These links are placed by artists and designers in the game environment, and included in prefabs for commonly used bot-traversible objects in the world, like railings and cars. Navigation mesh makes a certain operations much, much simpler than it would be if done by trying to reason about render or physics geometry. Our game work is made up of a lot of small objects, which are each typically made from many triangles. Using render or physics geometry to answer the question "can this bot stand here" hundreds of times every frame is not scalable. (Sunset Overdrive had 33ms frames. That's not a lot of time.) It's much faster to ask: is there navigation mesh where this bot is? Navigation mesh is relatively sparse and simple, so the question can be answered quickly. Also, we pre-compute bounding volumes for navmesh, to make answering that question even faster. Also, if a bot was standing on navmesh last frame, it's even less work to reason about where they are this frame. In addition to path-finding, navmesh can be useful to quickly and safely limit movement in a single direction. We sweep lines across navmesh to find boundaries to clamp bot movement. e.g. a bot animating through a somersault will have its movement through the world clamped to the edge of navmesh, rather than rolling off into who-knows-what. (If you're making a game where you want bots to be able to freely somersault in any direction, you can ignore the navmesh 😁) Building navmesh requires a complete view of the static world. The generated mesh is only correct when it accounts for all objects: interactions between objects affect the generated mesh in ways that are not easy (or fast) to reason about independently. Intersecting objects can become obstructions to movement. Or they can form new surfaces that an agent can stand upon. You can't really tell what it means to an agent until you mash it all together. To do as little work as possible at runtime, we required *all* of the static objects to be loaded at one time to pre-build mesh for Sunset City. We keep that pre-built navmesh loading during the game at all times. For the final version of the game (with both of the areas added via DLC) this required ~55MB memory. We use Recast to generate the triangle mesh, and (mostly for historical reasons) repack this into our own custom format. https://github.com/recastnavigation/recastnavigation Two meshes, one for "normal" humanoid-sized bots (2m tall, 0.5m radius) and one for "large" bots (4.5m tall, 1.35m radius). Both meshes are generated as 16x16m tiles, and use a cell size of 0.125m when rasterizing collision geometry. There were a few tools used in Sunset Overdrive to add some sense of dynamism to the static environment: For pathfinding and bot-steering, we have runtime systems to control bot movement around dynamic obstacles. Also, for custom nav clues, we keep track of whether they are in use, to make it less likely that multiple bots are jumping over the same thing at the same time. This can help fan-out groups of bots, forcing them to take distinctly different paths. Since Sunset Overdrive, we've added a dynamic obstruction system based on Detour to temporarily cut holes in navmesh for larger impermanent obstacles like stopped cars or temporary structures. Relevant tweet: We also have a way to mark-up areas of navmesh so that they could be toggled in a controlled fashion from script. It's less flexible than the dyanamic obstruction system - but it is very fast: toggling flags for tris rather than retriangulation. I spoke about Sunset Overdrive at the AI Summit a few years back - my slide deck is here: https://www.gdcvault.com/play/1022274/Sunset-City-Express-Improving-the. I can also highly recommend @AdamNoonchester's talk from GDC 2015: "AI in the Awesomepocalypse - Creating the Enemies of Sunset Overdrive". Here's some navigation mesh, using the default in-engine debug draw. What are we looking at? This is a top-down orthographic view of a location in the middle of Sunset City. The different colors indicate different islands of navigation mesh - groups of triangles that are reachable from other islands via custom nav clues. Bright sections are where sections of navmesh overlap in the X-Z plane. I literally just had a coworker looking over my shoulder ask "Is that Tron" 😁 There are multiple visualization modes for navmesh. Usually, this is displayed over some in-game geometry - it exists to debug/understand the data in game and editor. Depending on what the world looks like, some colors are easier to read than others. The second image shows the individual triangles - adjacent triangles do not reliably have different colors. And there is stable color selection as the camera moves, almost. Also, if you squint, you can make out the 16x16m tile boundaries, so you can get a sense of scale. A map of the entirety of Sunset City. (These images are being recompressed, which is reducing the detail & changing the colors - I'll upload some pngs sometime later) "The Mystery of the Mooil Rig" DLC area "Dawn of the Rise of the Fallen Machine" DLC area Referencing the comments from up-thread, these maps represent the places where agents can be. Additionally, there is connectivity information - we have visualization for that as well. This image has a few extra in-engine annotations, and some that I added. The purple lines represent custom nav clues - one line in each direction that is connected. Also marked are some railings with clues placed at regular intervals, a car with clues crisscrossing it, and moored boats with clues that allow enemies to chase the player. Also in this image (and nearly entirely lost thanks to recompression) are very faint lines on the mesh that show connectivity between triangles. When a bot is failing to navigate, it can be useful to visualize the connectivity that the mesh thinks it has. The radio tower where the fight with Fizzie takes place. The roller coaster The roller coaster tracks are one single, continuous and complete island of navmesh. That's all I've got for now - hit me up if you have any questions!
  9. There are a lot of great articles and tutorials focusing on performance in Unity. This article is not trying to replace them or improve them, this is just a summary of steps that we went through after reading these articles and the steps that helped solve our issues. I strongly recommend to go through https://learn.unity.com/ at least. During the development of our game, we ran into issues that caused an occasional lag during the gameplay. After some time spent with the Unity Profiler we found two types of issues: Unoptimised shaders Unoptimised C# scripts Most of the issues came from the second group, so I decided to focus this article on C# scripting (and maybe also because I have never written a single shader in my entire life). If you want to know more about best practices for writing your shaders just wait for an article that my colleague is about to write soon. Finding the Weak Spot The point of this article is not to give a tutorial on how to use the profiler, I just want to highlight what we focused on during the profiling. Unity Profiler is always the best way to go while trying to find the scripts causing your lag. I strongly recommend profiling the game directly on the device instead of profiling in the editor. So because our game is an iOS game I just had to connect the device and use the Build Settings shown in the picture below and the profiler was connected automatically Build Settings for profiling If you try to google “Random lag in Unity” or any other similar phrase you can find that most people recommend to focus on Garbage Collection, so I did exactly that. Garbage is generated anytime you stop using some object (instance of a class) then from time to time Unity’s Garbage collector is run to clear the mess and deallocate the memory which takes an insane amount of time causing the frame rate to drop. How to find the scripts causing garbage allocation in the profiler? Just Select CPU Usage -> Choose Hierarchy view -> Sort by GC Alloc Profiler settings for GC Your goal should be to get to all zeros in the GC alloc column in your gameplay scene. Another good point is to sort the records by “Time ms” (execution time) and optimise the scripts to take as little time as possible. This was a huge thing for us, because one of your components contains a large for-loop that took almost forever to execute (yeah we have not found a way to get rid of the loop, yet) so optimising the execution time for all the scripts was an absolute necessity for us, because we needed to save some execution time for this time-consuming for-loop while maintaining 60 fps. So based on the profiling, I split the optimisation into two parts : Getting rid of the garbage Lowering down the execution time Part 1: Fighting the Garbage This part focuses on what we did to get rid of all the garbage. These are the absolute basics that every developer should know and it also became an important part of our code review with every pull/merge request on a daily basis. 1st Rule: No New Objects in Update Methods Ideally, you should have no “new” keywords used in the Update, FixedUpdate or LateUpdate methods. You should always try to use, what you already have. Sometimes the new object creation is hidden in some Unity’s internal methods so it is not so obvious. We will discuss these later. 2nd Rule: Create Once and Reuse, Reuse and Reuse! This basically means to allocate everything you can in the Start and Awake methods. The rule is very similar to the 1st one. Actually, it’s just another way of removing “new” keywords from the Update methods. You should always try to move all code that: creates new instances, finds any game objects, out of the Update methods and move it to Start or Awake. Here are examples of changes that we did: Allocate Lists in the Start method, Clear them when needed and reuse wherever you want. //Bad code private List<GameObject> objectsList; void Update() { objectsList = new List<GameObject>(); objectsList.Add(......) } //Better Code private List<GameObject> objectsList; void Start() { objectsList = new List<GameObject>(); } void Update() { objectsList.Clear(); objectsList.Add(......) } Store references and reuse them like this: //Bad code void Update() { var levelObstacles = FindObjectsOfType<Obstacle>(); foreach(var obstacle in levelObstacles) { ....... } } //Better code private Object[] levelObstacles; void Start() { levelObstacles = FindObjectsOfType<Obstacle>(); } void Update() { foreach(var obstacle in levelObstacles) { ....... } } The same applies to FindGameObjectsWithTag method or any other method that returns a new array. 3rd Rule: Beware of Strings and Avoid String Concatenation Strings are horrible when it comes to garbage allocations. Even basic string operations can generate a lot of garbage. Why is that? Strings are just arrays and these arrays are immutable. That means whenever you try to concatenate two strings together a new array is created and the old one becomes garbage. Thankfully you can use StringBuilder to avoid or minimise this garbage allocation. Here is an example of how to improve this: //Bad code void Start() { text = GetComponent<Text>(); } void Update() { text.text = "Player " + name + " has score " + score.toString(); } //Better code void Start() { text = GetComponent<Text>(); builder = new StringBuilder(50); } void Update() { //StringBuilder has overloaded Append method for all types builder.Length = 0; builder.Append("Player "); builder.Append(name); builder.Append(" has score "); builder.Append(score); text.text = builder.ToString(); } The example shown above is ok, but there is still a lot of space to improve the code. As you can see, almost the entire string can be considered as static. So what we did is that we split the string into two parts, into two UI.Text objects. First, one containing only the static text “Player “ + name + “ has score “ which can be assigned in the Start method and the second one containing the score value which is updated every frame. Always make static strings really static and generate them in Start or Awake method. With this improvement, it is almost ok, but still, some garbage is generated by calling Int.ToString(), Float.ToString() etc. We solved this by generating and pre-allocating all possible strings. It might sound stupid and memory consuming, but it perfectly fits our needs and solve this issue completely. So we ended up with a static array that you can access directly using indices to get the required string representing the number : public static readonly string[] NUMBERS_THREE_DECIMAL = { "000", "001", "002", "003", "004", "005", "006",.......... 4th Rule: Cache Values Returned by Accessors This can be very tricky because even a simple accessor like this one generates Garbage: //Bad Code void Update() { gameObject.tag; //or gameObject.name; } Try to avoid using the accessors in the Update method. Call the Accessor only once in the Start method and cache the return value. In general, I recommend to NOT call any String accessors or Array accessors in the Update methods. In most of the cases, you only need to get the reference once in the Start method. Here are two common examples of another unoptimised accessor code: //Bad Code void Update() { //Allocates new array containing all touches Input.touches[0]; } //Better Code void Update() { Input.GetTouch(0); } //Bad Code void Update() { //Returns new string(garbage) and compare the two strings gameObject.Tag == "MyTag"; } //Better Code void Update() { gameObject.CompareTag("MyTag"); } 5th Rule: Use Non Alloc Functions For certain Unity functions, you can find their alternatives that don’t allocate anything. In our case, these functions are all related to Physics. Our collision detection is based on Physics2D. CircleCast(); For this one specifically, it is possible to find a function that does not allocate anything called Physics2D. CircleCastNonAlloc(); Many other functions have alternatives like this one, so always check the documentation for NonAlloc functions. 6th Rule: Don’t Use LINQ Just don’t. I mean don’t use it in any code that is executed often. I know the code is easier to read when using LINQ, but in many cases the performance and memory allocation of such code is horrible. Of course, it is possible to use it sometimes, but I want to keep this simple and honestly, in our game we don’t use LINQ at all. 7th Rule: Create Once and Reuse, Reuse and Reuse vol 2. This time it is about object pooling. I will not go into details of object pooling because it has been said many times, for example, check this tutorial https://learn.unity.com/tutorial/object-pooling In our case, the scenario for object pooling is this one. We have a generated level that is full of obstacles that live only for a certain period of time until a player passes this level section. These obstacles are instantiated from prefabs when certain conditions are met. The code is in the Update method. This code is absolutely inefficient considering both memory and execution time. We solved this by generating a pool of 40 obstacles and taking these obstacles from the pool when needed and returning the objects back to the pool after they are not needed anymore. 8th Rule: Look out for Boxing! Boxing generates garbage! But what is boxing? The most common occurrence of boxing is when you pass a value type (int, float, bool etc) into a function that expects a parameter of type Object. Here is an example of boxing that we needed to solve in our project: We implemented our own messaging system in the project. Every message can contain an unlimited amount of data. The data were stored in a dictionary that was defined like this Dictionary<string, object> data; And we had a setter to set values into this dictionary public Action SetAttribute(string attribute, object value) { data[attribute] = value; } The boxing here is pretty obvious. You can call the function like this SetAttribute("my_int_value", 12); So the value “12” is boxed and that generates garbage. We solved this by having separate data containers for each primitive type and the previous Object container is used only for reference types. Dictionary<string, object> data; Dictionary<string, bool> dataBool; Dictionary<string, int> dataInt; ....... and having separate setters for each data type SetBoolAttribute(string attribute, bool value) SetIntAttribute(string attribute, int value) And all these setters were implemented to call the same generic function SetAttribute<T>(ref Dictionary<string, T> dict, string attribute, T value) And the boxing is gone! To find more details check this article https://docs.microsoft.com/cs-cz/dotnet/csharp/programming-guide/types/boxing-and-unboxing 9th Rule: Loops Are Always Suspicious This is very similar to the first and second rule. Just try to remove all unnecessary code from Loops for both performance and memory allocation reasons. We try to avoid loops in Update methods in general, but when it is really needed we at least avoid any allocation in such loops. So follow again all 1–8 rules and apply this for Loops in general and not just for Update methods. 10th Rule: No Garbage in External libraries In case you find out that some of the garbage is generated by a code that you downloaded from Asset store you have multiple options how to solve this, but before doing any reverse engineering and debugging just check the Asset store again and update the library. In our case, all assets we used were still maintained by authors and they keep doing performance updates, so this solved all our issues. Keep your dependencies up to date! I would rather get rid of the library instead of keeping an unmaintained one. Part 2: Pushing the Execution Time to Its Limits Some of the rules mentioned here make barely noticeable difference if the code is not called often. In our case, we have a large Loop that is executed every frame so even these little changes made a significant difference for us. Some of these changes, when used incorrectly or in an inappropriate situation, might lead to even worse execution times. Always check the profiler after every single optimisation change in the code to be sure that it is going the desired direction. Honestly, some of these rules lead to a code that is much harder to read and sometimes even breaks coding best practices, for example, code inlining mentioned in the rules below. A lot of these rules overlap with the rules mentioned in the first part of this article. Usually, garbage allocating code performs poorly compared to non-allocating code. So I recommend going through the first part of the article before reading this one. 1st Rule: Proper Order of Execution Move your code from FixedUpdate, Update, LateUpdate methods to Start and Awake methods. I know this sounds crazy but trust me, if you dig deep into your code, you can find hundreds of lines of code that can be moved to one of the methods that are executed only once. In our case, such code was usually related to: GetComponent<> calls Calculations that actually returns same result for every frame Repeatedly instantiating same objects, usually Lists Finding some GameObjects Getting references to Transforms and using other accessors Here is a list of examples of code, that we moved from Update methods to Start methods: //There must be a good reason to keep GetComponent in Update gameObject.GetComponent<LineRenderer>(); gameObject.GetComponent<CircleCollider2D>(); //Examples of calculations returning same result every frame Mathf.FloorToInt(Screen.width / 2); var width = 2f * mainCamera.orthographicSize * mainCamera.aspect; var castRadius = circleCollider.radius * transform.lossyScale.x; var halfSize = GetComponent<SpriteRenderer>().bounds.size.x / 2f; //Finding objects var levelObstacles = FindObjectsOfType<Obstacle>(); var levelCollectibles = FindGameObjectsWithTag("COLLECTIBLE"); //References objectTransform = gameObject.transform; mainCamera = Camera.main; 2nd Rule: Run the Code Only When It Is Needed In our case, this was mostly relevant for the scripts that update UI. Here is an example of how we changed the implementation of a code that displays the current state of “collectibles” in the level. //Bad code Text text; GameState gameState; void Start() { gameState = StoreProvider.Get<GameState>(); text = GetComponent<Text>(); } void Update() { text.text = gameState.CollectedCollectibles.ToString(); } Because we only have few collectibles in each level, it does not make any sense to change the UI text every frame, so instead, we change the text only when the actual number changes. //Better code Text text; GameState gameState; int collectiblesCount; void Start() { gameState = StoreProvider.Get<GameState>(); text = GetComponent<Text>(); collectiblesCount = gameState.CollectedCollectibles; } void Update() { if(collectiblesCount != gameState.CollectedCollectibles) { //This code is ran only about 5 times each level collectiblesCount = gameState.CollectedCollectibles; text.text = collectiblesCount.ToString(); } } The code above is much better, especially if the code is more complex than just simple UI change. If you are looking for a more complex solution I recommend to implement an Observer pattern (https://en.wikipedia.org/wiki/Observer_pattern) using C#’s Events (https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/events/) Anyway, this was still not good enough for us and we wanted to implement a completely generic solution so we created a library that implements Flux (https://facebook.github.io/flux/) into Unity. This leads to a very simple solution where you have all game state stored in a “Store” object and all UI elements and other components get notified when any state is changed and they react to this change with no code needed in Update method. If you are interested in this solution, my colleague will write an article about this soon, so subscribe or follow us and stay tuned :). 3rd Rule: Loops Are Always Suspicious This is exactly the same rule as the one mentioned in the first part of this article. If you have any loop in the code iterating over a large number of elements always apply all the rules mentioned above in both parts of this article to improve the performance of the loop. 4th Rule: For over Foreach Foreach loop is so easy to write but “so complex” to execute. Foreach loop internally uses Enumerators to iterate given set of data and to return the value. This is more complex than just iterating indices in a simple For loop. So in our project whenever it was possible we changed Foreach loops to For loops like this: //Bad code foreach (GameObject obstacle in obstacles) //Better code var count = obstacles.Count; for (int i = 0; i < count; i++) { obstacles[i]; } In our case of the large for loop, this change was really significant. The simple for loop resulted in a 2 times faster code. 5th Rule: Arrays over List In our code, we found out that most of the Lists either have fixed length or we can calculate the maximum number of items. So we reimplemented these using arrays which in some cases led to even 2x faster iteration of the data. In some cases, you can not avoid using Lists or any other complex data structures. The common situation is if you need to add or remove elements often if this case it is better to use Lists. Anyway in general always use Arrays for fixed-size lists. 6th Rule: Float Operations over Vector Operations This difference is barely noticeable unless you do thousands of operations like this, which was exactly our case, so this performance increase became significant for us. We did changes like this: Vector3 pos1 = new Vector3(1,2,3); Vector3 pos2 = new Vector3(4,5,6); //Bad code var pos3 = pos1 + pos2; //Better code var pos3 = new Vector3(pos1.x + pos2.x, pos1.y + pos2.y, ......); Vector3 pos1 = new Vector3(1,2,3); //Bad code var pos2 = pos1 * 2f; //Better code var pos2 = new Vector3(pos1.x * 2f, pos1.y * 2f, ......); 7th Rule: Finding Objects Properly Always consider if you really need to use GameObject.Find() method. This method is a beast and takes an insane amount of time. You should never have such a method in any of the Update methods. We found out that most of our Find calls could be replaced by direct reference association in the Editor, which is, of course, the better way to go. //Bad Code GameObject player; void Start() { player = GameObject.Find("PLAYER"); } //Better Code //Assign the reference to the player object in editor [SerializeField] GameObject player; void Start() { } In case you can not do it like this you should at least consider using Tags and finding the object by its Tag using GameObject.FindWithTag. So in general: Direct Reference > GameObject.FindWithTag() > GameObject.Find() 8th Rule: Work Only with Relevant Objects In our case, this was significant for collision detection using RayCasts (CircleCasts etc). Instead of detecting all collisions and making the decision which ones are relevant in code, we moved our game objects to proper layers so we can calculate collisions only on relevant objects. Here is an example //Bad Code void DetectCollision() { var count = Physics2D.CircleCastNonAlloc( position, radius, direction, results, distance); for (int i = 0; i < count; i++) { var obj = results[i].collider.transform.gameObject; if(obj.CompareTag("FOO")) { ProcessCollision(results[i]); } } } //Better Code //We added all objects with tag FOO into the same layer void DetectCollision() { //8 is number of the desired layer var mask = 1 << 8; var count = Physics2D.CircleCastNonAlloc( position, radius, direction, results, distance, mask); for (int i = 0; i < count; i++) { ProcessCollision(results[i]); } } 9th Rule: Use Tags Properly There are no doubts that tags are very useful and can improve performance of your code, but keep in mind that there is only one correct way of comparing object tags! //Bad Code gameObject.Tag == "MyTag"; //Better Code gameObject.CompareTag("MyTag"); 10th Rule: Beware of Tricky Camera! It is so simple to use Camera.main, but the performance of such action is really bad. The reason is that behind each Camera.main call Unity actually does FindGameObjectsWithTag() to get the result, so we already know that it is not a good idea to call this frequently and the best way to solve this is to cache the reference in the Start or Awake method. //Bad code void Update() { Camera.main.orthographicSize //Some operation with camera } //Better Code private Camera cam; void Start() { cam = Camera.main; } void Update() { cam.orthographicSize //Some operation with camera } 11th Rule: LocalPosition over Position Use Transform.LocalPosition everywhere you can instead of Transform.Position for both getters and setters. The reason is that there are much more operations executed behind each Transform.Position call, specifically calculating the global position in case of calling a getter or calculating local position from the global one in case of calling a setter. In our case, we found out that we could use LocalPositions in 99 percents of occurrences of Transform.Position with no other changes needed to be done in the code. 12th Rule: Don’t Use LINQ Already discussed in the first part. Just don’t use it, that’s it. 13th Rule: Don’t Be Afraid to Break Best Practices (sometimes) Sometimes even a simple function call can be too expensive. In this case, you should always consider Code Inlining. What does that mean? Basically, it means you just take the code from the function and copy the code directly to the place where you wanted to use the function to avoid any additional method calls. In most of the cases, this will not make any difference because the code inlining is done automatically at compile-time, but there are certain rules by which the compiler decided whether the code will be inlined or not (for example Virtual methods are never inlined, for more details check https://docs.unity3d.com/Manual/BestPracticeUnderstandingPerformanceInUnity8.html). So just open profiler, run the game on the actual device and see if there is any space for improvement. In our case, we found a few functions that we decided to inline for better performance, especially in the large for-loop that we have in the game. Conclusion By applying the rules mentioned in the article we easily managed to get a stable 60 fps in an iOS game even on an iPhone 5S. Some of these rules might be too specific for our use case, but I still think that most of them should be in your mind while coding or doing code reviews to avoid any problems in later stages. It is always easier to continuously write code with performance aspects in mind than refactoring large chunks of the code later. --- We are Lonely Vertex, a small indie game studio located in Prague, Czech Republic. Currently getting ready to release our first game, Sine. You can subscribe for our newsletter, read our development blog posts or follow our progress on Twitter or Facebook. --- Note: This article was originally published on Medium, and is republished here with kind permission of the author.
  10. GameDev.net

    Design A Day As A Game Designer

    The fabled game designer. The man, the myth, the legend behind the game. An inspiration to young creatives who wish to one day work in the games industry. But really, what does a game designer actually do? And how do you become one? Let’s get one common misconception out of the way first: Game designers are not “idea guys”. Sure, they come up with ideas which often translate into features, but 99% of their job seeing to their realization in agonizing detail. You certainly won’t be sitting in the “idea circle” pitching “A Zombie Survival Shooter RPG” and patting yourself on the back before going home. Instead, you’ll spend three hours deciding if the cooldown of a double-jump mechanic with a height of 400/200 units, velocity of 550 units/s and stamina cost of 30 should be 2.5 or 3 seconds. And if you’re unlucky, you’ll get hate mail from angry gamers whose main you just nerfed when the patch hits. The Basics of Game Design Game designers are responsible for the rules, systems, mechanics and content of a video game. They work in teams and are often divided into specializations such as system design, level design or game balance. While I perceive game design to be more of an art than an exact science, it’s still in the domain of software development and you’ll be using standardized applications for the most part. Here are some I’ve come across: Spreadsheet of choice such as Excel or Google Sheets Documentation tool such as Word, a wiki or pen & paper Game engine such as Unreal or Unity Version control such as Git or Perforce Scripting Language such as Python or Lua An in-house level editor such as Hammer Editor or Fallout Creation Kit You’ll likely start out as an intern or junior designer in the games industry. A degree in game design or software engineering are a plus, but the quantity and quality of projects you have in your portfolio carry a much higher significance. Having coding knowledge or writing skills helps you set yourself apart from raw designers, and if you’ve shipped an actual game or app before you’re already well ahead of the competition. More on this later. Having played games and being into games should be a given – this is not a skill. The 5 Stages of Grief Game Development Video games, like any other piece of software, go through distinct phases during their development and the game designer’s job changes accordingly. Keep in mind that methodologies and philosophies differ from place to place, so even a general overview like this may not apply to every production out there. 1. PRE PRODUCTION After sitting through game pitches, meetings and shower thoughts, higher-ups will decide on the genre, budget, scope, target audience and rough release date for the next game. A small team is then tasked with creating a prototype. Your job here will be to conceptualize and actualize the core gameplay. Think taking the idea of “flying around with cars to hit a ball” or “free-for-all shooter where the map gets smaller over time” to a playable stage where you can clearly see why it is fun. This prototype highlights the core mechanics, the look and feel of the game as well its commercial viability. It should also shed some more light on the actual work required to develop the title. Most importantly though, it has to convince management. For a more detailed view on prototyping, check out this article. 2. FULL STEAM AHEAD After the prototype gets approved and funding is secured, the project will move into full production with the appropriate amount of personnel assigned to it. As alluded to previously, game design has a lot of specializations which I’ll try to break down here. SYSTEMS DESIGN Systems design refers to the conceptualization and design of entire game systems, such as the combat system in Overwatch, the crafting mechanic in Minecraft or the leveling system in World of Warcraft. You’re also responsible for documenting said system in extreme detail, so that everyone who has to work on it knows exactly what to do. This is commonly done in a Game Design Document. Systems designers also decide how their system will interact with other game systems and set the basis for what game mechanics and features can be designed around it. Due to the scope and importance of systems like this, it’s a job most often left for more senior game designers. FEATURE DESIGN Feature design refers to the design of smaller, standalone features such as a daily login bonus or guild house customization and will see you touch on a variety of features rather than a specific system like the systems designer. Feature design is usually not a comprehensive enough specialization to be a job in itself, so when you see a job listing for a “Game Designer” it often refers to feature design with the expectation that you will also do general purpose game design, like play testing and balancing for example. LEVEL DESIGN As an entry level game designer you’ll likely work on content for existing systems, such as creating a set of healing items or designing skills for a character. The most common type of content design is level design, which involves mapping out the playable area and sprinkling it with cover, obstacles and other doodads. Next up is scripting – the act of placing triggers inside the level which make it move forward. An example would be making a door open when the player is carrying a keycard and having enemies spawn when they move through it. Certain companies may refer to this as Quest or Mission design, where you will also be responsible for the writing and narrative context of the level – say a side quest in Witcher 3. GAME BALANCE Whether we specialize in it or not, we’ll all have to do this one day. Balancing a game is an iterative process and involves a lot of number crunching which is usually done via spreadsheets. Players who purchase “Big Ass Sword” as their second item have a 62% winrate in arena mode. Why is that? What ranking bracket does it affect? What do we need to tweak? Will this have unintended side-effects? Decent math skills are required for this, and you need to be able to read and correctly interpret raw data from analytics. An understanding of high level play is also important, especially if your game has a competitive scene built around it. UX DESIGN This is an aspect handled often handled by the UI designer, but you’ll be expected to do at least some basic wireframes here and there. This means sketching out the menus, buttons and user flow that the player will go through while interacting with your feature. Good systems can fall apart due to bad UX, and being able to not only spot minor annoyances but also identify solutions is a great skill to have. Images are also a lot simpler to understand than a paragraph listing technical steps, so try to make it a habit to visually represent your designs whenever possible. MONETIZATION DESIGN Designing a cool feature and thinking of how to monetize it afterwards won’t work. What you monetize, why people would spend money on it and how you avoid community backlash has to be an integral part of the design from the start. This is where the monetization designer comes in, who will conceptualize new systems and optimize existing ones alongside the designers responsible for the game’s progression system and economy. A good grasp on numbers and being able to interpret analytics is paramount, as you’ll be constantly monitoring KPIs and adjust price points, drop rates and events to further optimize the performance of your systems. You may have apprehensions about certain monetization practices, but try your best to stay on top of new trends in this field, especially if you’re going to work in the mobile games sector. GAME WRITING* While you may be able to write a few lines of dialog here and there, most games have a team of dedicated writers who own the script and work with the design leads to tie it to the game, making adjustments whenever needed. This workflow doesn’t always work out though, and can result in ludonarrative dissonance when players get slapped in the cutscene after one-shotting the final boss two seconds prior. To combat this, certain companies have started to adopt *narrative designers, which are game designers responsible for incorporating the game’s narrative directly into the gameplay. This is a highly specialized and sought after senior position requiring years of experience in both fields, so don’t expect to have this title on your resume any time soon. 3. CHASING MILESTONES Unfortunately, developers can’t just go into a cave for 3 years until the game is done. Publishers often set out milestones which the studio has to reach in order to get paid, such as “vehicle physics done” or “working player camera”. These milestones usually dictate what concretely the team should work on next, and serve as mini-deadlines within the actual deadline. Sometimes you’ll also get pulled aside to create a trailer for an event or having a playable demo ready for a convention. 4. POLISHING This is the final phase in a game’s production, and almost no new content will be added during this stage. The focus is instead shifted to removing redundant clicks in the UI, ironing out odd difficulty spikes, wrapping up the tutorial and addressing feedback from Quality Assurance. This work often continues after the game goes gold in the form of a day 1 patch, as it takes time to print, certify, and finally ship the game. The ninety-ninety rule absolutely applies to game development as well, and taking your game from good to great can be an agonizingly slow process. It’s extremely important though: When this step is skipped, you end up with a game like S.T.A.L.K.E.R. or Mount & Blade. Good games, but not very usable and thoroughly janky. 5. POST RELEASE Most games today are supported well beyond their release via DLC and balance patches. Working on a content update like this is just like working on a very small game – you’ll go through all the same steps. Live games take this a step further and often have a dedicated LiveOps team, which is responsible for keeping the game alive and profitable for as long as possible. This means planning in-game events, adding new content or nurturing the competitive scene. If you’re not on the LiveOps team and you haven’t been laid off by this point, it’s time to move on to the next title. Recommendations If you’re an aspiring game designer, here are some things that helped me out when I was in your shoes. But just like I mentioned in my previous post, these are personal anecdotes and not representative of everyone, so make sure to read up on the experience of others. HAVE A PORTFOLIO Your game design degree means jack shit. There will be hundreds more with the exact same degree wanting the exact same job. You have to stand out in another way. Finish a quality project. Give 110% when working on game projects during school. It will be what matters most when a potential employer compares you to a classmate. Finish a quality project. If you don’t have the opportunity to do student projects, make games by yourself. I started out in RPG Maker and moved up to Unreal. Board games count too. Finish a quality project. Go ham in a level editor, make a mod or write an essay deconstructing a game mechanic. You want to demonstrate a wide range of knowledge with a good amount of depth to it. Finish a quality project. Teach yourself basic coding. This will allow you to create prototypes by yourself and participate in game jams by not being a complete dead weight. Finish a quality project. Before I forget: Finish a quality project. BE COOL You have to be a strong communicator. Apart from being diplomatic, learn how to write clear, concise text that can be understood by outsiders and make it a habit to write down whatever you’re thinking about regularly. It’s good to have some ego about your designs, but you must to be able to let go. If you can’t handle the thought of having your ideas torn to shreds by a dozen other people, this job is not for you. It’s paramount that you expand your horizon to stay competitive in the games industry. You’ll likely work on different projects in different positions in your career, so read up on trends and play games you’re not normally into. You probably have strong opinions and maybe you made fun of games, companies and developers in a comment section before. Don’t do that in front of people working in the industry – you’ll burn bridges. Don’t be a “Gamer” with a capital G. GET IN TOUCH Make a portfolio website with your projects, bio, CV and an optional blog if you can write professional, insightful posts on a regular basis. You can shitpost like me once you make it in. Make a nice business card, print out multiple copies of your CV and visit some conventions. Talks are mostly useless, so spend time chatting with the HR people who likely have a recruitment booth around. Start growing your network today by setting up a LinkedIn profile and adding classmates as well as new people in the industry you come across. Having a point of contact will come in incredibly useful one day. Get in touch with actual game designers and ask for feedback about your projects and resume. We can also refer you to the proper recruiter within the company so you’re not starting your cover letter with “To whom it may concern.” I can’t speak for the internships in the states, but they’re well worth in here in Europe. It sets you apart from other graduates, counts as experience on your resume and the chances of getting a permanent job are decent. Keep your expectations in check. Getting a job as a raw designer is hard, and the chances of you getting a specialized senior position like narrative designer fresh out of school are nonexistent. AAA developers are highly organized, and you’ll likely end up working on a very specific thing in a very specific manner. Job security is decent, and the game will carry weight on your resume. Startups on the other hand are high-risk high-reward: They offer you a lot more influence on the project, pay less, tend to run out of money and often suffer from a chaotic workflow. Don’t pick up bad habits here. Closing Thoughts I hope this post was able to give you a better understanding of what a game designer does. I can only speak for myself, but game design is a highly rewarding creative experience akin to setting up a scene for a movie or writing a stage play. Plus, having shipped an actual video game does allow you to humblebrag here and there. But be prepared to work hard – this is a job a lot of people want and you have to stand out to get it. Good luck! --- Kai Wüest is a game producer currently freezing in Iceland working on a game called Starborne: Sovereign Space. Check out his blog over at kreidenwerk.com to find more articles like this and see what he's up to next. Website | LinkedIn Note: This article was originally published on the author's blog, and is reproduced here with kind permission.
  11. Presented by Amazon GameLift Adding online options to your game used to require serious investment in additional staff, development time and hardware resources. Not any more. Amazon GameLift offers a plug-and-play solution that goes far beyond simply connecting players together. Here are five compelling reasons why you should be using it to solve all your multiplayer problems. 1. It’s easy to set up You don’t need your own expensive network specialists and infrastructure to add multiplayer to your project using GameLift. Designed to be simple to implement, and flexible enough to meet the needs of everyone from the budding hobbyist game designer to a professional studio, if your server runs on Windows or Linux then GameLift requires only a little preparation, and the incorporation of the GameLift SDK into your game server, to get you up and running. If you thought that adding online functionality would add weeks or months to your schedule, think again: adding GameLift can be no more troublesome than a day’s work. 2. You make the rules With many off-the-peg software solutions, you can find yourself limited to the same basic options as everyone else, and that can be a killer when it comes to online gaming, where developers - and players - like to be able to decide who gets matched and how. GameLift FlexMatch makes it easy to match players based on your own custom rulesets. Whether it’s including party play functions, or balancing the search for good player matches against the need to get players into the action quickly, it’s always up to you to decide what works best for your game and your community. There are lots of code samples in the Amazon developer guide that you use to get started right away. 3. No more scaling worries Everyone dreams of their game becoming an overnight sensation, but that scenario can also quickly become a nightmare if you don’t have server capacity. Nothing kills the viral buzz faster than awkard “server full” messages. With GameLift, you won’t have to worry about that. GameLift can host your custom Windows or Linux game server, or you can create a server using AWS's own Node.js based server technology. Both will automatically scale to your needs depending on server load, so when you do get a sudden influx of eager newcomers you’ll automatically have the capacity to seamlessly accommodate them all, and during quieter periods unused server instances are terminated to reduce load. Not only does this mean players are never left waiting to join a game, it means you never waste money paying for server capacity that isn’t being used. Your Amazon Gamelift dashboard lets you see exactly where your peaks and troughs are and lets you update your auto-scaling settings on the fly, using simple if-then statements to tell the system when to scale up and scale down, and defining minimum and maximum server thresholds that meet your precise needs. It also offers game session protection, ensuring that an automated server scaledown doesn’t terminate active game sessions. 4. Servers wherever your players are In today’s global gaming marketplace, it can be hard to predict where your customers will come from. You may find your game is unusually popular in Korea, India, Norway, or anywhere else in the world. With a server-based experience, that can cause serious latency problems if your servers are all located in one place. Using Amazon Gamelift eliminates this problem at a stroke, as Amazon has many thousands of servers around the world, all of which GameLift can benefit from. So whether someone is joining your game from Ohio or Tokyo, your players will always be hosted on the servers closest to them, making lag a thing of the past. 5. GameLift does all the hard work for you GameLift manages every aspect of online gaming on your behalf, according to your preferences, so you can concentrate on the creative challenge of adding content and improving the game rather than obsessing over live server data. Getting online modes implemented in a game is only the beginning of the process, so GameLift doesn’t just make the start of the process easier. GameLift’s reactive nature means that it not only handles matchmaking on a session-by-session basis, it provisions new servers when needed during peak play and consolidates the server load during quiet periods, constantly balancing player load for the best performance and monitoring server health to get ahead of any potential issues. It’s quick to set up, easy to maintain and designed to eliminate waste in development time, server load and cost. There’s an entire online developer’s guide full of step-by-step examples and sample code that you can use to get started, and even a free tier that will let you try out GameLift before making a commitment. Learn more at https://aws.amazon.com/gamelift/.
  12. This is a blog about our development of Unexplored 2: The Wayfarer's Legacy. This game features state-of-the-art content generation, generative storytelling, emergent gameplay, adaptive music, and a vibrant art style. Part 1 Unexplored 2 is a roguelite action adventure game where the hero is tasked to travel the world in order to destroy a magic staff. It features perma-death, but when your hero dies you get a chance to keep the world, so you can uncover its many secrets over the course of several runs. In a way, the world is one of the most important and persistent characters in the game. In this article, I'd like to share how we generate it. There are several ways in which you can approach world generation for fantasy games. For example, you can use simulation techniques to generate a realistic topography and populate the world from there. Instead, we choose a different approach for Unexplored 2: we used a process where we sketch a rough outline first and try to fill in the map with in a way that optimizes the affordances and gameplay opportunities the map has to offer. Rough Outline It all starts with a random Voronoi graph with 80 cells placed on a map with a 3:2 aspect ratio: Figure 1 - The initial Voronoi We use a Voronoi because it has a fairly natural distribution of cells and because the structure can be treated as a graph with each cell being an individual node and each edge a connection between nodes. This is useful as we use graph grammar rules to generate the map. In the first step, the cells on the western edge are set to ocean. Then we grow the ocean a little creating a more interesting coastline, and set the remaining cells to be land mass. A starting location is picked along the coast and a goal location is picked somewhere on the eastern side. Each cell in the graph marked with its distance to the start and the distance to the goal. Distance in this case is measured in the number of cells between two locations. Figure 2 - Land and Sea Obviously placing the ocean always on the west is just a choice (Tolkien made us do it). It is easy to make the whole map an island or have the ocean cover other edges of the map. What matters for us, is that this creates a consistently large playing area. But we don't rule out adding other templates and variations in the future. The next step is to make sure that the journey will not be too easy. After all, 'one does not simply walk into Mordor'. The way we achieve is also lifted directly from The Lord of the Rings: we simply make sure there is a mountain range between the start and the goal: Figure 3 - A Tolkienesque mountain range The mountains are started somewhere close to the goal and then allowed to grow using the following graph grammar rule, which basically changes one open cell into a mountain for an open cell that is next to one (but no more) mountain cell, relatively close to the goal, and relatively far from the starting location: Figure 4 - Graph grammar rule to grow the initial mountain range Unexplored 2 has a journey from the start location to the goal. In order to tempt the player to divert from the most direct route and explore the rest of the map a number of 'adventure sites' are placed at some distance of the start and goal location. Creating a nice spread of potential interesting travel destinations. Each site is placed inside a region of a different type. In this case, the goal is placed in swamp (s), a haven (green h) is placed in a hill area close to the start, and other sites are placed in a desert (d), forest (f), and a barren area (b). Orange edges indicate the borders between the regions. Figure 5 - Adventure sites Adding Topography The remaining cells are randomly grouped into additional regions until every cell is assigned a region on the map. The terrain types for these regions are left undetermined for now. Figure 6 - Regions and rivers Next rivers are added to the map. Initially, rivers are allowed to grow along the borders of regions. Unlike a realistic world generation process, we choose to start growing rivers at the ocean, selecting a new edge to grow into at random, favoring to grow alongside mountains as the go along. Figure 7 - Graph grammar rule that changes a region border next to an ocean into a river After rivers have been added, the region types are filled in and reevaluated. In this case, more forests are added and the desert area in the south is changed into a plain because it was next to the ocean and far to the south (our map is located in the southern hemisphere, hence the south is cold). At a later stage, we might take the opportunity to change the desert into something more interesting, such as a frozen waste. Figure 8 - Complete topography Once the regions are set, rivers are allowed to grow a little more, especially through terrains like hills and swaps. Depending on their length rivers be narrow, wide, or very wide. Only narrow rivers are easy to cross, for the wider rivers certain edges are marked to indicate points where the river can be crossed. Figure 9 - Graph grammar rule to grow a river through a swamp Adding Opportunities The topography is fairly basics and we still need to fill in a lot of details. From a design perspective regions (not cells) are the best unit to work with in this respect as we want regions to form coherent units in the experience of the game. To make working with regions a little bit easier, the Voronoi graph is reduced to a graph representation where all cells of each region are combined into one single node. Based on the relative distance to the start and the goal regions are assigned a difficulty and a number of opportunities and dangers are generated accordingly. Figure 10 - Region graph At this stage, the generator starts to look for interesting gameplay opportunities. Using several graph grammar rules a large forest with high difficulty will be assigned different attributes than a small, low difficulty swamp harboring an adventure site. At this stage, special terrains, such as purple 'obscuri' forests or red sand desert are also added to the mix. When generating the game in the world we have the option to request certain special features such as special rare terrain, or special quest content. These are processed first. To the best of the generator's ability, it might be that no good fit is found, at which point either we need to generate a new or continue without the requested feature. One interesting effect is that if certain special terrains require slightly rare conditions to emerge then the terrain type automatically becomes rare content. For example, a special quest might require a large swamp area with a river which will not be present in every world. The downside is that sometimes rarity becomes hard to control or design as there literally is no simple slider to push up if we want to make such a terrain type or quest more frequent. Creating Visuals Figure 11 - The map as it appears in the game Up until this point, the map is all data. The next step is to create the visual representation based on the map. To this end, we generated a new Voronoi diagram with a higher resolution (about 1200 cells) and map each smaller cell to the cells of the original map data. This creates a better resolution of details. Figure 10 shows how to original cells map to the visual map: Figure 12 - Original cells projected onto the map Individual cells can be raised and lowered to create elevation, and colored and decorated to suggest different terrains. Some of these decorations are assets such as trees which can vary in size and density based on the relative temperature and humidity of each cell. For now, we're using a very simple algorithm to approximate individual climate using longitude, latitude (it gets dryer towards the east), elevation and closeness to water. Other decorations are build from simple geometry based on the high-resolution Voronoi graph. This can be easily seen in image 13 below. This geometry includes slightly sloped mountain peaks, elevated patchwork to create the impression of a broken, barren landscape, and sunken centers to create pools. Figure 13 - Map detail showing how decorations use geometry based on the Voronoi graph Regions and their associated terrain types play an important role in the generation of these details. As can be observed in the figure above, forest rise towards their center, as do hills and mountains. Rivers are never elevated (to save us the trouble of trying to do so consistently). Terrain is blended a little so that height difference are not too pronounced where not intended, and interesting borders are created. In many cases, these blended terrains offer ample opportunities to liven op de map with rare features. Setting Up Nodes The world is of Unexplored 2 is not a continuous world. Players travel from node to node and can choose (or are forced) to explore gameplay areas each node represents. Connection between nodes determines where the player can travel. To place the nodes on the map we use to original low-resolution Voronoi diagram. A node is placed on each cell and on each border between cells, as can be witnessed in the image below: Figure 14 - Network of nodes placed on the Voronoi graph Certain connections are special. As mentioned above wide rivers can only be crossed at certain points, and mountains also create barriers. For uncrossable rivers the node that would have been placed on the river is split in two and each node is moved away from the river a little. Where a crossing is needed the node is actually split in three so that a bridge node is created that conveniently only has two connections (and exits) on each side of the river. For mountains and passes across mountains something similar is done. Figure 15 - Detail of the node network showing rivers and mountains Some of the nodes are already marked out as special sites in the generated data. The area templates associated with these sites often indicate special features to appear on the map (for example a volcano, a village, a mud pool, or a group of trees). Although, in some cases these features are only added after the player has visited the area and found its secrets. All other nodes are assigned templates based on the region they belong to and their relative position within that region. Each region has a number of types of locations. Typically a region has one 'heart' location assigned to a node quite central in the region, or a 'smallHeart' location if the region is relatively small. A number of 'rare' locations are scattered out across the locations not on the region's edge, and finally, all other locations are drawn from a random destination table associated with the region's terrain. Figure 16 shows sample entries from the table we use to populate forest and plain regions (the 'locations' in this table are the random encounter location the game uses when travelling between each node). Figure 16 - Random destination table Wrapping Up At the moment of writing the map generation is still a work in progress. We are constantly adding details as the game's content keeps growing. But I don't expect the general approach to change much. We are quite happy with the results, as in our humble opinion the maps are quite beautiful. But what's more important, they are readable: players can predict where barriers and dangerous terrains are to be found. A lot of information is there and we don't hide it behind a fog of war. The map facilitates anticipation and foreshadowing which are two key gameplay design features. We hope that when the game is released in full, players will enjoy simply pouring over the map and plan their journey. If you are interested in learning more about the game please check us out on Fig.co or on Steam. Note: This article was originally published on the Ludomotion website, and is reproduced here with the kind permission of the author.
  13. This is a blog about our development of Unexplored 2: The Wayfarer's Legacy. This game features state-of-the-art content generation, generative storytelling, emergent gameplay, adaptive music, and a vibrant art style. The content generator of Unexplored 2 generates tile maps. Typical output looks like this (you can read more about our level generator here😞 These tile maps are stacked, using different tiles to indicate tiles ground types (grass or dirt in this example) and various decorations. In this case there are some bushes (large green circles), Rocks (black circles), plants (small green circles), flowers (white circles), and decorative textures (grey squares). There also are special tiles that indicate gameplay data such as the spawning point marked with an 's'. In addition, tiles can be tagged with additional information such as elevation or special subtypes. Tile maps are a convenient data structure for generators to work with. But they also are quite rigid, and often the grid has a tendency to be visible in game. Yet, in our case when the data is loaded into the game and assets are placed the result looks like this: I like to think we did a pretty good job at hiding the tiles, and here's how we did it. Voronoi Magic The trick is that individual tiles are matched to the cells in a Voronoi diagram. Which can be used to generate shapes that are much more natural looking. A Voronoi diagram is created from seeding a plane with random points and partitioning off cells so that each point in the plane belongs to the cell that corresponds to the closest seed point. There are quite a few interesting applications of Voronoi diagrams for procedural content generation (PCG). A typical Voronoi diagram created from a random but fairly even distribution of seed points looks something like this: For Unexplored 2 we use a different type of distribution of seed points. To start with, we seed one point for each tile. That way we are certain every tile in the tilemap can be mapped to one cell in the Voronoi diagram. Now, if you place the seed points in the middle of each cell you end up with straight grid that looks exactly like a tile map (for this image and the others below I also made a checkered version where half of the tiles are rendered yellow so you can see the patterns a little bit better): A simple way of making this look better is to simply randomize the position of each seed point. When shifting the points it helps to make sure the point does not move outside its original tile. The result looks something like this: Better, but very noisy, and you don't get nice flowing lines in this way. It can be improved by 'relaxing' the Voronoi diagram (a standard technique associated with Voronoi diagrams I won't go into here). But it will always stay a little noisy, and it is difficult to effectively suggest shapes on a scale that surpasses the scale of the individual tiles. To get around this you need to do is to move the points around smarter than simply using random displacement. Different types of movement have very different effects. For example, using Perlin noise can create interesting curved tilemaps. Or you can turn the whole thing into hexagonal shaped tiles simply by moving every other row of seed points to the left: The real breakthrough comes when we start moving around the seed points in particular patterns to create rounded corners. The first step of this process is already taken inside the level generator. Corners are detected between ground types and the corner tiles are marked with different shapes, indicating how they should be deformed to generate a better-looking environment: In this case, elevation differences also cause corners to appear in the tilemap. That's the reason you see the extra rounded corners in the grass in the top right and bottom left where slopes were generated. The game uses this information to displace the seed points of the Voronoi graph. Each rounded corner shifts the location of the seed point (see image below). In addition, it also shifts the seed points of its four orthogonal neighbors. This process is cumulative; seed points can be shifted multiple times if they are near several corners. However, after all displacement are processed, the seed points are randomized a little (about 10% of the width of a tile in either direction), and the final displacement is restricted to a maximum of 40% of the width of a tile. The result is already pretty astonishing: But we're not there yet... Smart Decoration The overall shape is better, but the edges are still very straight and somewhat ragged in appearance. The way we cover that up is by using curved assets placed along the edges where the colors are different. The real trick, however, is that one curve is often placed over two edges, using their relative angles to determine the direction of the curve. The result looks like this: Next, we use 3D assets to give extra texture to the cliffs: And finally, we add the other assets to fill out the level. The placement of these assets is dictated by the level data generated earlier, and in general follows a simple philosophy. We use smaller assets to surround larger ones creating natural and nice transitions. Of particular note is the rocks added to the bottom of cliffs to create more variety and to visually dampen the vertical slopes dictated by the gameplay: Local Variation The corners are not the only type of displacement we use. For example, near artificial structures (such as the ruined walls below) you want the edges to be straighter: In our system, this effect is easy to achieve. We simply introduce a different displacement rule that makes sure that tiles featuring artificial structures are not displaced. The generator uses smaller squares to mark these tiles and the game simply makes sure that all displacements are ignored: If you look at the ground you can clearly see how specific areas can be made straight while others curve more naturally: Isn't that neat? There are a few other rules you can use easily mix in with this technique. For example, we occasionally force the tiles into a hexagonal pattern to make sure narrow paths are wide enough to be traversed. And I am sure we will find other uses for other patterns as well. This is one of the many reasons I really love Voronoi diagrams. Another time I will write about how we use them to generate and decorate Unexplored 2 world maps. If you are interested in learning more about the game please check us out on Fig.co or on Steam. Note: This article was originally published on the Ludomotion website, and is reproduced here with the kind permission of the author.
  14. Intro Hey there, fellow indie game dev. Let’s cut to the chase: you’ve got a game that you've either just started working on, or maybe it’s already late in production and you need to start building its home on Steam, or maybe your page already exists but it could use some improvement. Whatever the case, you want your Steam page to be as efficient as possible, bringing in good traffic and converting it into wishlists and ultimately sales. I’m going to try and use what experience I’ve gained so far to help you do that. You can either read the disclaimer or jump straight into the thick of it below. Disclaimer First off, this is a long, loooong post. Don’t say I didn’t warn you. Everything I’m going to share falls into either a) common knowledge that is readily available but a hassle to put together from different sources, b) my personal confirmed experiences and experiences other devs have shared with me, or c) some personal speculations. Please keep this in mind, and don’t treat this post as a foolproof guide to surefire success on Steam. I have not released anything on Valve’s platform yet; my game has had a successful Kickstarter three years ago, I’m gearing up for a release soon, I’m currently at ~8500 wishlists, and I’ve learned a lot by both stumbling into good ideas and fucking up majorly. If I am wrong about anything, please correct me in a comment. Throughout this article, I will use my own game as an example, mainly because it was my vehicle to experiment and try to better understand Steam. The intention is to bring everything I’ve learned together in one convenient place, and make optimizing your Steam page easier for you than it was for me. Quick terminology index Wishlist (addition) - A number that goes up when some poor unsuspecting soul likes your game and throws it onto his “I want to play this later but probably never will” pile of shame; Visit - An unfortunate Steam user has actually landed on your page; Impression - Someone has seen a capsule (a visual asset) of your game on Steam. What you want is to convert these rare, Yeti-like sightings into visits (and, ideally, wishlists & sales);CTR (Click-through rate) - The percentage of impressions that actually end up in visits to your page. It’s important, but wishlist additions are way more important. Existential dread - What your life turns into from the moment you become hooked on checking Steam traffic and wishlist stats daily. 1. When do I launch my Steam page? Short answer: As early as fucking possible. Long answer: Still as early as fucking possible, but with a caveat that I’ll touch on below. You probably already know this, but - prior to actually releasing your game and becoming an internationally adored indie superstar - your main goal in life on Steam will be to accumulate wishlist additions (simply called wishlists from here on out for convenience). That’s what you should care about most, and focus all your efforts on. It therefore stands to reason that the longer before launch your page is up, the more wishlists it can accumulate. One year is not too long. I’ve had mine online since August 2018 and we were late as hell because of bureaucratic issues. Now for the caveat I was mentioning: don’t launch your page unless you are sure that you have the best video & visual assets and text descriptions you and your team can come up with. Your first day on Steam is bound to net you a lot of exposure and wishlists - significantly more than most days afterwards. Steam’s elusive algorithm will also start judging your game based on how it performs in this first critical day, so please take it very seriously. Please do not launch your Steam page without a trailer! This will make your game look bad, or as a low-effort move on your part at the very least. We’ll dive deeper into trailers below. This is our first day on Steam in terms of wishlist additions: Your first day on Steam is crucial wishlist-wise We did have a trailer, screenshots, and decent copy. Major fuck-up: no tags (more on their importance below). It could have gone a lot better. Also, already having a community that you can bring in and positively influence the numbers day one will help. A lot. If you do, make sure you let them know in advance when your page launches, and remind them that very day via social media. Just like on Kickstarter, it’s best to have that moment zero critical mass for a snowball-type effect. Always use “wishlist now” as a call to action basically every time you show your game in public: "Wishlist on Steam" is now your mantra Tl;dr: Bring your Steam page live ASAP but only once you have the best trailer, screenshots and text possible, and ideally with a community boost to boot. A quick aside about your game title: in case you haven’t yet named it, keep in mind that certain words fare better than others in Steam searches. I’m not saying name your game “Souls Battle Royale Roguelike Simulator 2021”, but it’s something to keep in mind. My game is called Gibbous: A Cthulhu Adventure. I have indeed intentionally chosen a title that the average mortal would have a 0.008% chance of spelling correctly on their first try, BUT it also has both “adventure” and “Cthulhu” in there, which (at least for the time) count towards nice “search suggestions” impressions on Steam. This means that once you start typing either “adventure” or “Cthulhu” in the search bar, my game pops up: Search suggestions can get a lot of eyeballs on your baby Yes, “Gibbous” is hard to spell and remember and nobody knows what the hell it even means, but on the other hand, good luck finding a specific game with “heroes” in its title by wading through Steam search results. It’s a trade-off, choose carefully. Alright, let’s start actually breaking down the Steam page. 2. The Trailer As I’ve said above, don’t launch your page without one. There are great articles out there about how to approach trailers; I will not go super deep into it, you’re better off reading posts like this one by people who actually know their stuff. I’ll just touch on some do-s and don't-s, and some generalities. DO Show off your best gameplay footage up front (it can also be a cutscene if it’s relevant or it helps set the scene). If you plug Google Analytics into your Steam page (more on that below), you’ll notice a lot of users spend no more than half a minute on your page before moving on, and they’re probably checking out your trailer. Try and hook the viewer within the first moments of the trailer, don't faff about Unless you sink your hook into them within those precious seconds, they’re off to the next 50th game released on Steam that day. If your game has both a story and voice acting, make sure that the lines you use in your trailer help set up the premise without spoiling too much. Choose wisely, and choose hard-hitting stuff that summarizes the plot or drives atmosphere. Look up free trailer SFX packs on the internet if “epic” is what you’re after. I like this one, but there are probably a bunch out there. There’s also freesound.org that only requires free registration, but keep in mind you will have to credit attributions in the description. I would not advise using royalty-free music in your trailer, unless you don’t have original music in your game. Whatever is unique or representative about your game - put that stuff up front and highlight it hard. They’re called hooks for a reason; please read Ryan Clark’s excellent post about what constitutes a hook and why they should be on your mind constantly when designing your game. And your trailer. If you can think of anything visually or audio-wise that can set your trailer apart and add a bit of wow factor, it would be great. In our case, I used parallax-scrolling 2D layers on my characters to give them a neat 3D effects (reddit post about it here). If the genre and tone permits, and you think you can pull it off, funny helps. Humor is great at retaining people’s attention. Check these trailers out to see what I mean. Again, only do this if people other than your spouse and that one coworker whose promotion depends on you have told you that you are, indeed, a funny guy. Watch a lot of indie game trailers. DONT Don’t start your trailer with a logo (or, God forbid, multiple logos) unless you are a well-known studio, or it’s two seconds tops. I know you spent entire days making it look amazing in After Fx, but gamers don’t care about anything but the game. You have a few precious seconds to make them stay and watch, please don’t let your ego squander them. Don’t go above 2 minutes unless absolutely necessary. Most trailers are about a minute and a half long, and it seems that they’re lately trending towards a minute. We’re all easily distracted idiots - plan accordingly. Not really a “Don’t”, but be very careful if you choose to go for the “epic trailer” feel. If you mess up the mood, or your visuals are (unintentionally) clashing with the bombastic music and sfx, it might have the opposite effect of what you were intending. If you’re unsure, just show it to someone who you know will not spare your feelings (actually, do this, period). Don’t rely on feedback from friends and family. They love you, but they’re liars. Filthy, filthy liars. If your game revolves around a strong narrative structure, don’t do what most movie trailers tend to lately and just give the entire story away. Jesus Christ, what the hell, people! Trailer generalities Depending on the genre, it’s sometimes a good idea to think of your trailer as an entire story told in a minute, a minute and a half (again, not giving everything away! Just teasing its high notes). Ideally, it should have an intriguing hook up front, a meaty middle part that shows it off efficiently, and a crescendo to a high point and / or a denouement. Read about the peak-end rule and think about how to efficiently apply it to your trailer (and your game). Keep in mind that a lot of users have trailers muted by default; if yours relies on audio (especially in the beginning), it might not make sense to someone watching it muted. My trailer starts with the main character asking “You wanna know what my problem is?”. This is meant as an audio hook to ramp up curiosity from the get-go; my solution to the trailer being muted was having the very first thing in the trailer be the text “PROBLEM?”, hopefully making you curious enough to un-mute. Sink the hook in early, keep the text snappy and intriguing 3. The top-right short description Probably the most important copy element on your page. Just like the trailer, start strong and try and get their attention immediately. As you can see, I went with crazy cultists and a talking cat; think about what’s impactful about your game. Sum it all up in the middle part, and end with your tagline (mine is “Comedy cosmic horror made in Transylvania”). If you don’t have a tagline, come up with one. Sink the hook in early, keep the text snappy and intriguing Keep in mind that there’s a character limit - it’s somewhere between 200 and 300. If your page is localized into other languages (more on that below), be very careful when entering this text in languages you don’t speak, because I’ll be damned if I understand how that goddamned character limit can fluctuate like that. 4. The release date There are actually two aspects to this: the forward facing one (what the users see), which can either be a date or custom text, and a tentative release date that you enter in the Steamgames back-end. You can change both as often as you like, but it’s not advisable to overdo it. As for the forward-facing one, if you do go for custom text then try to be clear and concise, e.g. “Coming soon”, “2019”, “TBA”, or “Never, lol”. Don’t use this space to beg for wishlists, I’ve seen that backfire in very ugly ways. 5. Tags According to Steam, tags can help determine what game has you in their “More like this” section. Choosing your tags so that they drive the right kind of traffic your way sounds easier than it is, and you’ll probably have to experiment a bunch, but what is important is to use all your tag slots available. My biggest mistake for a long time: only using 3 or 4 of the 15 possible. I was an idiot; you don’t have to be. I strongly advise you to read Steam’s documentation on tags. There’s very important information there that devs (myself included) typically just skim over. Here’s the tl;dr: tag order itself doesn’t seem to matter, but only the first 15 (out of 20 possible) tags count toward who the algorithm decides to show your game to. Apparently there’s talk of Steam intending to reduce their importance within the ecosystem, but for now, it seems that they’re pretty damn’ important, so treat them with the proper respect and attention. And a touch of reverence and fear. Anyone can tag your game, but you as the developer wield way much more power when you mess around with them. You can ban and reinstate tags at your will. You can encourage people to reinforce your tags, thus affecting their order, but it’s finicky stuff. What you do yourself is easier to control. You apply tags by clicking the plus button on your Steam page, logged in with your dev account: Do it. Ah, but what tags to apply? Good question, and I doubt anyone but Valve holds the definitive answer. Truth be told, I’ve just experimented until I’ve seen good results in both the traffic results and on Steamlikes, which is a neat site that shows what games have you in their “More like this” section. The more, the merrier. My game currently has 44; to put things into perspective, Sekiro has 2000+. I’m not exactly sure how all of this works - it might heavily rely on popularity or revenue. Your guess is as good as mine, you can go bug the Steamlikes guys on Twitter about it. You can also use custom tags you come up with, but other than the dubious satisfaction of wasting an important slot on “totes adorbs XD”, there’s not much to be gained. Check out Steam’s handy Popular Tags list and go from there. Look at games similar to yours. Note that Valve do encourage you to use “rarer” tags that better describe your product, rather than widely used ones such as “adventure” or “action”. A quick disclaimer: just getting a lot of traffic doesn’t equal automatic wishlist number increase. The two things that heavily factor into that are quality - which is, uh, subjective - and just how relevant your game is to the people that you’re steering in your page's direction. I suspect that driving a lot of irrelevant, non-converting traffic your way might actually hurt your game rather than help it. Also, it’s reasonable to assume that popularity is a big factor here, but I don’t think it’s ever been confirmed by Steam. 6. Main description text You can let loose here, but keep in mind that there’s only so many words a gamer can silently mouth his way through before the irresistible siren call of the next browser tab yanks them away. Your best bet is to have a more detailed description (2 or 3 paragraphs), and a bullet list of key features. You can now add animated gifs to this section. A good idea, but be very careful about file size. In their announcement, Valve warn that “If we see a store page with a large load size (e.g. 15MB+), we may remove any animated GIF's to ensure users can actually visit your page.” Just snicker derisively from your 100 Mb/second fortress and check your page load in Chrome by pressing F12 and choosing the Network tab - it’s under “transferred” (thanks for the tip, Alex). I’m sticking to just one gif, so my page load is right under 15MB. Keep your page load under 15 MB to be on the safe side 7. Localization In case you’ve decided to localize your game into more languages, congrats - it’s a wise decision. As soon as you’re positive about offering a certain language, enable it ASAP in the Steam back-end. This will significantly help drive traffic from speakers of that language your way. Again, the more the merrier, with EFIGS being the standard, but Russian and Chinese becoming more and more popular. Keep an eye on your Analytics to see where traffic comes from (more on that below). If you do localize, please make translating your Steam page a priority. Actually, even if you don’t have the budget to full localize your game, just translating your page into major languages will help. 8. Social links Pretty much self-explanatory: plug in all your youtubes, twitters, facebooks and twitches, plus your website. Speaking of your website, Steam now offers widgets that, when clicked, automatically add your game to the clicker’s wishlist (mental note: add one to our website). 9. Awards Flaunt’em if you got’em. 10. Achievements and trading cards People really seem to like these things. People are weird, but you’re here to give them what they want, not what they need. Incidentally, that’s what gamedev’s really all about. 11. System Requirements Much like talking to the pharmacist before a romantic encounter, please be honest and realistic about what you need in order to perform optimally. 12. Back-end Safari Steamworks’ back-end is a wild ride. Let’s jump in. First off, the really important stuff: graphical assets! Let’s talk capsules, first and foremost, since screenshots are pretty much self-explanatory (just choose the pretty ones, and positively no concept art). Laura Bularca goes into size and other in-depth stuff in this very helpful blog post. My advice is to have two nicely rendered promo images ready - a big’un and a small’un. Easy! The big one - We’ll call him George. Make sure George’s source file is big enough to serve as page background (1438px x 810px), and clear enough that he can be resized and used as the main promo image above the short description. Also clearly display your logo on this latter one, so it’s easily readable at every size. The small one - We’ll affectionately call this one Junior. Unless they are magically whisked to your page via your evil marketing machinations or just pure bad luck, versions of Junior are likely Steam users’ first contact with your game in the wild plains of Steam. I am recommending that this little guy be a different image from George, because if you just downsize his detailed, lushly rendered bigger brother you’ll end up with a busy, unintelligible mess. George & Junior are brothers, not twins As you can see, Kitteh, our feline protagonist, features prominently in both George and Junior (apparently it’s called “staying on brand”), but Junior is way simpler, so he can be easily read and understood at first glance. That’s because - like in nature documentaries - Junior has to survive in the very hostile conditions of a quadrillion other thumbnails around it screaming for your attention, and - unlike in nature documentaries - he wants to achieve the exact opposite of camouflaging himself. Also notice that I’ve increased Junior's subtitle so as to improve its readability. Valve are very adamant about the entire game title being included in Junior, so make sure to abide by that rule when submitting assets for approval. An effective trick for testing Junior’s efficiency is to take a screenshot of e.g. the New and Trending row of capsules, superimpose your capsule in Photoshop on top of an existing one, and ask a friend or your Nanna to check it out sight unseen, being honest about which of them grab their attention and which don’t. Survival of the fittest and most readable. George and Junior are brothers, and equally important to your game family. Make sure they look related, make sure they’re as pretty as possible. Further watching: check out Valve’s Tom Giardino beautifully explain the concept of capsule readability, with examples. Actually, just watch the whole thing, there’s very useful stuff about trailers in there that I’ve echoed in this article, it’s very good. Store traffic stats I never got either math or graphs, but I find myself returning daily to this collection of numbers and pretty colored lines you can find as a tab in the “Marketing and visibility” area of Steam’s back end. You should too, since it’s the best way to gauge how your traffic has been doing the previous day. You’ve got a nice big visits graph, an impressions graph that isn’t visible by default, but is a click away, and a detailed traffic numbers breakdown below, divided into a boatload of categories. You can “mute and unmute” specific traffic sources on the graphs to see how they’ve been faring, and it never stops being interesting, educational, and terrifying to compare visits to impressions. You can worry about CTR, but don’t obsess about it, because it’s relative and very dependent on how much traffic you are getting. Before starting to appear in search suggestions, my CTR was way bigger; now it’s a fraction of what it was, but daily wishlists have gone up, and your daily number of wishlists is the only thing that matters, really. As a general rule, you will of course want your external traffic to be strong, but how you market your game outside of Steam is a whole different discussion we won’t go into here. Each traffic report category can be clicked to reveal subcategories. There are way too many to go into detail about here, but the “Other product pages” category is where you can gauge how strong your tag-fu and capsule game are. This is good daily information, stay on top of it and use it wisely Research all categories via Steam’s documentation, and keep an eye on them daily. For me, at least, this page updates every night at around 12 AM CET. Wishlists As stated before, no matter what you do, you want these to go up every day, or at the very least not plummet. If you’ve done your homework, they should at least be stable, or gently rising. Good news for fans of tension and suspense, you can get a hefty dose of both by checking your progress every day around 12 PM CET. Not much else to say other than restate that doing good in this area is what all of your on and off-Steam efforts should be focused on at all times. I know a bunch of folks who’ve lost a lot of weight, and the thing they all have in common was not letting one day slip by without weighing themselves, regardless if it proved exhilarating or discouraging. Always being aware of where they were motivated them to stay focused on the task at hand. Same with checking wishlist additions daily - sometimes it feels good, sometimes it makes you shake your fist at the screen in anger and dismay, but at least you always know where you’re at. Your heart stops. Then you remember Steam only shows you yesterday’s wishlists, never today’s. Google analytics Stick it into your Steam back-end. That sounded worse than intended. It’s the tab right next to the Store Traffic Stats. Congratulations, now you can spend the rest of your days up to launch with one eye permanently fixed on GA’s real time results. By the way, Steam almost always shows me ~2x the traffic GA does. I have no idea why that is; if anyone does, let me know in a comment. Plug & pray Broadcasts Streaming your game live on Steam isn’t just a neat way of showing it off more than in a trailer and a bunch of screenshots, it can get you some super nice exposure via tag pages. Here’s what you need to do: download OBS, join this beta broadcast group, then read all about setting up the stream here, go here to get your stream key (aka token) and to pick a server. Go into OBS, choose “custom” as a streaming service, paste in your server address and your token/stream key, and fiddle around with the stream settings until they match what Steam recommends in the previously linked relevant page. I won’t go into OBS scene set up etc, there are plenty of tutorials on YouTube; don’t worry, it’s not exactly rocket science. The broadcast will appear at the very top of your page, and, more importantly, it will appear on your main tag page if it reaches at least 10 viewers, and if other broadcasts with more viewers aren’t already hogging those slots (they are). Anything over 10, really E.g. my main tag page is “adventure”; usually there’s 1 to 3 active streams at any given moment. Any user that scrolls to the very bottom of the tag page can see your stream there if it's above 10 viewers. Another chance at decent traffic, so do consider it. Don’t forget that you can click “Show Chat” and be insulted in real time by smart-asses with nothing better to do. Delightful. Other back-end stuff Here are some other important things that might be easy to miss in the intimidatingly dark and twisted corridors of Steamworks: Genre: Tick the appropriate box for your game. Also tick “indie”, maybe. Keywords: To be honest, this one is still a bit confusing for me. Mine are a bit of a mess, since they're a combination of stuff similar to my tags, and intentional misspellings of my title so that people typing it wrong can still reach my game (i.e. gibos, gibbios, ktulu, chtulu, etc). Saving and publishing: Whenever you are editing your store page, saving does not mean your changes are reflected in the page automatically. You need to hit “publish to public” in order for the public-facing page to reflect how you’ve now made it uglier and more confusing. It’s on that tab they've sneakily labeled “Publish”. 13. Steam page discussions Pin a thread about your Discord server. You do have a Discord server, right? Make a Discord server. Be nice. Gamers will ask when the game is coming already, constantly. They do not do this to annoy you, they do this because they care about your game, and that’s huge. Someone actually cares about what started out as such a beautiful thing, and now gives you headaches and nightmares and uuuurgh! Be thankful and respectful and as honest as possible when you lie to their faces that it’s almost done and right around the corner. But seriously, be honest and nice - there’s no situation where this advice doesn’t apply. Some of them will also say that they won’t buy your game unless it’s translated into their language. Solution #1: be nice and, if this is true, reassure them that it will be available as soon as budget permits. Solution #2: localize your god damned game already. But, again, be nice. There are exactly zero scenarios where you freak out and let loose on a potential buyer and things end up well for you. It should come naturally, but if it doesn’t, clench your teeth and at least try to be nice. Don’t leave discussion threads unanswered, especially the ones consisting of direct questions to you, even if you don’t yet have the answers. Be honest, and I think I already mentioned being nice a bunch, so let’s move on. 14. Wait, that’s it I’ll stop here, this was already a lot to take in at once. Congrats if you made it all the way through, you are probably super dedicated and you want to give your game the best shot at success on Steam possible. You’ve got the right attitude, now you just need a Steam presence to match. I really hope this guide helps you find your audience with less hassle - ultimately, it's all about connecting the right customer with the right product, and everybody wins (but Steam wins more). If you feel this post has been helpful or interesting, consider thanking me by wishlisting my game and telling a friend who’s into narrative games about it. We’re about to launch soon, and it’s as scary and stressful as it’s exciting. Note: This post was originally published on Reddit and is reproduced here with the kind permission of the author. The author is developing Gibbous - A Cthulu Adventure and would appreciate wishlists on Steam.
  • 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!