Explore Free Level Design Tutorials – GameDev Academy https://gamedevacademy.org Tutorials on Game Development, Unity, Phaser and HTML5 Tue, 28 Mar 2023 06:28:06 +0000 en-US hourly 1 https://wordpress.org/?v=6.1.1 https://gamedevacademy.org/wp-content/uploads/2015/09/cropped-GDA_logofinal_2015-h70-32x32.png Explore Free Level Design Tutorials – GameDev Academy https://gamedevacademy.org 32 32 How to Set up Environments with QUIXEL in Unreal Engine https://gamedevacademy.org/unreal-quixel-tutorial/ Fri, 31 Mar 2023 01:00:34 +0000 https://gamedevacademy.org/?p=21708 Read more]]>

You can access the full course here: MAKE A PLANE ARCADE GAME IN UNREAL ENGINE

Environment – Part 1

In this lesson, we will learn how to set up our environment to create a more visually appealing game. By using Quixel Bridge, we can easily download high-quality photo-scanned assets for free. Quixel is basically a library of many different photo-scanned, 3D models that can be used for free within Unreal Engine.

Using Quixel Bridge

To get started with Quixel Bridge, go to Window and then Quixel Bridge. You can also undock the window for ease of use.

Quixel Bridge

Next press the Planet symbol and choose Environment.

Planet symbol and Environment

From here, Scroll Down and choose the Natural environment option.

Natural environment

This will give you many different environments to choose from, feel free to pick any environment you like, however in this course we will be using the Artic Ice And Snow environment collection.

Artic Ice And Snow

Now you can select an asset you like and click and drag it into your level, this will download and spawn the object in your level. It may prompt you to sign in before downloading in the bottom right.

asset

You can then move, rotate and scale your 3D model as you see fit within the level to build your scene.

You can also click and drag materials onto objects in your scene, to try this, select a ground material from Quixel Bridge and drag it onto our ground cube in the level.

materials

Now you can bring in any 3D models, materials, and props you like from Quixel Bridge to make your environment. Also, duplicate the rings we created previously to set up a course for your plane to fly through!

Environment – Part 2

In our example level we created a small, inclosed environment using the Quixel Bridge assets and made a large path of rings through out it for the player to fly through.

inclosed environment

Testing

We’re now ready to press Play to test out the game.

Testing

You should now be able to control your plane, fly through all of the rings and complete the course while increasing your score. You are now all set for creating your own arcade plane game, you could expand upon this in multiple ways such as adding weapons to shoot at targets with, a race objective around an obstacle course or adding collisions to the walls.

BUILD GAMES

FINAL DAYS: Unlock 250+ coding courses, guided learning paths, help from expert mentors, and more.

Transcript – Environment – Part 1

Welcome back, everyone. In this lesson we are gonna be working on setting up our environment.

Now, right now you can see we have a pretty bland environment right here with just the rings, the floor, and the default sky.

So what we’re gonna do is we are gonna go ahead and use Quixel Bridge in order to get some high quality photo scanned assets into our game here. So to do this, we’re gonna go up to Window, we’re gonna go over to the Quixel Bridge.

Now, Quixel is basically a library of hundreds and thousands of different photo scanned 3D models. So these are high quality models that we can just drag and drop into our project for free, okay?

So in the bridge here, what we’re gonna do is I’m just gonna undock this window because we do sort of want it in the same view as our level here. And what we’re gonna do is we are just going to search for what we want.

So on the left hand side here, you’ll see there is a little planet. And I’m gonna hover over that, I’m gonna click on it, I mean, click on environment, and then environment here, we’re gonna go down click on natural.

And as you can see, there are plenty of different environments we can choose from. I’m gonna go Arctic Ice and Snow, just ’cause I think that’ll be pretty cool for a plane game.

And yet we can then go through, click on an asset that we might like, and you may have a option down here to log in before you actually download these.

And make sure you do that. Just log in with your Google account, with your Epic Games account. There’s plenty of ways to log in.

So once you do that, what we can do is we’re not gonna click on download because that will download it to our computer and makes it a bit hard to find.

Instead, what we’re gonna do is we are gonna click and drag on the thing that we want, and we’re gonna click and drag it into our level here. And then you’ll see that it spawns in like so, okay?

We can then scale it up, move it around, rotate it, and this basically just acts as a 3D model. And depending on which quality you set here, it depends on of course the size of the textures and the size of the model.

But overall, these models do look pretty good. And something else we can do is then, on our ground, we can click and drag on this material to apply it like so. And there we go.

We have that snow texture now applied to our ground. What I want you to do now is just go through and drag in the 3D models that you wish to create and set up your environment.

Okay, there are plenty of different models and environment set pieces here. So set those up. And also go ahead and start duplicating these rings and positioning them in places where, you know, you might have a nice challenging flight game to play. So I’ll be right back to see how you’re doing.

Transcript – Environment – Part 2

Okay, so you to go at that challenge. Pretty much just start placing those models around. As you can see, I also put these rings around, so the players to fly through them.

And you also got some other ground assets here to just add to the environment. So we can press play and test it out. Okay, increase our flight speed. Make it over to the ring little course I made over here. And there we go.

So as you can see, you can pretty much create whatever sort of flight arcade game you want. You might even wanna start adding in some weapons to the planes if you want.

You might add some targets that you could shoot down. Really, there’s a lot of things you can do with this little plane blueprint right here. You can of course, create rings like we’ve done. You can create weapons, create targets.

You might even wanna create a race around an obstacle course with collisions on the walls, so that if you were to bounce into them, the plane would explode. And yeah, that is our plane game inside of Unreal Engine.

Thank you for watching.

Interested in continuing?  Check out our all-access plan which includes 250+ courses, guided curriculums, new courses monthly, access to expert course mentors, and more!

]]>
Best Tower Defense Tutorials – Making Strategy Games https://gamedevacademy.org/best-tower-defense-tutorials/ Mon, 23 Jan 2023 09:45:57 +0000 https://gamedevacademy.org/?p=15574 Read more]]> Tower defense games are one of the most popular subgenres of strategy gaming, tasking players with repelling waves of enemies by placing weapons and defensive units around a maze-like map. They offer a fun challenge with plenty of replayability thanks to the variety of different playstyles and strategies that players can deploy.

As such, we’ve compiled a list of some of the best tower defense tutorials currently available online. By following these tutorials, you’ll be well on your way to crafting imaginative and challenging tower defense games for players to enjoy playing again and again!

Why Learn To Create A Tower Defense Game?

Tower defense games offer a fun challenge for both players and developers. Players have to work out the optimal strategy for holding back enemies, and developers have to design genuinely challenging levels without making the game unfair.

Because of their replayability and their relative simplicity compared to other strategy games like real-time strategy games, tower defense games can be highly appealing as an entry point into strategy game design. However, they still require aspiring game developers to master a range of different mechanics before they can start to build their own tower defense games.

Tower defense games are therefore an excellent genre for testing your level design and game balancing skills as a developer. Make a map too easy, and your players won’t be impressed by the lack of challenge – but make it unreasonably hard and they’ll simply give up instead of trying to find the right strategy. 

Learning to find the ideal middle ground between these extremes is a key test of your skills as a game developer, and tower defense games give you a great opportunity to master this art.

Tower defense character

Tower defense games also give you the chance to practice with various different game mechanics like enemy design, currency systems, technology trees, and more. You can also blend in elements of other genres like RPGs to give your tower defense game a fun twist. As such, tower defense games are an adaptable and rewardable genre for learning new skills and practicing your existing ones.

To help you on your way to creating your first tower defense game, we’ve put together a list of some of the best online tutorials for learning essential skills and mechanics in the tower defense genre. Most of these tutorials are designed to be accessible even for those with limited experience in coding and game development, so if you’re only just getting started making games, don’t worry – you’ll quickly find your feet with these tutorials! 

There’s also plenty to learn here for more experienced game developers, so whatever your skill level, you’re sure to find a tutorial that works for you from the selection below.

Create A Tower Defense Game 

If you’re new to the tower defense genre and need a comprehensive introduction to the essential skills and mechanics you need to make your own tower defense game, this tutorial from Zenva Academy has you covered. The Create A Tower Defense Game tutorial provides a detailed guide to creating your first tower defense game in Unity.

Through this tutorial, you’ll learn various core mechanics of the genre such as tower placement, enemy wave spawning, currency systems, and more. You’ll also master some fundamental programming skills for the Unity engine such as scriptable objects and game managers.

All you’ll need to get started is a basic understanding of Unity and C#, so it’s a perfect place to start even if you’re only just beginning your game development journey. It’s not just for beginners, though – more experienced coders will have the opportunity to practice their existing skills, learn new ones and add an impressive new project to their portfolio.

Key Topics Covered: 

  • Creating paths for enemies to follow
  • Spawning enemies in customizable waves
  • Placing towers with UI indicators
  • Tracking health and money for gameplay control
  • Implementing different towers and attack types
  • Setting up win and defeat/game over conditions

Duration: Just under 3 hours of video tutorials guiding you through the whole process of creating your first tower defense game.

How To Make A Tower Defense Game

Another option for aspiring game developers looking to make their first tower defense game in Unity is the How to make a Tower Defense Game series from Brackeys. This series explores how to use Unity to create a 3D tower defense game.

These tutorials will walk you through the entire process of creating your first 3D tower defense game in Unity, from the initial setup of the project to core tower defense mechanics like tower placement, enemy wave spawns, upgrades, and more. The series is split into 28 separate tutorials, each covering a different gameplay element, so even if you’re just looking to learn specific mechanics then it’s easy to jump in and out wherever you please.

Key Topics Covered:

  • Creating enemies, coding their AI, and setting up wave-based spawns
  • Creating, placing, and upgrading towers
  • Programming tower attacks and behaviors
  • Camera movement and control
  • Creating a currency system and tower/upgrade shop
  • Creating different tower classes
  • Implementing base health/lives and win/lose conditions
  • Adding non-damage effects like slowing and freezing enemies
  • Creating new levels and setting unlock requirements

Duration: A longer series lasting roughly 10 hours, 35 minutes – although you can jump between episodes if you only want to learn specific mechanics.

Develop A Technology Tree For Strategy Games

Tower defense games aren’t just about placing towers and leaving them be – most games in the genre also offer the opportunity to upgrade them with new abilities as you progress through each level. Tower upgrades and other unlockable abilities help to add another layer of depth and complexity to your game, giving players more options in how they’ll approach things.

If you’d like to build an upgrade system for your tower defense game, then one of the best places to start is with the Develop a Technology Tree for Strategy Games tutorial. This series of bite-sized video tutorials provide you with step-by-step instructions to build a technology tree for strategy games, adding deeper gameplay potential to your tower defense game.

Throughout the tutorial, you’ll learn to implement an upgrade system with distinct prerequisites and costs for each new upgrade. You’ll also learn to construct a UI system for your upgrades that can also be applied to other projects. The best part is that you’ll only need a basic familiarity with C# and Unity to get started, making it a rewarding course for beginners as well as more experienced devs.

Key Topics Covered: 

  • Creating hierarchical systems that lock and unlock technologies available for research
  • Deducting resources or currency when technologies are researched
  • Setting up event systems that detect a technology’s state and relay it to other game elements
  • Building a UI with nodes and connectors instantiated through C#
  • Adding UI mechanics such as tooltips and panel toggling
  • Modifying game mechanics based on technologies researched

Duration: Roughly 2 hours, 45 minutes of video tutorials explaining the process of creating a technology tree for your tower defense game.

Tower Defense In Godot

Unity isn’t the only engine you can use to create tower defense games – there are plenty of other options such as Godot, an open-source platform designed with indie developers in mind. If you’re interested in creating a tower defense game with Godot rather than Unity, then the Tower Defense in Godot series from the Game Development Center is a great place to start.

This tutorial series provides detailed instructions for creating a tower defense game using Godot, providing guides for everything from the initial project setup to adding finishing touches like muzzle flashes and impact animations.

By following this tutorial, you’ll learn various essential skills like map creation, tower scripting, enemy spawning, and more. By the end, you’ll have created a fun and challenging tower defense game to add to your portfolio, and you’ll have the necessary skills to create more complex and innovative tower defense games with Godot in the future.

Key Topics Covered:

  • Setting up a tower defense project in Godot
  • Creating maps
  • Setting up towers and script inheritance
  • Creating menus
  • Scene switching
  • Setting up tower attacks 
  • Adding essential UI elements including tower range, health bars, money, and info bars
  • Adding final details like muzzle flashes and impact animations

Duration: Just under 4 hours of video tutorials exploring different stages of setting up a tower defense game in Godot.

1 Hour Programming: A Tower Defense Game In Unity 3D

If you’re looking for a slightly shorter tutorial that still covers everything you need to know to start making tower defense games, then quill18creates has you covered with the 1 Hour Programming: A Tower Defense game in Unity 3D tutorial.

The tutorial is designed to help you quickly build out the shell of a 3D tower defense game which you can then further develop and build out with your own ideas. The complete project’s files are all freely available to download, making it even easier to follow the tutorial at each step and build the project yourself. 

Since it’s a shorter and more fast-paced tutorial, it might be easier for slightly more experienced coders to follow than for absolute beginners. However, it’s definitely worth trying out, as it’s a quick way to learn the basics of the genre and build a basic tower defense game that you can then flesh out and add to your portfolio.

Key Topics Covered:

  • Enemy scripting and pathfinding 
  • Tower scripting, targeting, and attacks
  • Damage and health systems
  • Enemy death behavior
  • Currency and life systems
  • Different tower classes

Duration: Roughly 1 hour, 15 minutes, with the bulk of the tutorial carried out as real-time coding in just one hour.

2D Procedural Maps For Beginners

One way to make your tower defense games stand out from the crowd and add endless replayability is to implement randomized maps that change each time the game is played. If you’d like to add a random map option to your tower defense game, then the 2D Procedural Maps For Beginners tutorial will be perfect for you.

The tutorial provides a series of bite-sized explainer videos that provide step-by-step instructions for creating procedurally generated maps for your games using expandable programming logic. In doing so, you’ll also learn some useful new C# skills and gain valuable practice using Unity.

