Skip to content

Text Boxes

Kinsey Dodd edited this page Sep 14, 2026 · 4 revisions

Text Boxes

Introduction

This is the wiki for the text boxes and everything related to displaying text on screen.

Text boxes are configured entirely through JSON files (TextConfig) and built by a factory (TextBoxFactory). The box itself is a single component (TextBoxComponent) that handles typing out text, paging through multiple screens of dialogue, and rendering a scroll-styled background.

Debug/Testing Commands

Load up the game, press the key to open the terminal (should be F1), then type:

  • textbox — loads configs/textBoxes.json via TextBoxFactory and displays it

TextConfig

TextConfig (com.csse3200.game.entities.configs) is a plain data class deserialised straight from a JSON file via FileLoader.readClass(TextConfig.class, filePath).

Fields

Field Type Default Notes
xPos int 100 Box x position
yPos int 100 Box y position
textColour String "Color.BLACK" Name of a Color constant, e.g. "Color.WHITE" or "WHITE"
backgroundColour String "Color.TAN" Same format as textColour
borderColour String "Color.BROWN" Same format as textColour
charsPerSecond float 30f Typewriter reveal speed
maxWidth int 200 Wrap width of the text
padding int 16 Padding around the text inside the box
borderThickness int 3 Also scales the scroll's roller/edge thickness (see below)
fontPath String "fonts/Pixeloidsans" Path to a bitmap font (.fnt), relative to assets.
textAlignment String "center" "left", "center"/"centre", or "right"
pages List<String> ["Test text"] One or more pages of text, shown in order (see Paging, below)

Colours are stored as strings (not Color) because plain JSON strings can't be deserialised directly into a Color object. TextConfig resolves them itself via reflection against Color's public static fields, with getters: getTextColour(), getBackgroundColour(), getBorderColour(), and getTextAlignment() (resolves to a com.badlogic.gdx.utils.Align constant).

Example JSON

{
  "xPos": 100,
  "yPos": 100,
  "textColour": "Color.BLACK",
  "backgroundColour": "Color.TAN",
  "borderColour": "Color.BROWN",
  "charsPerSecond": 30,
  "maxWidth": 200,
  "padding": 16,
  "borderThickness": 3,
  "fontPath": "fonts/scroll.fnt",
  "textAlignment": "left",
  "pages": [
    "First page of dialogue...",
    "Second page of dialogue...",
    "Third and final page."
  ]
}

TextBoxFactory

TextBoxFactory (com.csse3200.game.entities.factories) loads a TextConfig from a given file path and builds a TextBoxComponent from it.

public void createTextBox(String filePath) {
  TextConfig textConfig = FileLoader.readClass(TextConfig.class, filePath);
  if (textConfig == null) {
    // logs an error and returns rather than crashing
    return;
  }
  new TextBoxComponent(
          textConfig.xPos,
          textConfig.yPos,
          textConfig.getTextColour(),
          textConfig.getBackgroundColour(),
          textConfig.getBorderColour(),
          textConfig.charsPerSecond,
          textConfig.maxWidth,
          textConfig.padding,
          textConfig.borderThickness,
          textConfig.loadFont(),
          textConfig.getTextAlignment(),
          textConfig.pages)
      .create();
}

Each call loads the config fresh from the given filePath, so different calls can point at different JSON files.


TextBoxComponent

TextBoxComponent (com.csse3200.game.components) extends UIComponent; TextBoxComponent owns everything from config to rendering.

It can be built directly via its constructor, but the normal path is via TextBoxFactory + a JSON file, as above.

Paging

A box can hold multiple pages of text (List<String> pages), typed out one at a time:

  • The box types out pages[0] first.
  • Pressing TAB while a page is still typing instantly reveals the rest of that page.
  • Pressing TAB again once a page is fully revealed moves on to the next page (retyping from scratch).
  • Pressing TAB on the last page (once fully revealed) dismisses the box entirely.

Scroll visuals

The box background is generated procedurally (via Pixmap, no image assets needed) to look like an unrolled scroll:

  • A parchment-coloured centre (backgroundColour) that stretches to fit the text.
  • Rounded knobs at the corners where the rollers "poke out" past the paper.

borderThickness scales the roller and paper-edge sizing, a larger value gives a chunkier looking scroll. The default palette (Color.TAN background, Color.BROWN border, Color.BLACK text) is tuned to look right without any extra configuration.

Position anchoring

table.setPosition(x, y, Align.top) is now used to position the box, rather than the default bottom-left anchor. Confirm this matches where you expect the box to appear relative to xPos/yPos — this was a recent change and worth a sanity check on screen.

Custom fonts

Set fontPath to load a bitmap font (.fnt + its texture) instead of the skin's default font.

To generate a .fnt from a .ttf, use a tool like Hiero (bundled with LibGDX). Direct .ttf loading via gdx-freetype is possible as a future extension but isn't wired up yet.

Text alignment

textAlignment in the config ("left" / "center" / "right") controls the label's horizontal text alignment, replacing the old hardcoded centre alignment.

Text colour

Text colour is set once via the config (textColour) or constructor and applied at creation time. To change the colour, edit the JSON (or the constructor args) and recreate the box.


TypewriterEffect

Superseded by the reveal logic now built directly into TextBoxComponent (driven by charsPerSecond). The standalone TypewriterEffect class is legacy code and is still needed as a dependecy for the game end screen back end, for the time being.

Testing

  • See TextBox-TestPlan.md for the full test plan, including the manual/integration cases (typewriter reveal, TAB paging, dismissal, visual scroll/font/alignment checks) that need the game actually running, plus known issues found while writing it.

Clone this wiki locally