Tutorial - UQcsse3200/2026-studio-2 GitHub Wiki
# Overview
The movement tutorial is a command-only, in-level overlay. It shows a bottom-left textbox beside the inventory hotbar and advances when the player presses the correct raw keys: A + D, then SPACE, then SHIFT. It never blocks movement — the player can walk, jump, fall, or die throughout.
- Trigger: terminal (F1) → tutorial [config]
- Steps: A and D (both, any order) → SPACE (jump) → SHIFT (dash/sprint)
- SHIFT counts as dash because sprint() triggers dash() in PlayerActions
- Re-running tutorial restarts it (old box is disposed first)
| Piece | File | Role |
|---|---|---|
TutorialCommand |
ui/terminal/commands/TutorialCommand.java |
Loads a TextConfig, builds the textbox, attaches the observer. Registered as "tutorial" in Terminal |
TutorialComponent |
components/TutorialComponent.java |
InputComponent at priority 6 (above player 5). Snoops keyDown, latches seenA/seenD, advances the box. Always returns false so the player still gets every key |
tutorial.json |
assets/configs/tutorial.json |
TextConfig with position, style, and 3 pages |
TextBoxComponent |
components/TextBoxComponent.java |
Rendered with externallyControlled=true (TAB disabled); driven only via revealCurrentPage() + advance() |
Flow per step: keyDown matches → revealCurrentPage() (finish typing instantly) → advance() (next page) → step++.
Final step: advance() → dismiss() → dispose() (unregisters input, removes box).
Guards: ignores keys while any terminal is open (Terminal.isAnyOpen()); single active instance; dispose() dismisses a leftover box.
Config format (configs/tutorial.json) Same shape as textBoxes.json (TextConfig):
{ "xPos": 20,
"yPos": 150,
"textColour": "Color.BLACK",
"backgroundColour": "Color.TAN",
"borderColour": "Color.BROWN",
"charsPerSecond": 30,
"maxWidth": 320,
"padding": 16,
"borderThickness": 3,
"fontPath": "flat-earth/skin/fonts/PixeloidSans.fnt",
"textAlignment": "left",
"pages": [ "Move around using A and D.", "Jump using SPACE.", "Dash using SHIFT." ] }
Positioning: the box is pinned with Align.bottomLeft at (xPos, yPos), so it sits bottom-left beside the centered hotbar (InventoryBarDisplay: bottom, padBottom(20)) and survives redraws/resizes. Only strict A/D count (not arrow keys) — extend TutorialComponent.keyDown if aliases are wanted.
Usage
- Open the terminal in-game (F1).
- Run tutorial (or tutorial configs/myTutorial.json).
- Press A, then D → page 2. Press SPACE → page 3. Press SHIFT → box dismisses, tutorial ends.
Adding steps
- Add a page to tutorial.json.
- Add a step case in TutorialComponent.keyDown (check the key, call advanceStep(); call finishTutorial() on the last step).
- Keep keyDown returning false and priority above the player handler, or the observer will starve (the input chain stops at the first true).
| Symptom | Cause / fix |
|---|---|
| Box never appears | Bad config path (FileLoader returns null → command returns false); check terminal log |
| Keys don't advance | Terminal still open; or another handler consumes keys before priority 6 |
| Player frozen during tutorial | Something else consumed input, the tutorial itself never blocks input |
| Box overlaps hotbar | Adjust xPos/yPos in tutorial.json |