You’ll need to have some prior experience with C# and Unity to get the most out of this tutorial, but the step-by-step format makes it highly accessible and simple to follow.

Key Topics Covered:

  • Generating noise maps in Unity
  • Understanding noise settings for different effects
  • Calculating biomes based on noise map data
  • Organizing biome data with Scriptable Objects
  • Instantiating 2D tiles based on biome data
  • Implementing a player controller

Duration: 1 hour, 30 minutes of bite-sized video tutorials explaining the process of creating procedurally generated maps in Unity.

Roblox Tower Defense Tutorial

If you’re not familiar with Unity or C#, then an alternative starting point for your first tower defense game is Roblox’s creation engine. Roblox uses the beginner-friendly Lua programming language to power its game creation engine, and GnomeCode provides an excellent guide to using this engine to create your very own tower defense game within Roblox. 

By following the Roblox Tower Defense Tutorial series, you’ll learn various core elements of the tower defense genre, such as path navigation, wave-based enemy spawns, tower placement, and more. If you’ve used Roblox to create games before, then this is an ideal series for learning more about the underlying mechanics that make tower defense games work.

Key Topics Covered:

  • Map creation and path navigation
  • Programming wave-based attacks
  • Creating and animating different enemy types
  • Creating and placing different tower types
  • Tower vs enemy combat 
  • Implementing a base health system and currency system
  • Creating an upgrade system and corresponding graphical UI 
  • Selling/destroying towers 
  • Programming different targeting behaviors for towers

Duration: Roughly 6 hours, 50 minutes of tutorials on different elements of a Roblox tower defense game.

Conclusion

Tower defense games are a staple of the strategy genre, and making your own is a great place to start if you’re looking to master essential strategy mechanics. Their relative simplicity also makes them an ideal project for those just getting started with game design; you’ll quickly learn and master various key skills that will help you tackle a variety of other projects and genres in the future.

Using the tutorials above, you’ll be able to add some simple tower defense games to your portfolio and begin fleshing them out with new features to enhance their gameplay potential. Before long, you’ll be a tower defense master! Of course, there are plenty of tutorials out there, so don’t be afraid to continue exploring this fascinating genre.

BUILD GAMES

FINAL DAYS: Unlock 250+ coding courses, guided learning paths, help from expert mentors, and more.

]]>
What is Game Design? A Guide for Making Video Games https://gamedevacademy.org/what-is-game-design/ Fri, 13 Jan 2023 06:10:04 +0000 https://gamedevacademy.org/?p=13301 Read more]]> It is no real secret that making video games is a complex and intense process – whether you’re creating a simple platformer or something as robust as an MMORPG. This complexity begins first and foremost at the idea stage where the life essence of all video game projects begins. As much as some people might wish it, though, simply thinking of an idea doesn’t make a video game come into existence.

So, what is an aspiring video game maker supposed to do once they have the idea? This is where the story of game design begins, a fascinating subfield of game development that is crucial to the entire process.

In this article, we’ll explore what game design even is at the very foundation, how game design exists as a career, and help you understand why it is so critical to the world of game development at large. We’ll also provide you with a ton of resources so you can learn the “how” of game design too and apply it to your projects!

BUILD YOUR OWN GAMES

Get 250+ coding courses for

$1

AVAILABLE FOR A LIMITED TIME ONLY

Defining Game Design

In this first section, we’re going to take a look, first and foremost, at what game design is at the most base of levels. This will not only establish a good foundation as we explore how video game design functions as a career, but also help out beginners coming in not quite sure how to define it!

Two women planning out the UI for a mobile application

What Game Design is

Game design can be considered the planning arm of the entire process for making a video game. No video game gets made without a plan, and video game design is, more or less, the process of making that plan. The field is somewhat a hybridization of creativity and technical skills that combine into a cohesive, fleshed-out idea that people can work with using concrete and actionable tasks.

However, that is a lot to unpack, so let’s break everything down a bit more in layman’s terms.

Creative Side

As mentioned, all video games start with an idea. This idea can simply be something like:

  • “I want to make a platformer where the princess is the player character.”
  • “I will make a choice-based story RPG set in a Lovecraftian-inspired world.”
  • “I think it’d be cool if there was a one-hit kill battle royale video game.”

What the idea is doesn’t particularly matter, but the point is that these are the sparks that kickstart the game design. From there, though, this idea is not enough yet to make a video game. Instead, we’re left with a lot of questions:

  • What does the princess player character look like?
  • How are “choices” presented in the video game – dialogue or implemented in the gameplay itself?
  • How can a one-hit kill video game be balanced for fun rather than frustration – and is it multiplayer or singleplayer?
  • What sorts of weapons and/or items are available in these video games?
  • Do these video games have some deeper story?

We can certainly go on and on with these questions, yet what you may not realize is answering these questions is a large part of what game design is about! These are the exact elements that help you design the game – from the characters and plot, to the design of the levels, to the mechanics of how the video game is played, to the expression of the mechanics in a way that is fun, and even to aesthetics. Every little aspect like this must be answered, and game designers are the ones to do just that.

In essence, they take that base idea, and create a narrative out of it – just a specific one that helps elaborate on what elements need to be decided on and made piece by piece to make the whole puzzle of a video game come together.

Woman drawing technical things in the air

Technical Side

However, as creative as this might all sound, we can’t neglect to elaborate on why video game design is also still a technical field.

On the one hand, most game designers are actually expected to know a bit of programming, computer science, and math. While in bigger teams they might not be expected to program at all, they do need to have the background knowledge to oversee the game’s production. After all, if a programmer on the team makes something that doesn’t test well, the game designer is going to have a hard time communicating the technical problem unless they are familiar with the game’s construction.

So, having the necessary technical background will, at the very least, make communication easier as you polish and finetune the game design.

This is not to mention that many different game genres require pretty intense math and balancing. For example, if you’re making a city-building strategy game, you need to be able to plan costs, plan resources, plan timetables for construction or resource gains, and so forth. This will need to be tested, rebalanced, tested again, rebalanced again, and so forth. In order to do these tasks, as well as make the initial formulas, a strong understanding of math is needed.

Beyond this, game design can also be a lot about some of the humdrum business aspects as well, including things like planning the game around the target audience.

For example, according to GameRefinery, while realism is the preferred graphic style in the west for mobile games, Japan prefers anime-styled art across the board for their video games. So, depending on which market you were targetting, the art style choices of the game design might change drastically given that. While definitely not the most creative, these still are important factors to consider during the planning process.

Summary

Overall, game design is one part creativity with deciding the atmosphere, story, and aesthetics of the video game, and one part technical know-how deciding game mechanics, balancing, and so forth. Game design is a robust field of study that involves just as much knowing how and why to do a certain thing as it is using your imagination to create novel possibilities.

However, no matter which side you talk about, game design is about creating the initial plan, knowing the tools and techniques to create that plan, and how that will dictate how the full game comes together as one experience. This is a concept that surpasses many other aspects of video game development, such as even what game engines to use.

Bar chart and facts regarding the popularity of art styles in various world regions

Differences from Game Developer

Before we move on to talking about game designers as a professional career, let’s stop for a moment to talk about the elephant in the room. In other words, how does a game designer differ from a game developer?

This is a tricky question, as it depends on each game designer’s personal situation, some nuanced technicalities, and the exact context in which each term is used. However, we can try to break it down as best we can.

First and foremost, most game designers can be considered game developers. Rather than being entirely separate, game design can be considered a subfield of the entire video game development process. Generally, even for something like a UX/UI designer for a game, these subfields still encompass people considered to be game developers at the heart of the issue. Certainly, they have specialties, but they’re still part of the development team.

That being said, when most people are using the term “game developer”, they are generally speaking not of the specific subfields, but of the general programmers who work with the designer and plan out the super technical aspects like data structures, objects, and so forth. It’s also assumed these developers have a good grasp of computer science in comparison to other specialties.

We go more into depth on the entire field of game developer in this article, but the important point here is the context of how the terms are used generally refer to different things entirely – one about planning and one about programming.

Then again, it is worth pointing out that in the indie sector, where many video games are solo developed, the game designer can also be the sole “game developer” in charge of everything. As such, there is some huge crossover in activities. No game is made without a plan, so someone at some point has to do the game design.

All in all, though, the best way to navigate the world is to focus on game design as a specific subfield rather than focus on the differences. At the end, everyone involved in making a game is an important member of the game development process.

Computer with hands typing code onto the screen

Game Design as a Career

Now that we understand what game design is, let’s dive into the actual practice of it as a career in the gaming industry. Even if you’re only interested in video games as a hobby, this still may be a worthwhile section to explore just to get an understanding of a game designer’s everyday life – as game design is not all fun and playing games. It may also give you some insight into what awaits you should you make that critical decision to start this career path.

Activities

To begin, we’ll start by talking about the sorts of activities a professional game designer might do in the gaming industry as a whole. With your new understanding of game design, many of these will be no surprise.

However, before proceeding, let’s establish one thing: every game designer, video game, and game development studio is different. Some activities on this list a video game designer may never touch depending on the makeup of the team and what the video game is (as different types of video games need different things), whereas others might do all of them and then some. So, be sure to consider this when deciding if this is the right career for you or not!

  • Script/story writing: If a story is involved with the game, a game designer might spend a lot of time working on those aspects. This includes establishing the setting and history, establishing characters and their backstories, planning out the narrative plot, and potentially writing all the dialogue that will be used throughout the game. In larger teams, the game designer may simply coordinate with dedicated writers to get some or all of these various aspects done. Nevertheless, a game designer will often be intimately involved in getting the story off the ground.
  • Planning and creating game art: Part of a game designer’s duties is to decide the game’s aesthetics. This can include creating basic character designs, environment visual designs, and so forth. Technical decisions will also be made here, such as whether to do pixel-art, 3D graphics, etc. Now in some cases, a game designer will make a basic concept, which they then turn over to a professional game artist to flesh out into a usable piece for relay to asset creators. In other cases, the game designer’s own art may serve as the final concept art from which the game assets are made.
  • Designing levels/puzzles/challenges: One thing almost all video games have in common is that there are “levels” – i.e. spaces where the game is played. Even if a single-level game – for example, a fighting game stage – every block, aesthetic, and critical path will be planned out by the game designer. This can also include planning out battle encounters, puzzles, and similar should the specific game call for that. Besides planning, a game designer may also be one of the main members implementing the levels into the game by placing assets and so forth – allowing them to tweak things as they go to create the best game possible.

Screenshot of a puzzle platformer made with Unity

  • Planning interfaces: If there is no dedicated UI/UX designer on the team, guess what falls to the game designer? Whether an inventory screen, some sort of video game encyclopedia, health and hunger bars, or even simply a text score, all these interfaces need to be planned to exist, placed strategically, and have their aesthetic design decided on. Game designers will spend a huge amount of time designing this aspect, as it is one of the main ways players interact and receive information from a video game.
  • Developing gameplay: As mentioned earlier, one of the main things video game designers do, even more so than the activities above, is decide on the exact mechanics of the game and how it is played. Even if it’s just how fast a player character jumps, a game designer will serve a critical role in deciding these aspects. This process usually begins with a game designer writing a Game Design Document so everything is laid out, whether for just them or for a larger team. From there, a game designer will tweak the design further so every minute detail presents well and feels good as a player plays through the game.
  • Collaboration and communication: Depending on team size, another activity video game designers might do in the professional world has to do with both collaboration and communication. In the previous activities, we discussed how in some cases, a video game designer may delegate certain tasks to specific specialists. When that is the case, a game designer will spend a lot of time communicating and collaborating with those team members to make sure everything created – whether that be art or the programming itself – fits the specifications of the design. GitHub is a tool that makes collaboration easily, as it allows you to communicate with your team and implement version control.
  • Programming: Once again, this activity depends entirely on the situation. However, many game designers do participate at least somewhat in the programming activities of the video game. This can range from very literally doing it themselves, to simply helping out other programmers and overseeing certain technical aspects so it is a match for what the designer intended. At the very least, some programming knowledge is helpful even if you don’t do it, since some aspects of game design are reliant on the technical limitations.
  • Testing and changing: Finally, and a big one for video game designers, is testing and changing the video game they’re working on. Besides being fun, video games at their heart are supposed to have a consistent, quality experience. Game designers will spend a long time testing every aspect of the video game to test how it feels to play, whether there are any mechanics that are broken or ruin the competitive nature of the video game, and so forth. Once those issues are discovered, they help tweak the game design until the final video game product is the very best it can be as far as the core design goes.

Woman playing a computer game

Job Outlook & Salary

While job availability will always vary depending on location and experience, game design can be a lucrative career to get into. According to Career Explorer, the United States alone has nearly 300,000 positions for game design. Their sources estimate that this will grow from 2016 to 2026 by 9.3%. Other sources, such as DegreeQuery which gathers information from the United States Bureau of Labor Statistics, put the job growth anywhere from 4% to 10% depending on specific data used.

These sources also indicate that game designers who specialize in mobile games will often have more ample job opportunities going forward.

On the salary front, even junior designers can expect to earn quite a bit. Without considering specializations, the job sites below reported the following salary ranges for game designers in the US:

Salaries might also vary greatly by company. For example, PayScale shows Bungie having the lowest salary for game designers at $61K, while Age of Learning, Inc. and Electronic Arts both pay over $85K for their game designers. Experience can also play a big role, with developers seeing an average of $10,000 more per year for every 1-5 years more experience they possess.

As you can see, though, game design is both in-demand and a profitable field to pursue. Further, game design can be even more profitable as you specialize, especially for things like UI/UX design.

List of average salaries for game developers

Becoming a Video Game Designer

By this point, not only should you have a good idea about what game design is, but also maybe you want to become one now – whether that means joining a professional AAA company or simply solo-developing some video games as a hobby. Whatever your ultimate goals, though, we’ve compiled some of our tips and resources to help you take the first steps on this amazing journey and master game design!

Get the Technical Skills

We’ve long since established that game design is not just about having creative ideas – it’s also about technical skills and knowing how and why to do certain game design things (not to mention knowledge of computer science).

