Skip to main content

Getting started

This page takes you from an empty place to a tutorial that runs. Nothing here assumes you have used the kit before.

What you are installing

TutorialKit is a client-side module plus a small server module. It ships its own copies of janitor and ezvisualz inside itself, so installing it cannot disturb the packages your game already uses, and it carries its own RemoteEvent, so it needs no slot in your networking layer.

Step 1 — add the Wally dependency

The recommended way to install is Wally. Add this line to your game's wally.toml:

TutorialKit = "kartzrbx/tutorial-kit@0.1.0"

Then install:

wally install

Package page: wally.run/package/kartzrbx/tutorial-kit

Pin the version

Use @0.1.0 while learning, then bump deliberately when you read the changelog. @^0.1.0 is fine once you trust semver on this package.

Step 2 — map it in Rojo

Wally creates Packages/TutorialKit.lua, a shim that points at the installed copy (including its vendored Packages child). Map that shim in your default.project.json:

"TutorialKit": {
"$path": "Packages/TutorialKit.lua"
}

Place it wherever your other Wally packages live. In most games that is under ReplicatedStorage.Packages:

"ReplicatedStorage": {
"$className": "ReplicatedStorage",
"Packages": {
"$className": "Folder",
"TutorialKit": {
"$path": "Packages/TutorialKit.lua"
}
}
}

After syncing you should see:

ReplicatedStorage
└── Packages
└── TutorialKit (ModuleScript — the Wally shim)
└── (via _Index) src, Server, Packages, …

The kit resolves its own janitor and ezvisualz from the Packages folder inside the installed module. You do not need to add those to your game's wally.toml.

Step 3 — require it

On the client:

const TutorialKit = require(ReplicatedStorage.Packages.TutorialKit)

On the server, require the server module directly:

const TutorialServer = require(ReplicatedStorage.Packages.TutorialKit.Server)
caution

Never require the main facade from a server script. It pulls the spotlight, the pointer and ezvisualz, none of which belong on a server. The separate entry point is what keeps that from happening by accident.

Adjust the path if your Rojo tree mounts TutorialKit somewhere other than ReplicatedStorage.Packages.

Step 4 — the smallest tutorial that works

Put this in a LocalScript. It highlights one button and ends when the player clicks it.

const ReplicatedStorage = game:GetService("ReplicatedStorage")
const Players = game:GetService("Players")

const TutorialKit = require(ReplicatedStorage.Packages.TutorialKit)
const Tutorial, Step, FocusUI = TutorialKit.Tutorial, TutorialKit.Step, TutorialKit.FocusUI

const playerGui = Players.LocalPlayer:WaitForChild("PlayerGui")
const shopButton = playerGui:WaitForChild("HUD"):WaitForChild("ShopButton")

const tutorial = Tutorial.build({
Step.new(1, {
FocusUI.to(shopButton, { Advance = true }),
}),
})

tutorial:Start()

Run it. The screen dims except for the shop button, and clicking the button clears everything.

If nothing happens, jump to Troubleshooting.

What just happened

Four things, in order:

  1. Step.new(1, {...}) built a piece of data. Nothing ran.
  2. Tutorial.build({...}) sorted the steps and created the shared spotlight, pointer and camera. Still nothing ran.
  3. tutorial:Start() entered step 1 and called each of its actions.
  4. FocusUI.to dimmed the screen and connected to the button. Advance = true told it to end the step on click.

Because that was the last step, ending it completed the tutorial and cleared the overlay.

Alternative — git submodule

If you prefer vendoring the source instead of Wally:

git submodule add https://github.com/KartzRbx/TutorialKit lib/tutorial-kit
"TutorialKit": {
"$path": "lib/tutorial-kit/src",
"Packages": { "$path": "lib/tutorial-kit/packages.project.json" }
}
const TutorialKit = require(ReplicatedStorage.TutorialKit)

The submodule path skips Wally but you must keep the Packages child mapping, or the kit errors on first require.

Where to go next