Start typing to search packages!
tutorial
By @dontmineatnight
Roblox
MirroredTutorial
A small, client-side onboarding package for Roblox experiences.
Tutorial presents guidance around UI and world targets while leaving tutorial content, input, game actions, and progression to the calling experience. It provides:
- Spotlight guidance: a screen-space focus, tap indicator, and off-screen arrow for UI or world targets.
- Cinematic guidance: an animated focused hole or letterbox overlay.
- 3D guidance: optional highlights, beams, and world markers.
Tutorial does not render toast content, capture input, disable movement, or advance steps based on gameplay actions.
Installation
Add Tutorial to a Wally project:
[dependencies]
Tutorial = "dontmineatnight/tutorial@0.4.1"
Then require it from the installed package:
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Tutorial = require(ReplicatedStorage.Packages.Tutorial)
Quick start
local Players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Tutorial = require(ReplicatedStorage.Packages.Tutorial)
local playerGui = Players.LocalPlayer:WaitForChild("PlayerGui")
local tutorial = Tutorial.new({
steps = {
{
id = "open-inventory",
title = "Open your inventory",
description = "Select the inventory button to continue.",
presentation = {
screenTarget = function()
local button = playerGui:FindFirstChild("InventoryButton", true)
if button and button:IsA("GuiObject") then
return button
end
return nil
end,
screenMode = "focusAndTap",
inputHints = {
keyboard = "Press I",
gamepad = "Press the inventory button",
touch = "Tap the inventory button",
},
},
},
},
onStepChanged = function(step, _, _, target)
-- Render step.title, step.description, and target in your own UI.
end,
onComplete = function()
-- Remove the experience's instruction UI.
end,
})
tutorial:start()
-- After the experience has confirmed the action:
-- tutorial:complete()
Use functions for targets that can be created, replaced, or moved while a step is active. Tutorial evaluates those functions during presentation updates and treats invalid or unavailable targets as absent.
Client API
Create a controller with Tutorial.new(options).
| Option | Description |
|---|---|
steps | Required ordered list of step inputs. |
presentation | A Tutorial.Presentation instance, or false to render nothing. |
presentationOptions | Options used to create the default presentation. |
startStepId | Optional initial step ID. |
onStepChanged | Receives (step, index, count, screenTarget). |
onStop | Runs when an active tutorial is stopped or destroyed. |
onComplete | Receives the last active step. |
Controller methods:
start(stepId?)starts the current or named step.stop()hides guidance without completing the tutorial.setStep(stepId)shows a named step.advance()moves to the next step, completing at the end.skip()completes the tutorial locally.complete()hides guidance and invokesonComplete.destroy()disconnects the controller and destroys owned presentation.refresh()updates dynamic targets immediately.getCurrentStep()returns(step, index)while running.isRunning()andisCompleted()expose controller state.getPresentation()returns the presentation when one is enabled.
A presentation provides show, hide, refresh, getScreenTarget, and
destroy. The screenTarget passed to onStepChanged is the target resolved
when that step was shown; call getScreenTarget() after refresh() for the
current target.
A controller owns the default presentation created from presentationOptions.
If an existing presentation is supplied, the caller owns it; controller
destruction hides it but does not destroy it.
advance, skip, and complete are local operations. For a
server-authoritative tutorial, let the experience call setStep or
complete only after its own server confirmation.
Step presentation
Tutorial passes title, description, and inputHints to the experience but
only uses target fields for visual presentation.
presentation = {
screenTarget = GuiObject or function() -> GuiObject?,
screenMode = "focus" | "tap" | "focusAndTap" | "letterbox" | "none",
worldTarget = BasePart | Model | Vector3 or function() -> target?,
worldOrigin = BasePart | Model | Vector3 or function() -> origin?,
worldMode = "beam" | "highlight" | "marker" | "all" | "none",
inputHints = {
keyboard = "...",
gamepad = "...",
touch = "...",
},
}
If screenTarget is omitted and worldTarget is supplied, spotlight guidance
projects the world target into screen space. It follows the target and shows an
edge arrow while the target is outside the viewport.
screenMode = "letterbox" shows the screen presentation's top and bottom bars
and does not require a target. The bar fraction and dim transparency are
configured with ScreenGuidanceOptions.
World presentation can use a BillboardGui or Model as markerTemplate. For
model markers, markerOrientation, markerDistance, and markerTargetOffset
control placement and orientation. markerTargetPadding reserves space from
the target when markerDistance or markerOrientation is also supplied.
Reusing visual assets
Templates are optional and are cloned by Tutorial:
local presentation = Tutorial.Presentation.new({
screen = {
focusTemplate = ReplicatedStorage.Assets.TutorialFocus,
tapTemplate = ReplicatedStorage.Assets.TutorialTap,
edgeArrowTemplate = ReplicatedStorage.Assets.TutorialArrow,
},
world = {
beamTemplate = ReplicatedStorage.Assets.TutorialBeam,
highlightTemplate = ReplicatedStorage.Assets.TutorialHighlight,
markerTemplate = ReplicatedStorage.Assets.TutorialMarker,
},
})
Templates provide the visual contents and structure. Tutorial owns the
presentation properties needed to place, animate, and control the clones. For
example, screen templates receive Tutorial's position, size, anchor, z-index,
and input settings; BillboardGui markers receive Tutorial's size, offset,
AlwaysOnTop, and enabled state; and Highlights receive Tutorial's adornee,
depth, colors, transparencies, and enabled state. The original template
instances are never modified.
Cinematic overlay
Tutorial.CinematicOverlay is a separate shared overlay for explicit
cinematic transitions:
local overlay = Tutorial.CinematicOverlay
overlay.ShowLetterbox({
barFraction = 0.12,
transparency = 0.35,
})
overlay.Focus(targetGui, {
scaleFactor = 1,
transparency = 0.35,
})
overlay.Hide()
overlay.Destroy()
Focus follows a target while it remains in the local player's PlayerGui and
its rendered ancestors remain visible. ShowLetterbox creates animated top
and bottom bars. Both transitions use short Sine/InOut animations; their render
connections and completed tweens are released automatically. Call Destroy
when the experience no longer needs the shared overlay.
License
MIT
Package Details
Install command (Click to copy)
Version
0.4.3
License
MIT
Safe for commercial use
Automated license review — not legal advice.