So, obviously, the first step here is to get some technical skills and master the basics, both of game design and its many facets, and of programming. We’ve broken some helpful tutorials and online courses below to get you started on your journey.

Voxel tree made with MagicaVoxel

Programming

General Game Design

Game Art

Game Writing

Charts of various aspects of game design

Make a Video Game

Once you have the basics down, the next step in the journey to becoming a game designer would be to simply put it in practice and make your own games (in any of the popular game engines).

This not only allows you to practice your skills, but also lets you build a portfolio which is crucial if you’re trying to get hired. Plus, as we’ve established above, game design is an expansive field that is about game mechanics, UIs, and more. So the more opportunities you put each aspect of game design into practice, the more you’ll find what works from you.

Below we’ve compiled some of our favorite resources that will help you make your first video game. Keep in mind, we’ve also included some non-computer games in this list as well, since game design principles (like good mechanics) are still as relevant to board games, card games, and so forth. Also, don’t forget to expand past these tutorials as well – game design is about experimentation!

Text-based RPG example made with C++

Conclusion

By this point, we hope you have a good idea of what game design is. Game design is an essential component to all games no matter how large or how small. Without game design, projects would fall through quickly. With a concrete plan, though, any developer can bring a project into reality.

Additionally, game design is recognized as an important position in larger companies, with high salaries and a need for the in-demand skillsets involved. It is not just thinking of ideas, but understanding how to logically and systematically arrange those ideas in a way that produces a fun game.

All this being said, we’ve only just scratched the surface here. There are a lot of skills involved with game design – from understanding how to guide players, to understanding high-level concepts like game loops. However, with the resources provided, you can definitely dive deep into the field and even join the video game industry. Maybe you’ll even make the next hit game. 😉

BUILD GAMES

FINAL DAYS: Unlock 250+ coding courses, guided learning paths, help from expert mentors, and more.

]]>
Complete Guide to Procedural Level Generation in Unity – Part 1 https://gamedevacademy.org/complete-guide-to-procedural-level-generation-in-unity-part-1/ Mon, 19 Dec 2022 10:31:09 +0000 https://gamedevacademy.org/?p=5733 Read more]]> In this tutorial series, we are going to procedurally generate levels using Unity. In the first tutorial, we are going to use pseudorandom noise to generate height maps and choose terrain types according to the height in each part of our level. In the next tutorials, we are going to assign biomes for each part of the level and in the end, we are going to generate a level map object that can still be manually edited according to the game needs.

This tutorial series takes inspiration from, and expands on techniques presented by Sebastian Lague, Holistic3D and this GDC talk on procedural generation in No Man’s Sky.

Rest of the series: part 2, part 3.

In order to follow this tutorial, you are expected to be familiar with the following concepts:

  • C# programming
  • Basic Unity concepts, such as importing assets, creating prefabs and adding components

Before starting to read the tutorial, create a new Unity project.

Looking for procedural generation on 2d maps instead? Check out this article here instead!

Source code files & Requirements

You can download the tutorial source code files here.

Before starting to read the tutorial, create a new Unity project. If you’re new to Unity, we recommend checking out some beginner-friendly Unity courses first. For teachers, you can also provide students core Unity teaching via the Zenva Schools platform which offers easy-to-use online courses and classroom management features.

Looking for procedural generation on 2d maps instead? Check out this article here instead!

BUILD YOUR OWN GAMES

Get 250+ coding courses for

$1

AVAILABLE FOR A LIMITED TIME ONLY

Generating noise

In order to procedurally generate levels, we are going to use noise functions in our code. A noise function is basically a function that generates pseudorandom values based on some input arguments. By pseudorandom it means the values look random, despite being algorithmically generated. In practice, you can see this noise as a variable, which can be used as the height, temperature or moisture values of a level region. In our case, we are going to use it as the height of different coordinates of our level.

There are different noise functions, but we are going to use a specially popular one called Perlin Noise. You don’t need to fully understand Perlin Noise, since Unity provides an implemention it. What I’m going to explain in this tutorial is how you can use it in your code.

So, let’s start by creating a script we are going to generate a noise map. First, create a new script called NoiseMapGeneration. This script will have a function called GenerateNoiseMap, which will receive as parameters the map height, map width and a scale. Then, it will generate a matrix representing a noise map, with the noise in each coordinate of the level.

For each coordinate, we generate the noise vaue using the Mathf.PerlinNoise function. This function receives two parameters and generate a value between 0 and 1, representing the noise. Notice that we are going to use the x and z axes to access the level coordinates, while the y axis will be used to change the height of our level in a given coordinate. So, the parameters for the PerlinNoise function will be the x and z indices divided by the level scale. In practice, the level scale parameter acts as a zoom parameter in the level. In the end, it returns the noise map.

public class NoiseMapGeneration : MonoBehaviour {

	public float[,] GenerateNoiseMap(int mapDepth, int mapWidth, float scale) {
                // create an empty noise map with the mapDepth and mapWidth coordinates
		float[,] noiseMap = new float[mapDepth, mapWidth];

		for (int zIndex = 0; zIndex < mapDepth; zIndex ++) {
			for (int xIndex = 0; xIndex < mapWidth; xIndex++) {
                                // calculate sample indices based on the coordinates and the scale
				float sampleX = xIndex / scale;
				float sampleZ = zIndex / scale;

                                // generate noise value using PerlinNoise
				float noise = Mathf.PerlinNoise (sampleX, sampleZ);

				noiseMap [zIndex, xIndex] = noise;
			}
		}

		return noiseMap;
	}
}

Now we need some way to visualize this noise map. What we are going to do is creating a Plane GameObject to represent a tile in our level. Then, we can show the generated noise values by painting the tile vertices according to their corresponding noise values. Again, this noise can represent anything you want, such as height, temperatura, moisture, etc. In our case, it will represent the height of that vertex.

Creating level tile

Let’s start by creating a new Plane (3D Object -> Plane) object called Level Tile. This will create the object below, already with a Mesh Renderer, which we are going to use to show the noise map.

Level Tile object in the Unity Inspector

Before showing the noise map in the tile, it is important that you understand how a Plane mesh looks like. The figure below shows the a Plane created in Unity along with its Mesh. Notice that the mesh vertices are not only the four Plane vertices. Instead, the Mesh contains several intermediate vertices that are connected inside the Plane. Basically, what we are going to do is using each one of those vertices as a coordinate for our noise map later. This way, we can assign a color to each vertex (which will be a height later) according to each generated noise value.

Grid tile in Unity Scene view

Now, we create the following Script called TileGeneration. This script will be responsible for generating a noise map for the tile and then assigning a texture to it according to the noise map. As this noise map will be used to assign heights to each vertex, from now on I’m going to call it a height map.

First of all, notice that the script has the following attributes:

  • noiseMapGeneration: the script which will be used to generate the height map
  • tileRenderer: the mesh renderer, used to show the height map
  • meshFilter: the mesh filter component, used to access the mesh vertices
  • meshCollider: the mesh collider component, used to handle collisions with the tile
  • levelScale: the scale of the height map

Basically, in the Start method it will call the GenerateTile method, which will do all this stuff. The first thing it does is calculating the depth and width of the height map. Since we are using a square plane, the number of vertices should be a perfect square (in our case, the default Unity Plane has 121 vertices). So, if we take the square root of the number of vertices, we will get the map depth and width, which will be 11. Then, it calls the GenerateNoiseMap method with this depth and width, as well as the levelScale.

public class TileGeneration : MonoBehaviour {

	[SerializeField]
	NoiseMapGeneration noiseMapGeneration;

	[SerializeField]
	private MeshRenderer tileRenderer;

	[SerializeField]
	private MeshFilter meshFilter;

        [SerializeField] 
        private MeshCollider meshCollider;

	[SerializeField]
	private float mapScale;

	void Start() {
		GenerateTile ();
	}

	void GenerateTile() {
                // calculate tile depth and width based on the mesh vertices
		Vector3[] meshVertices = this.meshFilter.mesh.vertices;
		int tileDepth = (int)Mathf.Sqrt (meshVertices.Length);
		int tileWidth = tileDepth;

                // calculate the offsets based on the tile position
		float[,] heightMap = this.noiseMapGeneration.GenerateNoiseMap (tileDepth, tileWidth, this.mapScale);

                // generate a heightMap using noise
		Texture2D tileTexture = BuildTexture (heightMap);
		this.tileRenderer.material.mainTexture = tileTexture;
	}

	private Texture2D BuildTexture(float[,] heightMap) {
		int tileDepth = noiseMap.GetLength (0);
		int tileWidth = noiseMap.GetLength (1);

		Color[] colorMap = new Color[tileDepth * tileWidth];
		for (int zIndex = 0; zIndex < tileDepth; zIndex++) {
			for (int xIndex = 0; xIndex < tileWidth; xIndex++) {
                                // transform the 2D map index is an Array index
				int colorIndex = zIndex * tileWidth+ xIndex;
				float height= heightMap[zIndex, xIndex];
                                // assign as color a shade of grey proportional to the height value
				colorMap [colorIndex] = Color.Lerp (Color.black, Color.white, height);
			}
		}

                // create a new texture and set its pixel colors
		Texture2D tileTexture = new Texture2D (tileWidth, tileDepth);
		tileTexture.wrapMode = TextureWrapMode.Clamp;
		tileTexture.SetPixels (colorMap);
		tileTexture.Apply ();

		return tileTexture;
	}
}

After generating the height map, the script will call the BuildTexture method, which will create the Texture2D for this tile. Then, we assign this texture to the tile material.

The BuildTexture method will create a Color array, which will be used to create the Texture2D. Then, for each coordinate of the height map, it will choose a shade of grey based on the height value. We can do this by using the Color.Lerp function. This function receives as parameters two colors (in our case black and white) and a float value between 0 and 1 (in our case the noise value). Then, it chooses a color between the two ones selected according to the float value. Basically, the lower the height, darker will be the color. In the end, it creates a Texture2D using this Color array and return it.

Now that the TileGeneration script is complete, we add both our scripts to the Level Tile object.

Level Tile in Unity Inspector with Tile Generation script

And then, we can try playing our game to visualize the height map. The image below shows a height map generated using a scale of 3. Hint: it is easier to visualize the tile if you switch back to the Scene view after starting the game. This way you can easily move the camera to see tile by different angles.

Tile game object with height map applied

Assigning terrains types

Our next step is to assign terrain types (such as water, grass, rock, mountain) to different height values. Also, each terrain type will have a color associated with it, so that we can add colors to our Level Tile.

First, we need to create a TerrainType class in the TileGeneration Script. Each terrain type will have a name, height and color. Also, we need to add the [System.Serializable] tag before the class declaration. This will allow us to set the TerrainType attributes in the editor later. Finally, we are going to add another attribute to the TileGeneration Script, which will be an Array of TerrainTypes. Those will be the available terrain types for our level.

[System.Serializable]
public class TerrainType {
	public string name;
	public float height;
	public Color color;
}

public class TileGeneration : MonoBehaviour {

        [SerializeField]
	private TerrainType[] terrainTypes;

}

Then, we can set the terrain types for the Level Tile in the editor. Those are the terrain types I’m going to use. You can set them as you prefer, but it is important that the terrain types are in a ascending order of height values, as this will be necessary soon.

Level Tile in the Unity Inspector with Terrain Types settings

Now let’s change the TileGeneration script to use those terrain types to assign colors to the tile. Basically we are going to change the BuildTexture method to, instead of picking a shade of grey for the color, we are going to choose a terrain according to the noise value (using a ChooseTerrainType method). Then we assign the terrain type color to that level tile coordinate.

private Texture2D BuildTexture(float[,] heightMap) {
		int tileDepth = heightMap.GetLength (0);
		int tileWidth = heightMap.GetLength (1);

		Color[] colorMap = new Color[tileDepth * tileWidth];
		for (int zIndex = 0; zIndex < tileDepth; zIndex++) {
			for (int xIndex = 0; xIndex < tileWidth; xIndex++) {
				// transform the 2D map index is an Array index
				int colorIndex = zIndex * tileWidth + xIndex;
				float height = heightMap [zIndex, xIndex];
				// choose a terrain type according to the height value
				TerrainType terrainType = ChooseTerrainType (height);
				// assign the color according to the terrain type
				colorMap[colorIndex] = terrainType.color;
			}
		}

		// create a new texture and set its pixel colors
		Texture2D tileTexture = new Texture2D (tileWidth, tileDepth);
		tileTexture.wrapMode = TextureWrapMode.Clamp;
		tileTexture.SetPixels (colorMap);
		tileTexture.Apply ();

		return tileTexture;
	}

The ChooseTerrainType method will simply iterate through the terrainTypes array and return the first terrain type whose height is greater than the height value (that’s is why it is important that the terrain types are in ascending order of height).

TerrainType ChooseTerrainType(float height) {
		// for each terrain type, check if the height is lower than the one for the terrain type
		foreach (TerrainType terrainType in terrainTypes) {
			// return the first terrain type whose height is higher than the generated one
			if (height < terrainType.height) {
				return terrainType;
			}
		}
		return terrainTypes [terrainTypes.Length - 1];
	}

Now we can try playing the game again to see our tile with colors. You will notice that the tile looks a little blurred, but don’t worry about that now. It will look better once we have multiple tiles in the level.

Level Tile with earth-like colors applied

Changing mesh heights

We have assigned terrain types to the tile coordinates. However, it is still a plane, even in the mountain regions. What we are going to do now is using the height map to assign different heights to the tile vertices. We can do that by changing the y coordinate of the vertices.

In order to do so, we are going to create a new method in the TileGeneration Script called UpdateMeshVertices.  This method will be responsible for changing the Plane Mesh vertices according to the height map, and it will be called in the end of the GenerateTile method. Basically, it will iterate through all the tile coordinates and change the corresponding vertex y coordinate to be the noise value multiplied by a heightMultiplier. By changing the heightMultiplier we can change how the level looks like. In the end, it updates the vertices array in the Mesh and call the RecalculateBounds and RecalculateNormals methods. Those methods must be called every time you change vertices in the mesh. We also need to update the Mesh in the MeshCollider.

