Tutorial Design and Implementation for Games


Tutorials are an integral part of a game. It helps users understand the game and get on board easily. Basic steps like how to play, goals, powerups and settings need to be presented to the user in a clean and easy to understand manner.

There are 3 kind of tutorials

  1. Informational — Shows an information and will have an OK button(Eg. This is gold).
  2. Actionable — Forces user to do an action(Eg. Tap to Start Playing).
  3. Multi-step — Teach the user how to use something step by step(Eg Tap a cell and Tap a number to enter).

Usually tutorials are tightly coupled to the puzzle, this makes modularization of the tutorial code difficult.

If you look at the following 3 step tutorial, on step 1 the circle points to an empty cell, since we have random puzzles, we won’t be able to hard code the position.

Puzzle Screen Tutorial (also example of 3 tutorials chained — multi-step)
Map Screen with an Actionable tutorial

Also, at the map screen, we are pointing to the icon when we teach how to play a milestone(milestones are levels in this game). If the user pans the map, the position of the milestone will change, so hard coding the milestone position is not at all possible.

Here is our solution.

Tutorial Module Structure

Our tutorial module consists of 3 files. A model file, a view file and a data file. The Model file has all the logic for setting up a tutorial, starting, stopping and cancelling. The view displays the tutorial and has 3 parts, the background, an info section and an area to handle tap events. The data file is a json with all tutorial specifications(a set of rules on which tutorial should load when, tutorial type, positions if any etc..).

Even though the module we have created will work only with GameClosure, The same approach can be used in any language or framework.

To use this module in your GameClosure project, copy tutorial model, view and create a data file. Call tutorial.build() in the init function of the file where you want to show the tutorial. This will auto start tutorial if it meets the milestone condition. In case you want to show it independent of the milestone, you can use tutorial.add() and the module will handle everything else.

Tutorial data

Tutorials are auto triggered based on screen name and milestone. There can be multiple tutorials chained together, so tutorial list is an array. There is no need to hard-code positions, it automatically determines from the elements that are passed while building the tutorial. If the positions have to be adjusted, x and y values can also be passed.

A tutorial object can have the following data

  1. id —id of the tutorial.
  2. text — text to show in info box.
  3. ok — whether to show ok button(on the message area) or not. An ok button will be shown for tutorials which just have information. We can force the user to interact on the highlighted part of the tutorial by setting this as false.
  4. hideNext — if there is more than 1 tutorial for a particular condition, the tutorial module will automatically show the next button. Set this option to true to hide it.
  5. ms — set this to false if a tutorial is not related to any milestone, set this only if tutorial is going to be called manually.
  6. x and y — to adjust the position from the calculated value.

We also have tutorials independent of milestones. These need to defined directly in the root object. Here is an example. These need to be triggered manually.

https://gist.github.com/jishnu7/e492e592fc60de941ff2

Model

This model automatically handles chaining(tutorials can come one after the other — in cases of on-boarding), marking tutorial as completed and not showing it again, calculates position for the views, cancels a tutorial in case cancel function is called and disable input to other views while the tutorial is open.

Public functions in the model are

  1. build(opts) — This is the function which builds the tutorial object for the particular screen, or milestone. Look at the sample code below to see all the options that this function takes.
  2. cancel()— Cancel a tutorial that is about to start.
  3. add(id, force) — Add a tutorial to the queue using an id which is defined in tutorial data. Second parameter `force` is to forcefully start the tutorial immediately without waiting for the time limit. This function needs to be used if you want to start the tutorials manually.
https://gist.github.com/jishnu7/eb1843813e2bd4e12f73

View

For the view, we are using a 9-slice image, the circular region is not scaled and the rest are scaled to cover the entire screen.

The visible area in the picture is the screen. The 9 sliced view is scaled up to twice the base size of the screen. In scenarios where the element on which the tutorial has to be shown may not be in the center. This would lead to complex calculations for scaling as each slice might to be scaled differently. Scaling is done twice the screen size because this ensures no matter where the tutorial appears on screen, the tutorial view would cover the entire screen. The animation is also better.

There is an additional, hidden view in the at the circular part of the view to handle the user interactions. Action for the tap can be passed along with other options for building the tutorial.

The view part of the module can be further improved by moving view as a parameter for the tutorial build function. This will give more flexibility as a module.

Source code of this module is available along with other GameClosure helper functions: https://github.com/hashcube/DevkitHelper

See it in action. Download Sudoku Quest on iOS, Android and Kindle.