public class TileGeneration : MonoBehaviour {

	[SerializeField]
	private float heightMultiplier;

	private void UpdateMeshVertices(float[,] heightMap) {
		int tileDepth = heightMap.GetLength (0);
		int tileWidth = heightMap.GetLength (1);

		Vector3[] meshVertices = this.meshFilter.mesh.vertices;

		// iterate through all the heightMap coordinates, updating the vertex index
		int vertexIndex = 0;
		for (int zIndex = 0; zIndex < tileDepth; zIndex++) {
			for (int xIndex = 0; xIndex < tileWidth; xIndex++) {
				float height = heightMap [zIndex, xIndex];

				Vector3 vertex = meshVertices [vertexIndex];
				// change the vertex Y coordinate, proportional to the height value
				meshVertices[vertexIndex] = new Vector3(vertex.x, height * this.heightMultiplier, vertex.z);

				vertexIndex++;
			}
		}

		// update the vertices in the mesh and update its properties
		this.meshFilter.mesh.vertices = meshVertices;
		this.meshFilter.mesh.RecalculateBounds ();
		this.meshFilter.mesh.RecalculateNormals ();
		// update the mesh collider
		this.meshCollider.sharedMesh = this.meshFilter.mesh;
	}
}

Then, we can assign a heightMultiplier to the Level Tile and try running the game. The figure below shows a tile using a heightMultiplier of 3. We can see the mountains on it, but there is still a problem. We are applying heights even for water regions, which make them look weird, since they should be plane. That’s what we are going to fix now.

Level Tile object in the Unity Inspector Level Tile with greater height map applied

What we are going to do is creating a custom function that receives as input height values from our height map and returns corrected height values. This function should return a 0 value for all height values below 0.4, so that water regions are plane. We can do that by adding another attribute in the TileGeneration Script which is an AnimationCurve. Then, when assiging the y coordinate value of each vertex, we evaluate the height value in this function, before multiplying it by the heightMultiplier.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class TileGeneration : MonoBehaviour {

	[SerializeField]
	private float heightMultiplier;
	
	[SerializeField]
	private AnimationCurve heightCurve;

	private void UpdateMeshVertices(float[,] heightMap) {
		int tileDepth = heightMap.GetLength (0);
		int tileWidth = heightMap.GetLength (1);

		Vector3[] meshVertices = this.meshFilter.mesh.vertices;

		// iterate through all the heightMap coordinates, updating the vertex index
		int vertexIndex = 0;
		for (int zIndex = 0; zIndex < tileDepth; zIndex++) {
			for (int xIndex = 0; xIndex < tileWidth; xIndex++) {
				float height = heightMap [zIndex, xIndex];

				Vector3 vertex = meshVertices [vertexIndex];
				// change the vertex Y coordinate, proportional to the height value. The height value is evaluated by the heightCurve function, in order to correct it.
				meshVertices[vertexIndex] = new Vector3(vertex.x, this.heightCurve.Evaluate(height) * this.heightMultiplier, vertex.z);

				vertexIndex++;
			}
		}

		// update the vertices in the mesh and update its properties
		this.meshFilter.mesh.vertices = meshVertices;
		this.meshFilter.mesh.RecalculateBounds ();
		this.meshFilter.mesh.RecalculateNormals ();
		// update the mesh collider
		this.meshCollider.sharedMesh = this.meshFilter.mesh;
	}
}

Now let’s create this heightCurve. We can do this in the Editor, by selecting it in the Level Tile object. The curve should look similar to the one below. You can create a curve like this by selecting the third one in the menu, then adding a Key (right-click -> Add Key) in the 0.4 point and then dragging it to 0. You will also need to change the borders of the Key so that it is plane up to 0.4.

Height curve with a steep climb after 0.4

Finally, if you try playing the game it should show the level with plane water areas, which should look much better.

Level Tile object with heightCurve applied

Building a level with multiple tiles

The last thing we are going to do in this tutorial is adding multiple tiles to build a whole level. Each level tile will generate its own height values and the neighbor tiles should have continuous heights. So, the first thing we are going to do is making sure that Level Tiles will have the same height values in their borders.

We can do that by making sure that we are calling the PerlinNoise function with the same argument values for the border pixels. In order to do so, we are going to add offset parameters in the GenerateNoiseMap function. Those offsets are added to the x and z indices when calculating the x and z samples. Later, those offsets will correspond to the Level Tile position, so that the height is continuous along the tiles.

public class NoiseMapGeneration : MonoBehaviour {

	public float[,] GenerateNoiseMap(int mapDepth, int mapWidth, float scale, float offsetX, float offsetZ) {
                // create an empty noise map with the mapDepth and mapWidth coordinates
		float[,] noiseMap = new float[mapDepth, mapWidth];

		for (int zIndex = 0; zIndex < mapDepth; zIndex++) {
			for (int xIndex = 0; xIndex < mapWidth; xIndex++) {
                                // calculate sample indices based on the coordinates, the scale and the offset
				float sampleX = (xIndex + offsetX) / scale;
				float sampleZ = (zIndex + offsetZ) / scale;

                                // generate noise value using PerlinNoise
				float noise = Mathf.PerlinNoise (sampleX, sampleZ);

				noiseMap [zIndex, zIndex] = noise;
			}
		}

		return noiseMap;
	}
}

Then, we need to add those offset parameters when calling GenerateNoiseMap in the TileGeneration Script. The value of those parameters will be the opposite of the x and z coordinates of the Level Tile.

void GenerateTile() {
		// calculate tile depth and width based on the mesh vertices
		Vector3[] meshVertices = this.meshFilter.mesh.vertices;
		int tileDepth = (int)Mathf.Sqrt (meshVertices.Length);
		int tileWidth = tileDepth;

		// calculate the offsets based on the tile position
		float offsetX = -this.gameObject.transform.position.x;
		float offsetZ = -this.gameObject.transform.position.z;

		// generate a heightMap using noise
		float[,] heightMap = this.noiseMapGeneration.GenerateNoiseMap (tileDepth, tileWidth, this.mapScale, offsetX, offsetZ, waves);

		// build a Texture2D from the height map
		Texture2D tileTexture = BuildTexture (heightMap);
		this.tileRenderer.material.mainTexture = tileTexture;

		// update the tile mesh vertices according to the height map
		UpdateMeshVertices (heightMap);
	}

Before creating the whole level with several tiles, let’s create just two of them and put them side by side to check if the heights are continuous on the borders. For example, I created the two tiles below.

Level Tile 1 object in the Unity Inspector Level Tile 2 object in the Unity Inspector

Then, when running the game, they should look like a single level with two tiles.

Level Tile objects next to each other with height maps applied

What we are going to do now is generalizing this to a level with any number of tiles. First, save the Level Tile object as a prefab, so that we can instantiate copies of it later. Then, let’s create a new Script called LevelGeneration. This script will be responsible for creating multiple Level Tiles. It will have the following attributes:

  • mapWidthInTiles: number of tiles in the x axis
  • mapDepthInTiles: number of tiles in the z axis
  • tilePrefab: Level Tile prefab, used to instantiate the tiles

Then, the GenerateLevel method will create the Level Tiles by iterating through all the tile coordinates. For each tile, it calculates its position based on the tile coordinate and then instantiate a copy of it from the Level Tile prefab. In the end, this GenerateLevel method is called inside the Start method.

public class LevelGeneration : MonoBehaviour {

	[SerializeField]
	private int mapWidthInTiles, mapDepthInTiles;

	[SerializeField]
	private GameObject tilePrefab;

	void Start() {
		GenerateMap ();
	}

	void GenerateMap() {
		// get the tile dimensions from the tile Prefab
		Vector3 tileSize = tilePrefab.GetComponent<MeshRenderer> ().bounds.size;
		int tileWidth = (int)tileSize.x;
		int tileDepth = (int)tileSize.z;

		// for each Tile, instantiate a Tile in the correct position
		for (int xTileIndex = 0; xTileIndex < mapWidthInTiles; xTileIndex++) {
			for (int zTileIndex = 0; zTileIndex < mapDepthInTiles; zTileIndex++) {
				// calculate the tile position based on the X and Z indices
				Vector3 tilePosition = new Vector3(this.gameObject.transform.position.x + xTileIndex * tileWidth, 
					this.gameObject.transform.position.y, 
					this.gameObject.transform.position.z + zTileIndex * tileDepth);
				// instantiate a new Tile
				GameObject tile = Instantiate (tilePrefab, tilePosition, Quaternion.identity) as GameObject;
			}
		}
	}
}

Now, remove the Level Tiles from your scene and add a single Level object, with some tiles in the x and z axis. The figure below shows an example of a Level with 10 tiles in each axis. You may also want to change the Level Scale and Height Multiplier for the Level Tiles to make the level look better. In the figure below I used a Level Scale of 10 and a Height Multiplier of 5. However, you can still see some repeating patterns in the level, as well as some weird-shaped regions. So, our last step in this tutorial will be to polish a little bit the Noise Map generation to make the level look more natural.

Level object with Level Generation script attachedLarge level map with terrain generation applied

Adding multiple waves

What we are going to in order to polish the noise map generation is adding more noise waves. Basically, when you call Mathf.PerlinNoise, you’re sampling points from a noise wave. So, if we change this wave frequency and amplitude we change the noise result. Another way of changing the noise values is adding a random seed in the samples. By creating multiple waves with different frequency, amplitude, we can generate more interesting noise, which will led to levels that look more natural. The different seed values, by their turn, allows us to remove the repetitions in the level.

So, first, let’s create a Wave class inside the NoiseMapGeneration Script. Like the TerainType, the Wave will be a Serializable class with a few attributes. The attributes we are going to use are the seed, frequency and amplitude of the wave, as discussed earlier.

[System.Serializable]
public class Wave {
	public float seed;
	public float frequency;
	public float amplitude;
}

Then, we change the GenerateNoiseMap method to receive an Array of Waves as parameter. Then, instead of calling Math.PerlinNoise a single time, we call it once for each Wave, using the wave seed, frequency and amplitude. Notice that the frequency is multiplied by the sample value, while the amplitude is multiplied by the noise result. In the end, we need to divide the noise by the sum of amplitudes, so that its result will remain between 0 and 1.

public float[,] GenerateNoiseMap(int mapDepth, int mapWidth, float scale, float offsetX, float offsetZ, Wave[] waves) {
		// create an empty noise map with the mapDepth and mapWidth coordinates
		float[,] noiseMap = new float[mapDepth, mapWidth];

		for (int zIndex = 0; zIndex < mapDepth; zIndex++) {
			for (int xIndex = 0; xIndex < mapWidth; xIndex++) {
				// calculate sample indices based on the coordinates, the scale and the offset
				float sampleX = (xIndex + offsetX) / scale;
				float sampleZ = (zIndex + offsetZ) / scale;

				float noise = 0f;
				float normalization = 0f;
				foreach (Wave wave in waves) {
					// generate noise value using PerlinNoise for a given Wave
					noise += wave.amplitude * Mathf.PerlinNoise (sampleX * wave.frequency + wave.seed, sampleZ * wave.frequency + wave.seed);
					normalization += wave.amplitude;
				}
				// normalize the noise value so that it is within 0 and 1
				noise /= normalization;

				noiseMap [zIndex, xIndex] = noise;
			}
		}

		return noiseMap;
	}

Now, we need to add an Array of Waves as a new attribute of the TileGeneration Script, so that we can send it to the GenerateNoiseMap method.

public class TileGeneration : MonoBehaviour {

	[SerializeField]
	private Wave[] waves;

	void GenerateTile() {
		// calculate tile depth and width based on the mesh vertices
		Vector3[] meshVertices = this.meshFilter.mesh.vertices;
		int tileDepth = (int)Mathf.Sqrt (meshVertices.Length);
		int tileWidth = tileDepth;

		// calculate the offsets based on the tile position
		float offsetX = -this.gameObject.transform.position.x;
		float offsetZ = -this.gameObject.transform.position.z;

		// generate a heightMap using noise
		float[,] heightMap = this.noiseMapGeneration.GenerateNoiseMap (tileDepth, tileWidth, this.mapScale, offsetX, offsetZ, waves);

		// build a Texture2D from the height map
		Texture2D tileTexture = BuildTexture (heightMap);
		this.tileRenderer.material.mainTexture = tileTexture;

		// update the tile mesh vertices according to the height map
		UpdateMeshVertices (heightMap);
	}
}

Finally, we add some Wave values in the Level Tile prefab and then we can play the game again to see the new level. The figure below shows the values I’m using in this tutorial to generate the level in the righthand figure. Notice that I changed the Level Scale and Height Multiplier again, to make the level look better. You may have to try different values until you find the one that looks better to you.

Level Tile object in the Unity Inspector Level Tile object with numerous generated waves

And this concludes this procedural level generation tutorial! In the next one we are going to generate tempereatures and moisture values for our level, so that we can select biomes for different level areas.

Access part 2 here, or brush up on your Unity skills with robust online courses for individual users and for schools.

BUILD GAMES

FINAL DAYS: Unlock 250+ coding courses, guided learning paths, help from expert mentors, and more.

]]>
A Guide to Procedural Generation https://gamedevacademy.org/procedural-2d-maps-unity-tutorial/ Mon, 19 Dec 2022 01:00:50 +0000 https://coding.degree/?p=522 Read more]]> While hand-crafted 2D maps for games are amazing, they can take a lot of time to make. Plus, once your game is published, the only way to add more maps is to update the game – which in itself is a tedious process.

This is where procedural generation comes in, as it allows our code to generate maps for us and takes out much of the grunt work!

In this tutorial, we’ll be creating a 2D map that is procedurally generated with many different types of terrain(forest, snow, desert, etc). We’ll accomplish this by using procedural noise maps and generating one for the height, moisture, and heat. Combining these together will give us a specific biome for each tile, and result in a pretty nifty map generation handled entirely by our backend!

Let’s get started!

Example of a procedurally generated map in Unity

Project Files & Requirements

In this tutorial, we’ll be using an edited public domain sprite sheet for the different biome tiles (from OpenGameArt.org).

  • Download the edited sprite sheet here
  • Download the complete Unity project here

Additionally, before getting started, be aware that this tutorial assumes you have some of the basics of Unity under your belt. If not, we recommend starting with some of our other Unity tutorials first, or visiting the Unity Game Development Mini-Degree for an entire curriculum on Unity skills.

Teachers can also try out Zenva Schools – a platform designed specifically for teaching students in the classroom. Along with Unity courses, the platform offers other features such as classroom management tools, reporting, and much, much more.

BUILD YOUR OWN GAMES

Get 250+ coding courses for

$1

AVAILABLE FOR A LIMITED TIME ONLY

Creating the Project

To begin with our procedural map generation, let’s create a new Unity project with the 2D template selected. In our new project, we want to create 4 new folders.

  • Biomes – where we’ll store the scriptable objects representing each biome
  • Prefabs – where we’ll store the tile prefab and player prefab
  • Scripts – where we’ll be storing our C# scripts
  • Sprites – where we’ll be storing our sprite sheet

Unity Assets folders set up for map generation

Inside of the Sprites folder, drag in the sprite sheet.

Spritesheet we'll be using for procedurally generating our map

Selecting the sprite sheet, let’s change some settings over in the Inspector.

  • Set the Texture Type to Sprite (2D and UI)
  • Set the Sprite Mode to Multiple
  • Set the Pixels Per Unit to 32
  • Set the Filter Mode to Point (no filter)
  • Click Apply to apply the changes

Unity Inspector with Spiresheet Import Settings

Now we need to divide our sprite sheet into individual sprites. In the Inspector, click on the Sprite Editor button to open up the Sprite Editor window.

  • Click on the Slice dropdown
  • Set the Type to Grid By Cell Size
  • Set the X and Y Pixel Size to 32
  • Click Slice
  • After that’s done, click on the Apply button and exit the Sprite Editor

Unity SpriteEditor for 2D map sprite sheet

In the Project browser, you should now be able to open up the sprite sheet to see all of the individual sprites.

Sprites in Unity Assets after being sliced

What is Noise?

How are we going to procedurally generate our map? With noise. You give the algorithm an X and Y value and it will return to you a value between 0 and 1. Below is an example of Perlin Noise – this is what Unity uses.

Example of a noise map

Noise is used for a large number of things and pretty much every game with procedurally generated terrain uses it. Now, this doesn’t look very natural as the transition between 0 and 1 is very uniform across the noise map. To combat this, we can stack multiple noise maps on top of each other to get more varied and custom outputs.

These are known as waves and have a few properties that we can modify.

  • Seed – this is the amount we are offsetting the noise so that we’re not sampling the same area for everything
  • Frequency – this is the scale of the noise map we’ll be sampling, a higher frequency will result in a more bumpy and noisy output, while a lower frequency will result in something more like the image above
  • Amplitude – this defines the size or intensity of the output

Here’s a visual look at frequency:

Graph demonstrating high frequency waves vs. low frequency

Here’s a visual look at amplitude:

Graph showing High Amplitude waves vs. low amplitude

Here’s what a noise map would look like with just 1 wave. It looks quite uniform and not that natural.

Noise map example with only 1 wave used

Here’s a noise map with 2 waves. It looks a lot more natural as the transitions between 0 and 1 are less consistent.

Noise map with 2 waves used

Noise Generator

Let’s now create a new C# script and call it NoiseGenerator. This script is only going to have one function – generate noise. Before we do that though, at the bottom of the script (outside of the NoiseGenerator class) let’s create a new class so that we can have waves.

[System.Serializable]
public class Wave
{
    public float seed;
    public float frequency;
    public float amplitude;
}

Now back in the main NoiseGenerator class, let’s create the Generate function.

public static float[,] Generate (int width, int height, float scale, Wave[] waves, Vector2 offset)
{

}

Here’s what each of the parameters do:

  • width – width of the noise map
  • height – height of the noise map
  • scale – overall scale so we can zoom in or out if needed
  • waves – array of different waves to generate the noise map
  • offset – horizontal and vertical offset if needed

The function also returns a float[,] – a 2D float array. Think of this as a spreadsheet with columns and rows. Each element will be a number between 0 and 1.

So inside of this function, we want to create a 2D float array for our noise map and then loop through each of those elements with 2 for loops.

float[,] noiseMap = new float[width, height];

for(int x = 0; x < width; ++x)
{
    for(int y = 0; y < height; ++y)
    {

    }
}
        
return noiseMap;

Inside of the second for loop, let’s first get the sample position for the X and Y values.

float samplePosX = (float)x * scale + offset.x;
float samplePosY = (float)y * scale + offset.y;

Then we can look through each wave and sample the noise – taking into consideration the frequency and amplitude.

float normalization = 0.0f;

foreach(Wave wave in waves)
{
    noiseMap[x, y] += wave.amplitude * Mathf.PerlinNoise(samplePosX * wave.frequency + wave.seed, samplePosY * wave.frequency + wave.seed);
    normalization += wave.amplitude;
}

noiseMap[x, y] /= normalization;

And that’s it! Here’s a look at the final function.

public static float[,] Generate (int width, int height, float scale, Wave[] waves, Vector2 offset)
{
    // create the noise map
    float[,] noiseMap = new float[width, height];

    // loop through each element in the noise map
    for(int x = 0; x < width; ++x)
    {
        for(int y = 0; y < height; ++y)
        {
            // calculate the sample positions
            float samplePosX = (float)x * scale + offset.x;
            float samplePosY = (float)y * scale + offset.y;

            float normalization = 0.0f;

            // loop through each wave
            foreach(Wave wave in waves)
            {
                // sample the perlin noise taking into consideration amplitude and frequency
                noiseMap[x, y] += wave.amplitude * Mathf.PerlinNoise(samplePosX * wave.frequency + wave.seed, samplePosY * wave.frequency + wave.seed);
                normalization += wave.amplitude;
            }

            // normalize the value
            noiseMap[x, y] /= normalization;
        }
    }
        
    return noiseMap;
}

Biome Preset

In order to define our biomes, we’re going to use scriptable objects. These are basically files we can create which hold properties. Let’s create a new C# script called BiomePreset.

  1. First, we need to be using the UnityEditor namespace.
  2. Then we need to add the CreateAssetMenu attribute.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;

[CreateAssetMenu(fileName = "Biome Preset", menuName = "New Biome Preset")]
public class BiomePreset : ScriptableObject
{
...

Inside of the class, we can now define our properties.

  • We have the sprites in an array for variation.
public Sprite[] tiles;
public float minHeight;
public float minMoisture;
public float minHeat;

Underneath our properties, we’re going to create two functions. GetTileSprite returns a random sprite from the tiles array.

public Sprite GetTleSprite ()
{
    return tiles[Random.Range(0, tiles.Length)];
}

MatchCondition checks to see if this biome matches the given height, moisture, and heat values. A biome can be viable if the given values for that tile are greater than or equal to the biome’s minimum values.

public bool MatchCondition (float height, float moisture, float heat)
{
    return height >= minHeight && moisture >= minMoisture && heat >= minHeat;
}

Back in the editor, let’s go over to our Biomes folder and create some biomes. Right-click and select Create > New Biome Preset. Give it a name. Go ahead and create 7 biome assets. Desert, Forest, Grassland, Jungle, Mountains, Ocean, and Tundra.

Biomes set up in Unity assets for 2D map generation

Then for each biome, we want to select it, go over to the Inspector, and fill in the properties.

  • Desert
    • Min Height = 0.2
    • Min Moisture = 0
    • Min Heat = 0.5
  • Forest
    • Min Height = 0.2
    • Min Moisture = 0.4
    • Min Heat = 0.4
  • Grassland
    • Min Height = 0.2
    • Min Moisture = 0.5
    • Min Heat = 0.3
  • Jungle
    • Min Height = 0.3
    • Min Moisture = 0.5
    • Min Heat = 0.62
  • Mountains
    • Min Height = 0.5
    • Min Moisture = 0
    • Min Heat = 0
  • Ocean
    • Min Height = 0
    • Min Moisture = 0
    • Min Heat = 0
  • Tundra
    • Min Height = 0.2
    • Min Moisture = 0
    • Min Heat = 0

Also, make sure to fill in the tiles array with each biome’s respective sprites from the sprite sheet.

Creating the Map

Now we can create a new C# script called Map and attach it to a new empty GameObject called _Map. This script is in charge of generating our 2D map. First, let’s start with some properties.

An array to store all of our biomes and the prefab for each tile.

public BiomePreset[] biomes;
public GameObject tilePrefab;

The dimensions of the map, scale and offset.

[Header("Dimensions")]
public int width = 50;
public int height = 50;
public float scale = 1.0f;
public Vector2 offset;

We’re going to be generating 3 maps. A height, moisture and heat map. These each need their own waves and output array.

[Header("Height Map")]
public Wave[] heightWaves;
public float[,] heightMap;

[Header("Moisture Map")]
public Wave[] moistureWaves;
private float[,] moistureMap;

[Header("Heat Map")]
public Wave[] heatWaves;
private float[,] heatMap;

Now we can create our main function called GenerateMap. This will get a noise map for the height, moisture and heat, then spawn in the tiles and give them each a biome.

void GenerateMap ()
{
    // height map
    heightMap = NoiseGenerator.Generate(width, height, scale, heightWaves, offset);

    // moisture map
    moistureMap = NoiseGenerator.Generate(width, height, scale, moistureWaves, offset);

    // heat map
    heatMap = NoiseGenerator.Generate(width, height, scale, heatWaves, offset);

    for(int x = 0; x < width; ++x)
    {
        for(int y = 0; y < height; ++y)
        {
            GameObject tile = Instantiate(tilePrefab, new Vector3(x, y, 0), Quaternion.identity);
            tile.GetComponent<SpriteRenderer>().sprite = GetBiome(heightMap[x, y], moistureMap[x, y], heatMap[x, y]).GetTleSprite();
        }
    }
}

We can then call this function in the Start function.

void Start ()
{
    GenerateMap();
}

You’ll see we’re calling a function called GetBiome. This is in charge of deciding which biome to select based on the given values for height, moisture and heat. Let’s create it now.

BiomePreset GetBiome (float height, float moisture, float heat)
{

}

Before we fill in the function though, there’s something we need to create. It’s a new class called BiomeTempData. Because this is how we’re going to calculate which biome to choose:

  1. First, we’ll loop through each biome and see if the height, moisture and heat are equal to or greater than the biome’s minimum values.
  2. If so, we’ll add that biome to a list (because multiple biomes may meet those conditions and we need to choose one).
  3. Then we’ll loop through that list and for each biome calculate its difference value. This is basically the difference between the height and its min height, the moisture and its min moisture and the heat and its min heat added together to give us a number.
  4. We want to find the biome with the lowest difference value as that means it’s the closest to the target conditions.

Here’s what the BiomeTempData class looks like:

public class BiomeTempData
{
    public BiomePreset biome;

    public BiomeTempData (BiomePreset preset)
    {
        biome = preset;
    }
        
    public float GetDiffValue (float height, float moisture, float heat)
    {
        return (height - biome.minHeight) + (moisture - biome.minMoisture) + (heat - biome.minHeat);
    }
}

Now inside of our GetBiome function, let’s first get a list of all the biomes which match the given height, moisture and heat.

List<BiomeTempData> biomeTemp = new List<BiomeTempData>();

foreach(BiomePreset biome in biomes)
{
    if(biome.MatchCondition(height, moisture, heat))
    {
        biomeTemp.Add(new BiomeTempData(biome));                
    }
}

Once we have the list of possible biomes, we need to find the one with the lowest difference value.

float curVal = 0.0f;

foreach(BiomeTempData biome in biomeTemp)
{
    if(biomeToReturn == null)
    {
        biomeToReturn = biome.biome;
        curVal = biome.GetDiffValue(height, moisture, heat);
    }
    else
    {
        if(biome.GetDiffValue(height, moisture, heat) < curVal)
        {
            biomeToReturn = biome.biome;
            curVal = biome.GetDiffValue(height, moisture, heat);
        }
    }
}

if(biomeToReturn == null)
    biomeToReturn = biomes[0];

return biomeToReturn;

Back in the Unity editor now, we can fill in the properties. First, drag in all the biome assets into the biomes array.

List of Biomes added in Unity Inspector for Procedural Map Generation

  • Set the Width to 100
  • Set the Height to 100
  • Set the Scale to 1

Then, create two elements inside of the height waves array and make them like so:

Settings for height waves for procedurally generated maps in Unity

For the moisture waves I only have 1, although you can have as many as you wish.

Moisture Waves settings in Unity for map generation

Then finally, the heat waves:

Heat Waves settings in Unity for procedurally generated map project

Tile Prefab

Let’s now create the tile prefab. In the Hierarchy, right click and create a new 2D Object > Sprite. Call it TilePrefab. Drag it into the Prefabs folder to save it as a prefab.

TilePrefab created in Unity Assets

Select the _Map object and drag the tile prefab into the corresponding property field.

TilePrefab added to Unity Inspector

Press play and you should see the generated map!

Procedurally generated map in Unity

Conclusion

Congratulations! We just created a procedurally generated 2D map inside of Unity!

As you’ve seen, with procedural generation, we can easily add a lot of variety to our games. This has a ton of implications on the replayability value of them, as well as how much development time will be needed to set them up.

Of course, you can extend map generation far beyond this. Perhaps you want to expand your biomes more and make unique ones for an alien planet. Or maybe you want to tweak the settings and create more of an ocean world. The sky is essentially the limit here, but with randomized maps, you’ll have a whole new world to explore each time the game is played.

Keep in mind as well that this can be useful for tons of different genres. So as you explore RPGs, strategy games, and more through Unity courses, tutorials, or school environments, you can adapt these techniques.

We hope you’ve gotten a lot out of this tutorial, and we wish you the best of luck with your future games!

BUILD GAMES

FINAL DAYS: Unlock 250+ coding courses, guided learning paths, help from expert mentors, and more.

]]>
A Guide to Handling Huge Open Worlds in Unity – Part 1 https://gamedevacademy.org/how-to-handle-huge-worlds-in-unity-part-1-deactivating-distant-regions-to-improve-performance/ Sun, 18 Dec 2022 17:49:55 +0000 https://gamedevacademy.org/?p=6014 Read more]]> Have you ever wondered how open worlds in video games work performance-wise?

In this tutorial series, we’re going to explore just how video games deal with huge worlds and make the best use of the processing power and memory available to the computer.

For this first part of our huge world tutorial, we’re specifically going to focus on how to process terrains, split them, and write scripts that will hide them when the player is too far away. In Part 2, we’ll circle back to how to deal with other objects, like trees, and also cover fog so you can easily hide your environment manipulations.

If you’re ready to learn the tools necessary for building open-world environments, let’s get started!

Source code files & Requirements

You can download the tutorial source code files (the Standard Assets folder was not included to reduce the file size)  here.

Additionally, please note that this tutorial does assume you already know the basics of Unity and C#. If this is your first time venturing into Unity, we recommend pausing and taking some beginner-friendly courses first to explore the fundamentals you’ll need to jump in.

If you’re an educator, you can also consider trying out Zenva Schools. Zenva Schools is an online learning platform aimed at K12 institutions. It comes with a variety of features for classroom management, and also offers many beginner-friendly courses on Unity as well.

BUILD YOUR OWN GAMES

Get 250+ coding courses for

$1

AVAILABLE FOR A LIMITED TIME ONLY

Creating the world

Before starting the tutorial, create a new Unity project.

There are different ways to create the world map of your game. Since the focus of this tutorial is on how to handle such world map, and not on how to create it, we are going to use an automated tool to create the map.

The tool we are going to use is called L3DT. This tool allows you to generate huge world maps which you can import in Unity later. Start by downloading and installing the program. Then, open it and select File -> New project.

L3DT with File menu open

We are going to create a Designable map. Select the map size you prefer.
In this tutorial, I’m going to generate a map with size 512×512. You can leave the other parameters in their default values.

L3DT Wizard with Heightfield size settings open

In the calculation queue window, select all maps to be created. In the end, we are only going to use the height map and the texture map, but generating the other maps will add information to the texture map in the end. For each map, you can leave the default parameters.

L3DT Wizard with Calculation queue settings open

In the end, l3dt will generate a map like this one.

World generation provided by L3DT

What we need to do now is exporting the height map and the texture map, so that we can import them later in Unity. In order to export the height map, select the heightfield tab, then right-click on the map and select Export. Unity only imports RAW, so we need to export it in this format. I’m going to create a folder called L3DT in the Assets folder of my Unity project, so that I can export the L3DT files there.

L3DT Wizard with Export Map window open

The texture map can be exported in a similar way. Select the texture map tab, right-click on the map and select Export. We are going to export it in the PNG format.

L3DT Wizard Export map options to export texture

Importing the map in Unity

Now, let’s import this map in Unity. First, open the Unity project you have created. In this project add a new Terrain object (right-click on the hierarchy and select 3D Object -> Terrain). This will create a new object with the Terrain component.

Terrain object in the Unity Inspector with Terrain Component open

Now, we are going to import the height map and the texture map into this terrain. In order to import the height map, select the terrain settings, go to the Heightmap section and click on Import Raw. Then, select the height map you have export from L3DT. It is important to set the Terrain Size to be the same as the L3DT map size (512×512). The size in the Y axis defines the height of the mountains, so you can try different values until you find the one that looks better in your game. I’m going to use a Y size of 100.

Import Heightmap window in Unity with 100 set for the Y

In order to import the texture map, you need to select the Paint texture option in the Terrain component. Then, click Edit textures to add a new texture.
Select the exported L3DT texture and set its size to be the L3DT map size (512×512). However, notice that, due to different coordinate systems between L3DT and Unity, the Y size must be negative (-512).

Add Terrain Texture window in Unity with world selected

After doing so, you should have your map imported in Unity. Now, our next step will be to slice this map into tiles.

World deformation in Unity game scene

Slicing the map into tiles

As I mentioned, we are going to activate the map regions that are close to the player, while deactivating those far away from it. In order to do so, we need to slice our world map into tiles. Instead of writing our own code to slice the map, we are going to use a solution available online.

Here you can download a Unity package to split terrains. After downloading it, just open it and it will import itself into your project. This will add a tab called Dvornik in your Unity project. By selecting it you can split the create terrain into four tiles.

However, once you do this, you will see that the terrain texture is being repeated for each tile.

Unity map object with tiles sliced

You can fix that by clicking on edit texture and adding the following offsets for the tiles:

  • Terrain 0: offset x = 0, offset y = 0
  • Terrain 1: offset x = 0, offset y = 256
  • Terrain 2: offset x = 256, offset y = 0
  • Terrain 3: offset x = 256, offset y = 256

We can repeat the process for each created tile, further dividing the terrain into sixteen tiles. Again, after splitting each tile, we need to adjust the offsets accordingly. However, instead of adding an offset of 256, now we need to add an offset of 128. For example, the offset of the new tiles created from Terrain 1 are:

  • Terrain 1 0: offset x = 0, offset y = 256
  • Terrain 1 1: offset x = 0, offset y = 384
  • Terrain 1 2: offset x = 128, offset y = 256
  • Terrain 1 3: offset x = 128, offset y = 384

In the end you should have a map with 16 tiles. Now that we have our world tiles, let’s start coding the script which will activate and deactivate terrain tiles according to the player proximity.

Deactivating distant tiles

We want our game to keep track of the player position and, when the player is far away from a given tile, to deactivate this tile from the game in order to improve performance. This way, this tile won’t be rendered, and our game won’t be wasting CPU and memory on such distant tiles.

The first thing we need is creating a HideTilesScript. This Script will be added to the Player object, and it will keep track of the distant terrains in order to hide them. In order to do so, we need the following attributes in this script:

  • tileTag: the tag of the tile objects, so that we can identify them.
  • tileSize: the size of each tile (128×128 in our case).
  • maxDistance: the maximum distance the player can be from the tile before it is deactivated.
  • tiles: the array of tiles in the game.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class HideTiles : MonoBehaviour {

	[SerializeField]
	private string tileTag;

	[SerializeField]
	private Vector3 tileSize;

	[SerializeField]
	private int maxDistance;

	private GameObject[] tiles;

	// Use this for initialization
	void Start () {
		this.tiles = GameObject.FindGameObjectsWithTag (tileTag);
		DeactivateDistantTiles ();
	}

	void DeactivateDistantTiles() {
		Vector3 playerPosition = this.gameObject.transform.position;

		foreach (GameObject tile in tiles) {
			Vector3 tilePosition = tile.gameObject.transform.position + (tileSize / 2f);

			float xDistance = Mathf.Abs(tilePosition.x - playerPosition.x);
			float zDistance = Mathf.Abs(tilePosition.z - playerPosition.z);

			if (xDistance + zDistance > maxDistance) {
				tile.SetActive (false);
			} else {
				tile.SetActive (true);
			}
		}
	}

	void Update () {
		DeactivateDistantTiles ();
	}

}

Then, in the Start method we use the FindGameObjectsWithTag method to retrieve the tiles in our game using the tileTag. Those tiles are saved in the tiles array, so that we can call the DeactivateDistantTiles method.

The DeactivateDistantTiles method, by its turn, will check the distance from the player to each tile in the game. Notice that the tile position is added with half of the tile size. That’s because we want to measure the distance from the player to the center of the tile, and not its bottom left corner. If the sum of the distances in the X and Z indices is greater than the maximum distance, we deactivate the Tile. Otherwise, we activate it. Finally, this method must also be called in the Update method, so that we keep updating the tiles status.

Now, in order to test our Script we need to add a Tile tag and a Player object. In order to add the Tile tag, select an object, click on the Tag menu and select Add Tag. Then, create a new Tag called Tile. Finally, you can assign this Tag to all the tile objects.

Terrain 0 0 object in the Unity Inspector

In order to create the Player object, we are going to import a Unity package. So, in the Assets menu select “Import Package -> Characters”. You can import all the Assets from the package.

Import Unity Package window with Standard Assets selected

This will create a Standard Assets folder inside the Assets folder of your project. Drag and drop the FPSController (Standard Assets/Characters/Prefabs/ FPSController) prefab into your game. This will be the player in our game, so let’s rename it to Player and add the HideTiles Script to it. Remember to properly set the Script attributes. In this tutorial I’m going to set 256 as the maxDistance attribute.

Player object in the Unity Inspector and Hide Tiles script

Now, you can try playing the game to see if the distant tiles are being properly deactivated. You can put the Scene view in the left side of the Unity Editor (alongside the Object Hierarchy) so that you can see its content while moving the player in the game.

Unity world map in a cross shape

And that concludes this tutorial. In the next one, we are going to add more stuff to our world, as well as adding a fog to hide the distant tiles that are being deactivated.

In the meantime, you can further expand your skills by learning about sound design for 3D worlds as well – another must-have feature to create the right atmosphere! You can also expand your Unity skills in general with online courses for both individuals or classroom settings, since one needs a game project to make use of a game world.

BUILD GAMES

FINAL DAYS: Unlock 250+ coding courses, guided learning paths, help from expert mentors, and more.

]]>
How to Build 2D Levels in Unity – Tilemap Editor Tutorial https://gamedevacademy.org/mastering-unitys-new-tilemap-editor-building-2d-levels/ Mon, 31 Oct 2022 12:50:53 +0000 https://gamedevacademy.org/?p=6387 Read more]]> Levels and level design make up a huge portion of game development – even when it comes to 2D levels.

In this tutorial, we’re going to cover Unity’s Tilemap Editor: the quickest way to construct 2D levels for your games. This editor easily lets you “paint” your levels using a grid-based system and sprites, speeding up your production time.

If you’re ready to expand your Unity 2D skills for level creation, let’s get into it.

Introduction

In October of 2017, Unity Technologies released Unity 2017.2. This version released a new tool called the Tilemap Editor, which not only allows the user to create vast and complex grid-based layouts in a matter of minutes, but also eliminates the need for a third party program (such as Tiled) to create a similar result. According to Rus Scammel (Project Manager of Unity for 2D), the Tilemap Editor will allow users to “…literally paint directly in Unity”, and that is exactly what it does. In this tutorial, we will look at the Tilemap Editor and the tools that go with it. Through this relatively simple project, you will learn skills that can be applied to complex levels in your future projects.

BUILD GAMES

FINAL DAYS: Unlock 250+ coding courses, guided learning paths, help from expert mentors, and more.

Importing the Assets

You can download the 2D assets we are going to be using here. These are from the Kenney asset website and are free to be used in any project, commercial or private. Check out their website here.

Setting up our project

Create a new project. Create a new folder called “Scenes”.

Create a new scene in that folder called “Scene1” and the open Scene1.

Now, create a new folder called “Tiles”. This is where we will be storing all our tiles for the Tilemap Editor. Then create two folders, one called “Tile Palettes” and another called “Tile Images”.

The use of these folders will become apparent as you move through this tutorial. Next, import the asset pack you downloaded and drag its contents into the “Tile Images” folder.

Now we need to head to Github. This is where Unity Technologies stores the extra tools that we will be using. Click this link: it will take you to the download page. Once it has finished downloading, unzip the package and drag it into the “Assets” folder of our project.

We will be looking at the specifics of what is in this package later in the tutorial. Once you have completed all of this you can head to the next paragraph!

Tilemaps and Grids

If you have a look at the assets provided, you’ll notice there are a several environment types to choose from, including “Cake”, “Castle”, “Choco”, “Dirt”, “Grass”, “Metal”, “Purple”, “Sand”, “Snow”, and “Tundra”.

Look through each of these and pick the one that you like best. This will determine what kinds of tiles we need to put in the Tilemap Editor. Once you have a tileset picked out, navigate to Window -> Tile Palette.

Chose an appropriate place to put this on your workspace (I prefer the right side of the scene view).

Next, click “Create New Palette”. A Palette is a set of images that we use to “paint” with. The name Palette is very appropriate since it resembles the palettes used by painters. The settings here are pretty self-explanatory, we don’t need to change them so just leave them set to default.

Call this one “Solids” since this palette is going to house the tiles that players are not allowed to pass through, such as the ground and the walls. Save “Solids” in the “Tile Palettes” folder. Now, drag all of your selected environment images into the Tile Palette window.

You may have to drag them in one by one. Save each tile in the “Tiles” folder. Before we start painting we need to create something called a “Tilemap” in our scene. Right-click in the hierarchy and go to 2D Object -> Tilemap.

This has created two things: a “Grid” and a “Tilemap”. This is how the Tilemap Editor works, there is only one Grid in the scene, but there can be several Tilemaps. The Grid creates the Grid that the Tilemap rests on. If you select the Grid you will notice a “Grid” component attached to it.

There are three things that we can change with this component: “Cell Size”, “Cell Gap”, and “Cell Swizzle”. “Cell Size” is the size of each square on the Tilemap. Only change this value if it is absolutely necessary, as the Cell Size applies to all Tilemaps within the Grid. “Cell Gap” determines how much distance there is between each square in the Grid. Once again, this should be changed with caution since this also applies to all of the tilemaps. “Cell Swizzle” is the direction that the Grid is facing. You can experiment with this value if you choose, but for this tutorial leave it set to “XYZ”. Now that we’re familiar with the Grid game object, what about the Tilemaps? Let’s take a look…

There are two components, “Tilemap” and “Tilemap Renderer”.  Most of the settings in the “Tilemap” component should be pretty self-explanatory and, at first glance, there are a lot of things that we can control. “Animation Frame Rate” is for animated Tiles. If this Tilemap contained any animated Tiles, we could change the speed of the animation with this value. We don’t have any animated tiles (but we will soon!) so just leave this set to 1. “Color”, as the name suggests, is the color of the Tiles in this Tilemap. With this, we can also set alpha or transparency values for things like water or clouds. “Tile Anchor” is, well, the Tile’s Anchor! Right now it is set to the center of each tile which is a where I need it to be. “Orientation” is the direction the tiles will be facing. I would only change this if I was doing a 3D game since, at times, it isn’t even in 2D space. Feel free to experiment with this value, but I’ll just leave it set to “XY”. In “Tilemap Renderer” we can change the material that each tile is rendered with, which we are going to leave set to the default. The rest of the settings deal with what order the tiles are rendered in. The ones that we are going to be paying attention to are the “Sorting Layer” and the “Order In Layer”. “Sorting Layer” defines what lay this Tilemaps rests in. We are going to be changing this value as we move on. “Order In Layer” is used if there is more than one object in a Sorting Layer. This is another value that should be changed with caution since it can get kind of confusing if there are several Tilemaps, with their own Order In Layer value, to determine which is rendered first. So, that is how Tilemaps and the Grid works! Let’s look at the Tile Palette now!

 

The Tile Palette

There are a couple of tools in the Tile Palette that we need to look at.

This one is called the “Selection Tool” and allows you to select a tile in the Tile Palette window in order to see it’s settings.

This one is known as the “Move Tool” and allows you to move tiles around in the scene view.

This is the “Brush Tool” and allows you to paint in the scene view, with the tile that you selected in the Tile Palette window.

This is called the “Fill Selection Tool” and it allows you to select a certain area to fill with the selected tile.

This is the “Tile Sampler” works just like a color picker in an image manipulation program like Photoshop or Gimp.

This is the “Eraser” and erases the tiles in the scene view, a shortcut to this is Shift-Click.

Finally, the “Fill Tool” and will fill an area with the selected tile without having to first select the area to fill. This one should be used for areas that are bounded by other tiles, otherwise, you can fill the entire scene view with the selected tile which is taxing on the RAM and the GPU. So those are the tools you can use to start painting your scene! The last important thing to look at is this button right here:

This determines which tilemap you are painting on. If you have multiple tilemaps in your Grid, then you need to set this to the tilemap that you want to paint on. This is something to watch out for. If you ever encounter a problem, whether it is overlapping tiles or tiles that are not animating, check this first. The last important thing to look at here is the tile images themselves. If you were to try and start painting now you would notice one thing about your tiles, they are overlapping!

To fix this, we have to find the tile images in our project window and change the import settings.

The value we need to look at is the “pixels per unit” value. A larger value decreases the size of our image and, conversely, a smaller value increases the size. We have to employ some trial and error here in order to find the correct value. Fortunately, I have found a value that corrects this problem fairly well.

Select all of the tile images that you used, change the “pixel per unit” value, and then click “apply”. Now they shouldn’t be overlapping!

If you are ever importing different tiles then you might have to do some experimentation in order to find the correct value.

Brushes and Rule Tiles

Let’s look at a few more tools before we start creating our environment. Near the bottom of our Tile Palette window, you will find a button that says “Default Brush”. If you click on it, it will show you a couple of different brushes.

We aren’t going to be using many of these brushes in this tutorial, but I encourage you to experiment with them in order to become familiar with them. The one that we are going to be using is the “Line Brush”. If you select this one you can click once to start the line, then click again and it will have the selected tile painted in a line between the two points.

Also, if you check “Fill Gaps”, the brush will try and make a diagonal line smoother by “filling the gaps” in the line.

So that’s how we can use different kinds of brushes!

The final tool that we will be using is known as “Rule Tiles”. Imagine that you are designing a 2D platformer. You start to make your levels using the Tilemap Editor only to find out that you are slowed down by having to trace the shape of the land, place the edge tiles in their proper places, and then fill in the middle space by using either the Fill Tool or the Fill Selection Tool. (This example may not be relevant to you but it certainly was to me when I was making my 2D platformer). Fortunately, the the Tilemap Editor has a solution to this! That’s right: Rule Tiles. Go to your “Tiles” folder and create a new folder called “Custom Tiles”.

In this folder, right-click and select Create -> Rule Tile and name it “Environment”.

A  Rule Tile is a specific set of tile images that we can give custom instructions to in regards to their placement or appearance.

It doesn’t matter what the Default Sprite is set to, but it is best to set it to a tile that is in your selected environment tile images. “Default Collider” specifies to how the tiles will have physics interactions. Leave it set to “Sprite”. Now, create as many “Tile Rules” as there are images in your selected set of environment tiles. If you aren’t going to use all of the images then just exclude those from the number of Tile Rules. Now, drag each tile image into their respective positions on the Tile Rules’ list. Now if you click on any of the squares you will notice that it creates an arrow, if you click again you will notice it creates a red X, and if you click again it leaves it blank.

An arrow signifies that the tile is continuing from the direction the arrow is pointing. And an X means that the tile “stops” or has an edge at this point. With this knowledge, let’s go through and assign arrows and Xs to each image. This can be kind of tricky to get used to so take a look at my final Rule Tile:

 

All we need to do now is drag the Environment rule tile into our Tile Palette and start painting.

You’ll see that it changes the image based on the tile’s position. This really speeds creation time up. The next part of Rule Tiles that we are going to explore is the animated aspect. Create a new Tile Palette and Tilemap called “Animated Tile”.

Now, create a new Rule Tile called “AnimatedTile1”.

Now go to the “Animations” folder in the asset pack and pick a set of animated tiles. Set the default sprite to one of these, then create a new tile rule. Change the “output” type to be “Animation”. Set the “Size” to be the number of sprites in your animation and then drag the animated sprites into their respective positions. Now create a new tilemap called “AnimatedTiles”. This screenshot sums up the whole process.

Drag “AnimatedTile1” into the Tile Palette

and set the active Tilemap to “AnimatedTiles”.

Now start painting! Before we hit play, let’s go to the “AnimatedTiles” tilemap and change the “Order In Layer” value to -1.

This makes the animated tiles rendered before the “Solids” tiles. If you hit play you’ll notice that our tiles are now animating!

The last part of a rule tile is the “Random” output. With “output” set to random, you can have it chose randomly between a set of tile images.

I didn’t use this part of a Rule Tile but feel free to try it if you would like.

Tile Colliders

The very last part of this tutorial is about Tile Colliders. On any tilemap, click Add Component and search TilemapCollider.

Find the component and assign it. Now our tiles will actually prevent an object from passing through them! Fantastic!

Outro

Whew! The last part! Now you can start creating your scene ’till your heart’s content! Once you’re done, you can test it out by importing Unity’s 2D assets by going to Assets -> Import Package -> 2D. They already have a 2D character controller which you can use to break-in your new level!

All this being said, don’t be afraid to experiment and expand what you’ve created here. For example, you can learn about procedural generation to expand your tilemaps or, if you’re up to it, code your own 2D character controller. No matter where you go with your skills, though…

Keep making great games!

]]>
How to Make Levels: Level Design for Open World Games https://gamedevacademy.org/level-design-open-world-tutorial/ Fri, 25 Jun 2021 01:00:41 +0000 https://gamedevacademy.org/?p=14035 Read more]]>

You can access the full course here: Level Design for Beginners

Open World Design

Unlike linear levels, open world games pose unique challenges when designing levels as it is inherently “open” to the player. They have the freedom to go wherever they want. We need to figure out how we can have control over the player’s progression through our open world.

The idea of an open world is that the player can travel anywhere they want at any time. But while this is true, many open-world games still have control over where the player goes in relation to progression.

Let’s start by looking at an example– “Grand Theft Auto IV”. When starting out, you can only explore one island. As you progress through the game, more and more islands get unlocked.

Open World Level Progression Grand Theft Auto IV
Grand Theft Auto IV © Rockstar Games

The reason why they do this is that they want you to get familiar with the island that you start off with. The story is tied to one specific point in the game map, and that is where the player should be.

Open World Level Progression Grand Theft Auto IV
Grand Theft Auto IV © Rockstar Games

As the story expands, the player can explore other islands. This gives a player a chance to explore the starting island, as well as serving as a point of where the story can take place. This is how the game can drive the player in a linear way through the game story, and through the game world itself.

In “The Legend of Zelda: Breath of the Wild”, you start off restricted to one tiny area of the map. Once you complete a few dungeons and understand the game mechanics, you are then allowed to leave and explore other areas.

Open World Level Progression The Legend of Zelda
The Legend of Zelda: Breath of the Wild © Nintendo

Level-based Progression

In “The Witcher 3”, progression is guided through enemy difficulty/leveling. Once you get put into the main map, you can go wherever you want, but each area has a different level of enemies. So if you’re walking around and encounter enemies that are higher level, the chances of you being attacked and dying increase as well. This will deter players from going to certain areas and keep them on the desired path.

Open World Level Progression The Witcher 3
The Witcher 3: Wild Hunt © CD Projekt

Resource-based Progression

Another example is “Minecraft”– although it is an open-world game, there is a fine control over where you go in what order, based on the items you need and the various different resources that you need to collect.

Open World Level Progression Minecraft
Minecraft © Mojang

Open World Level Progression Minecraft
Minecraft © Mojang

Landmarks

When you want your players to explore your world, the placement of landmarks is important. In “Skyrim”, all the major cities are displayed with special icons showing that they’re landmarks:

Open World Level Progression Skyrim
The Elder Scrolls V: Skyrim © Bethesda Game Studios and Bethesda Softworks

For a player navigating between these landmarks, they cover pretty much the entirety of the map. There are no areas that they may potentially miss.

Open World Level Progression Skyrim
The Elder Scrolls V: Skyrim © Bethesda Game Studios and Bethesda Softworks

In “GTA V”, there are three main landmarks spread across the entire map, giving the players reasons to explore.

Open World Level Progression GTA V
Grand Theft Auto V © Rockstar Games

Barriers

Barriers can also help in guiding your player through your open world. The two types of barriers in level design are:

  • Solid barriers – rigid obstacles that the player must follow or avoid
  • Soft barriers – obstacles that are used to guide the player yet can be ignored

The most obvious examples of solid barriers are in racing games, where we have a strict path to follow, and barriers that prevent us from going off the map.

Open World Level Progression Solid barriers
Forza Motorsport 7 © Turn 10 Studios and Microsoft Studios

Castles are common examples of a solid barrier in games as they have specific entry points and exit points that the player must go through in order to enter/exit the castle.

Open World Level Progression Solid barriers
The Witcher 3: Wild Hunt © CD Projekt

“Skyrim” has many soft barriers in the form of an overhang near paths. These overhangs subtly guide the player along the path, but they can still be ignored and walked over.

Open World Level Progression Soft barriers
The Elder Scrolls V: Skyrim © Bethesda Game Studios and Bethesda Softworks

“Subnautica” uses the depth of the ocean as a soft barrier to control the player’s progression through the game. At the start of the game, you can only go so deep as your oxygen will run out, preventing you from going deeper until you get better equipment. When you level up your submarines, your oxygen tank gets larger and you can go deeper down the ocean.

Open World Level Progression Soft barriers
Subnautica © Unknown Worlds Entertainment

Transcript

When trying to tackle open world game design it can be quite difficult as unlike previous levels you may have created which are quite linear, open world are inherently open to the player and they have the freedom to go wherever they want.

So what we need to do is try and figure out how we can have a control over the player’s progression through our open world, okay? Because the idea of an open world is that the player can travel anywhere they want at any time.

But while this is true, many open world games out there still have control over where the player goes in relation to progression. And by progression, I mean, progression through the story, or progression through the players’ abilities, okay?

When they level up, when they get new items, when they become more powerful, okay? So, let’s start by looking at an example. We have Grand Theft Auto IV. And when starting out in GTA IV, you can own the explore one island. You’re basically stuck to this one island at the start of the game, okay?

And as you progress through the game, more and more islands get unlocked. Now, the reason why they do this, is because they want you to get familiar with the island that you start off with, okay? They don’t want you to start off in the game and you have this entire world to explore. They don’t want you to just start running off going everywhere, okay?

Because the story is tied to one specific point in the game map and that is where you should be. It gives the player both a chance to explore this starting island, you know, learning the streets, learning where different locations are, becoming familiar with it, as well as serving as a point of where the story can take place.

And then as the story expands, the player can then explore other islands, learn those. And this is how the game can sort of drive the player in a linear way through the game story and through the game world itself.

Now, another example is Legend of Zelda: Breath of the Wild. And in this game, you start off restricted to one tiny area of the map. And after you complete a few dungeons and understand the game mechanics, you are then allowed to leave, you’re given the glider. So you can then exit this area and then explore the entire world, okay?

This starting area it gives you the knowledge of different tribes that run dungeons, how to play the game basically, how to defeat enemies. So when you go out into the world, you’re well prepared.

Another example is The Witcher 3. Now in The Witcher 3, apart from the starting map, once you get put into the main map right here, you can pretty much go wherever you want, but the game still has a control over where you go overall, based on leveling.

Now, each area has different level of enemies. So if you’re walking around and all of a sudden you are in an area where their enemies are double your level, you’re not really gonna go in there, okay? Because the chances of you being attacked and dying is quite high.

So you can sort of stick to the area where you’re most comfortable. And as you expand through the game, as you level up, you can go into more and more areas. And it relates to where the story is and where you go in the story. So this is how The Witcher 3 sort of guides you through their open world.

Another example is Minecraft. Now Minecraft is probably one of the most open world games you could say in that you can do anything at any time. But to progress through the main game, it is actually quite linear, okay?

There is a fine control over where you go and in what order, based on the items you need and the various different resources that you need to collect, okay? So even Minecraft is quite linear in how it actually guides you through the game as well.

Now, something we also need to keep in mind is landmarks, okay? Your players want to explore your world so the placement of important landmarks is quite important, okay? For example, let’s look at Skyrim. As you can see, I have highlighted all the major cities in Skyrim and these can be considered landmarks, okay?

When you’re exploring the world, you are either going in between these landmarks or you are going to different places that are very close by, okay? Because in Skyrim, these landmarks are important. They are where you get a lot of requests from. That’s where you can sell your stuff. That’s where you can buy stuff. There’s lots of important things at these landmarks.

Now, look what happens when I draw a line between each of these landmarks, okay? For a plane navigating between these landmarks, they pretty much cover the entirety of the map. And there are no areas where they may potentially miss, okay?

There’s no blank area, for example, if we got rid of rift in, that entire bottom right corner of the map would not really serve much of a purpose since there’s no reason for the player to go down there. But the fact that there is a city down there, means that the player traveling in the area has a reason to go down there, okay?

Let’s look at some other examples. We have GTA V, which has its three main landmarks going pretty much vertically. Again, you can think if the town at the top of the map was gone, then what purpose would there be for a player to explore up there? They wouldn’t really be anything. So having these landmarks spread across the entire map gives the player a reason to explore and go around, okay?

Same with Red Dead Redemption 2. You can see, we have all our towns and cities spread across the map so that the player has a reason to explore over there.

Some other examples. We have Breath of the Wild and Oblivion. The Elder Scrolls games are pretty much great at doing this. As you can see, it’s the same scarring that’s spread evenly across the map. Same with Breath of the Wild.

And now not so good example is The Witcher 3, okay? The Witcher 3 on its main map, it has its three major landmarks, the two cities and the town, which are all at the top half of the map. Now, if you’ve played the game, you of course are familiar with these places and the top of the map. But I don’t reckon you’ve really explored much of the bottom half, okay? Especially at the bottom left corner of the map.

Not many people really go down there. And that is because there’s no major landmarks to actually find down there. There’s no major places to go to, to sell your stuff, to buy your stuff. It’s rather quite barren. So, next up, we need to be looking at barriers.

Now barriers are important to promote games as they can also help guiding your player through your open world. So, first of all, there are two types of barriers. You have solid barriers. And these are rigid obstacles which the player must follow or avoid. And then we have soft barriers. And these are used to guide the player, yet can be ignored, okay?

The player can choose to go through them, go over them. They’re just there to lightly guide the player along a certain path. So first of all, solid barriers. The most obvious example would be in racing games where we have a strict path that we have to follow. And we have barriers on other side, basically stopping us from, you know, going off the map and driving wherever we want.

As well in games with castles. Castles have specific entry points and exit points that the player must sort of go through in order to enter and exit the castle, as well as pretty much any wall in any game, it’s there to guide the player around it to a specific entrance.

Now what about soft barriers? Well, soft barriers, for example, in Skyrim over here we have a path that goes up straight head, yet to the left, we have a sort of overhang. Now this overhang is there to basically guide the player along the path and stop them from, you know, going off into the forest, but it’s not strict, okay? We can choose to get over it and explore that way if we wish, but it’s just there to subtly guide us along this road here so that we stay on track.

And Subnautica is a game set in the water, where you are a scuba diver and this also has soft barriers. But it’s soft barriers are a bit more abstract. And that is actually the depth of the ocean, okay?

Progression through the game is basically how deep you can get. You know, when you level up your oxygen tank, when you level up your submarines, you can go deeper and deeper. Yet at the start of the game, you can only go so deep as your oxygen will run out. So that is a soft barrier. It is the depth of the ocean preventing you from going deeper and deeper until you get better equipment.

And just like in video games, there are solid and soft barriers all throughout the real world. Solid barriers are pretty obvious. Things like walls, things like gates. These are things that we can’t go past yet are there in order to guide us around them.

And soft barriers in the real world are everywhere as well, okay? We have a sort of there’s velvet ropes that we can technically go over, but we choose not to, as they are there to guide us along a certain path.

Wet floor signs. Most of the time when you see wet floor sign, you’ll either be careful or try and go around it. These things we don’t have to stick to their specific rules but they are there in order to guide us along a certain path, just like in video games.

So, thank you for watching. And that was just a bit on how we can look at progression through open world level design, okay?

As it is a very important factor in guiding your players through your open world, as what you don’t really want to do is have an aimless open world, okay? You don’t want to have an open world where the player has 100% total freedom as although that may seem as a good selling point, it won’t give the player any reason to do anything, okay? So thank you for watching.

Interested in continuing?  Check out our all-access plan which includes 250+ courses, guided curriculums, new courses monthly, access to expert course mentors, and more!

]]>
Free Course – Create a Day-Night Cycle in Unity https://gamedevacademy.org/day-night-cycle-unity-tutorial/ Wed, 24 Mar 2021 01:00:25 +0000 https://coding.degree/?p=1083 Read more]]>

Learn to mimic the passage of time for your Unity games in this day-night cycle tutorial. You can also explore how to utilize this day-night cycle for survival games by exploring the full course linked below!

Survival Game Player Mechanics for Beginners

About

This Unity tutorial, taught by Unity developer Daniel Buckley, will provide you with all the skills you’ll need to cycle through atmospheric changes to create the illusion of day and night. You’ll master techniques for not only adjusting lighting based on the time of day, but also how to move the sun and moon to create an immersive experience. Regardless of what type of game you’re making, these systems can be expanded and used for many different applications – providing you with numerous ways to enhance your game projects!

]]>
Game Design: Making Intuitive Tutorials for your Games https://gamedevacademy.org/game-tutorials-guide/ Fri, 29 Jan 2021 01:00:52 +0000 https://gamedevacademy.org/?p=13406 Read more]]>

You can access the full course here: Intro to Game Design

Creating In-Game Tutorials

In creating our games, we always need to keep in mind how we’re going to teach the player the mechanics of the game. How are we going to teach them how to control the player, how to engage with the game’s systems, and what the story of the game is?

Probably the easiest way of teaching the player is through Text Tutorials.

Text Tutorials

These are pop-up text boxes (as shown below from The Witcher 3) that tell you what to do, which is the easiest way of teaching the player but also the worst in the sense that it can take you out of the experience. It takes away all of the amazing opportunities you have to add in tutorials based on the design of your levels and how intuitive they are.

Screenshot of The Witcher 3 showing one of the many text tutorials
The Witcher 3: Wild Hunt © CD Projekt Red

When to Use Them?

Text boxes should be used in games with complex mechanics, e.g. strategy games. In strategy games, such as Crusader King’s 3, it’s generally not easy to intuitively figure out game mechanics without text instructions.

Screenshot of Crusader Kings III showing a text pop-up for the tutorial
Crusader Kings III © Paradox Interactive

To teach through the level design and the mechanics themselves being intuitive, we need to stick to this Three-step process.

3 Step Process

Card showing the first step of the 3-step process for making tutorials

In the first step, we introduce the mechanic to the player in a safe environment. The player should not be in danger, and there are no other distractions present. If it’s something like an enemy, we’ll see the enemy and preview what the enemy is going to do in a scripted encounter.

Cards showing the first two steps of the 3-step process for making tutorials

The next step of the process is to allow the player to use the mechanic in a real situation. The player should now be able to interact with the mechanic as they would normally. There may be a danger now where they can be damaged.

Cards showing the 3-step process for making tutorials

And the third step is to combine the mechanic with others. This allows the player to further understand the emergent systems of your game. If your game is quite emergent with various turn systems that can interact with each other, then this is a great step to add as it can further reinforce both the new mechanic and the old mechanic that is now interacting.

Example: Half-Life 2

Half-Life 2 is a great example of teaching the player through the game’s design. The only time text appears on screen is telling you what buttons to press to move, jump, and shoot. Apart from that, all of the game’s emergent systems are taught to you through the levels themselves, and through actually interacting with them.

The enemy called Barnacle hangs from ceilings and pulls up anything that touches it. So how is this taught to us in the game?

The first time the barnacle appears in the game is when it is displayed to the player through a scripted encounter. A bird flies into the barnacle’s tentacle, which then sucks it up. So in this case, the player is not in danger at all when they learn about the danger of barnacles.

Screenshot of Half-Life 2 with barnacle on the ceiling
Half-Life 2 © Valve

Not too long after this moment, we have the third step, which has a large number of barnacles that the player cannot cross nor shoot, so their only choice is to pick up explosive barrels and throw them into the barnacles. Then the player will see the barnacle eating this explosive barrel and killing all of the other barnacles around it. The player now has a more refined knowledge of these two systems.

Screenshot of Half-Life 2 with barrel and barnacle mechanic demonstrated
Half-Life 2 © Valve

So this is how Half-Life 2 uses this three-step process in teaching us a mechanic without necessarily having a text box appear and listing out exactly what it does. Whilst they could’ve explained that in a text box, the level is set up in a way so that the player has to be the one engaging with the mechanic to learn it, thus magnifying the experience of discovering it by the player themselves.

3-stop process cards compared to the screenshots used for Half-Life 2
Half-Life 2 © Valve

Challenge!

  • Think of a game you’ve played recently.
  • How were the game’s systems and mechanics taught to you?
  • What improvements would you make to the tutorial?

As a bit of a challenge, go ahead and think of a game you’ve played recently, and then think about how the game’s systems and mechanics were taught to you.

Want to Learn More?

If you want to learn more, you can look into the video by Game Maker’s Toolkit on how a similar process is done in Super Mario 3D Worlds. And if you haven’t played Half-Life 2 already, we highly recommend it as the entire game is filled to the brim with great game design decisions.

[Video] Super Mario 3D World’s 4 Step Level Design by Game Maker’s Toolkit

 

Transcript

In creating our games, we always need to keep in mind how we are going to teach the player the mechanics of the game okay? How are we gonna teach them how to control the player, how are we gonna teach them how to engage with the game systems and what the story of the game is. Well, this can be done for a number of different methods.

Probably the most easiest method of this is through text tutorials okay? These are pop-up text boxes that tell you what to do. Now, this is the easiest way of teaching the player but it’s also probably the worst in the sense that it can take you out of the experience and it takes away all the amazing opportunities you have to add in tutorials based on the design of your levels and how intuitive they are okay?

Now with text tutorials there are cases where they should be used for example, in strategy games. It’s normally not that easy to intuitively figure out strategy game mechanics, so in those cases, then they are probably needed as well as more complex game mechanics that can not be taught for the level of design.

But what do I mean about teaching through the level design and the mechanics themselves being intuitive? Well, there is a three-step process and many games follow this three-step process. If you’ve ever played a game where a mechanic is introduced to you, then there is a chance that this is what has happened okay?

So first step we teach the player the mechanic in a safe environment, okay? The player is not in danger and there are no other distractions present. Normally if it’s something like an enemy we’ll see the enemy and we’ll actually be able to preview what the enemy is gonna do in a scripted encounter. So maybe another NPC will go out and the enemy will defeat them in a certain way so that we then know, okay, this is how the enemy functions, let’s go in and use that knowledge against them.

The next step of the process is allow the player to use the mechanic in a real situation, and the player is now able to interact with the mechanic as they would normally okay? So there is that danger now where they can be damaged or they will be affected by it, but hopefully in the previous step they now have informed themselves on what this mechanic is and how it can be used.

And the third step is to combine the mechanic with others and this allows the player to further understand the emergent systems of your game. If your game is quite emergent with various turn systems that can interact with each other then this is a great step to add as it can further reinforce both the new mechanic and the old mechanic that is now interacting.

So, let’s look at Half-Life 2 because Half-Life 2 is a great example of both game design and teaching the player for the game design itself okay? If you’ve ever played Half-Life 2 before you’ll notice that the only time text appears on screen is telling you what buttons depressed to move, to jump and to shoot. Apart from that, all of the games emergent systems are taught to you through the levels themselves and through actually interacting with them.

So let’s look at the Half-Life 2 barnacle enemy, okay? This enemy hangs from ceilings and pulls up anything that touches it. So how is this taught to us in game? The first time the barnacle appears in the game its mechanic is displayed to the player through a scripted encounter. A bird actually flies into the barnacles tentacle which then sucks it up. So in this case, the player is not in danger at all, they see this and they then realize, okay, if an object or a person interacts with the barnacle it will begin to suck them up.

So the player now has this knowledge. So the next time they interact with the barnacle it is now in a situation where they can choose to either avoid the barnacle or go ahead and try and shoot it down okay? And there is that danger of them being grabbed. And then later on, not too long after this moment we have the third step, which has a large amount of barnacles that the player can not cross and cannot shoot.

So their only choice is to actually pick up these explosive barrels and throw them into the barnacles. And what the player finds out then is that when the barnacle basically eats this explosive barrel it explodes killing all of the other barnacles around it okay? So the player now has a much more refined knowledge of these two systems okay? He knows the barnacle can pick up any object and it will eat it, so it’ll interact with it and the play also knows that, okay, these explosive barrels can be used against these barnacles.

So this is how Half-Life 2 uses this three-step process in actually teaching us a mechanic without necessarily having a text box appear and listing out exactly what it does okay? It could have done that, it could have said, “Okay, this is the barnacle, “it sucks things up when it touches the tentacle. “If you throw an explosive barrel in it, “it’ll also explode”. Now they could have done that and it might’ve been easier for the player to notice that at the start but at the same time, it doesn’t give that player the experience of discovering it by themselves. The level is set up in a way so that the player has to be the one engaging with the mechanic in order to learn it okay?

So the three-step process, again we have the first step, which is teach the player the mechanic in a safe environment, like we have here. We then allow the player to use the mechanic in a real situation and we then combine the mechanic with others okay? Further reinforcing the emergent systems of their game.

As a bit of a challenge, I want you to think of a game you’ve played recently and then think to yourself how was the game’s systems and mechanics taught to you, okay? There is obviously mechanics in games and systems that you learned, how did you learn those? And what improvements would you make to the tutorial okay? Would you remove the text and somehow integrate a much more Half-Life 2 style of teaching, where it has a three-step process of teaching you in a safe environment, then teaching you the mechanic in a normal environment, and then teaching you how to combine different systems together okay?

So if you wanna learn more, there’s a great video by Game Maker’s Toolkit on how a similar process is done in Super Mario 3D Worlds and if you haven’t played Half-Life 2 already I highly recommend it as the entire game is filled to the brim with great game design decisions, it’s an immersive experience, and it has many moments where it teaches the player new mechanics, just like it done with the barnacle okay? So it’s a great game to analyze and to further reinforce your game design principles. Thank you for watching.

Interested in continuing?  Check out our all-access plan which includes 250+ courses, guided curriculums, new courses monthly, access to expert course mentors, and more!

]]>