Skip to content
Arnaud Solé edited this page Nov 1, 2024 · 16 revisions

This section contains documentation regarding the new themes system included in SAOUI. Note that themes are in active development right now and things are subject to change. We'll try to update these pages as often as possible to reflect updates, and please share your suggestions (both regarding the content and the format of this page) in our Discord server.

As of writing this, the theme format version is INDEV. We will transition towards using Semantic Versioning as we get closer to releasable beta builds. Along with this we will include the minimum version number for new features.

Installing themes

Themes can be installed by adding a resource pack containing a theme : image

This will make the theme appear in the SAOUI options, where it can be enabled and disabled at will : image

TODO : update documentation with Screen-specific themes

Legacy themes

These refer to themes using the old format, which includes the HUD and very basic screens customization support, whose structure looks like this :

<pack root folder>
├── assets
│   └── saoui
│       ├── textures
│       │   ├── ascii.png
│       │   ├── entities.png
│       │   ├── gui.png
│       │   ├── icons.png
│       │   ├── logo.png
│       │   ├── particleLarge.png
│       │   └── slot.png
│       └── themes
│           ├── hud-schema.xsd
│           ├── hud.xml
│           └── style.css
├── pack.mcmeta
└── pack.png

The mod will try it's best to load legacy-format themes, however please understand that features and support may be limited and pack authors are advised to migrate as soon as possible (in line with the SAOUI release schedule...) to the new format described below. Please find help in our Discord server should you need it ! Each section should include a note specifying support in legacy themes.

Authoring themes

Table of Contents

Theme structure

Note : all folders and files should use only lowercase characters, numbers and underscores as is the case with any Minecraft resource pack (AFAIK)

The basic resource pack structure is the same as for vanilla resource packs :

<pack root folder>
├── assets
│   ├── saoui_hex_new_format
│   └── wip_test_theme
├── pack.mcmeta
└── pack.png

In assets/, you can have as many folders as you want. Each of these folders will be considered a separate theme namespace similar to a modid (if it contains themes). Namespaces can contain one or more themes using the following structure :

<namespace root>
├── lang (1)
│   └── en_us.lang
├── sounds (2)
├── sounds.json (2)
├── textures (3)
│   ├── alo
│   ├── ggo
│   ├── hex
│   ├── hex2
│   ├── os
│   ├── sao
│   ├── sao_json
└── themes (4)
    ├── alo
    ├── ggo
    ├── hex
    ├── hex2
    ├── os
    ├── sao
    └── sao_json

TODO: this structure needs to be updated (ie theme resources being under the theme root)

  1. lang/ contains translation files (just like regular resource packs). See here for theme-specific options.
  2. sounds/ contains custom sounds. Full theme-specific support for this is not yet implemented.
  3. textures/ contains custom texture files. Common practice and support for several customizations currently rely on using one folder per theme, using the theme's identifier. These theme-specific texture folders will later be referred to as the theme texture roots.
  4. themes/ contains one folder for each theme, with the name of the folder used as theme identifier. These folders will be referred to as theme roots and contain the main theme customization files like metadata and settings :
themes
├── alo
│   ├── hud.xml
│   └── style.css
├── ggo
│   ├── hud.xml
│   └── style.css
├── hex
│   ├── hud.xml
│   └── style.css
├── hex2
│   ├── hud.xml
│   ├── settings.json
│   └── style.css
├── os
│   ├── hud.xml
│   └── style.css
├── sao
│   ├── hud-schema.xsd
│   ├── hud.xml
│   └── style.css
└── sao_json
    ├── hud.json
    └── style.css

Legacy themes : the compatibility loader will load legacy themes using the resource pack file (or folder) name as namespace and the same name barring the potential ZIP extension as identifier. For example, the legacy saoui_hex.zip will be uniquely identified as saoui_hex.zip:saoui_hex. Note that this means the namespace will be different when working on a pack as a flat folder from when it is zipped up for sharing ! The theme texture root will be assets/saoui/textures and the theme root will be assets/saoui/themes.

Theme metadata

General theme metadata is yet to be developed. The plan is for it to include a few technical properties to help deliver quality themes :

  • theme version
  • theme format officially supported version(s)
  • potential SAOUI addons support (along with versions)
  • customization for the currently "expected paths" (see HUD and screens)

If you have other suggestions for metadata, please post them on our Discord server ;)

Legacy themes : this feature is unsupported for legacy themes

Theme localization

Currently, out of the box expected localization is for the theme's name and description. The following two translation keys are used by the base mod :

theme.<theme-namespace>.<theme-identifier>.name=User-friendly Theme Name
theme.<theme-namespace>.<theme-identifier>.description=User-friendly theme description

(if you need a refresher on theme namespace and identifier, please refer to the section on theme structure)

As an example, here's the current (as of writing this) theme-specific localization for the built-in themes :

mcui.theme.saoui.alo.name=ALO
mcui.theme.saoui.alo.description=Built-in theme inspired by ALfheim Online
mcui.theme.saoui.ggo.name=GGO
mcui.theme.saoui.ggo.description=Built-in theme inspired by GunGale Online by Blaez
mcui.theme.saoui.hex.name=Hex
mcui.theme.saoui.hex.description=Built-in dark theme using hexagonal geometry by Genetyx8
mcui.theme.saoui.hex2.name=[WIP] Hex2
mcui.theme.saoui.hex2.description=[WIP] Built-in experimental variant of the Hex theme using WIP features
mcui.theme.saoui.os.name=OS
mcui.theme.saoui.os.description=Built-in theme inspired by Ordinal Scale by Blaez
mcui.theme.saoui.sao.name=SAO
mcui.theme.saoui.sao.description=Built-in theme inspired by SAO (the original theme of the mod)
mcui.theme.saoui.sao_json.name=[WIP] SAO
mcui.theme.saoui.sao_json.description=[WIP] Built-in experimental variant of the SAO theme using JSON hud

Since they're built into the SAOUI mod, we defined all of them in the saoui namespace (which matches the modid). Each theme uses a recognizable acronym used to clearly distinguish theme-specific resources in the pack by their folder name. Note again that both have to be made up of lowercase characters, numbers and underscores.

Legacy themes : see the special compatibility handling of legacy themes in the structure section regarding namespace and identifier.

Theme settings

Themes can include custom settings, which will be stored in the user's config folder like mod-specific configuration files using the following structure :

saoui
├── friend_list.cfg
├── main.cfg
├── saoui
│   └── hex2.cfg
└── saoui_hex_new_format
    └── hex2.cfg

Each namespace will have it's own subfolder, and each theme has it's own configuration file using the theme identifier with .cfg extension. As you can see in the above example, duplicate identifiers are fine as long as the namespace is different. friend_list.cfg and main.cfg are the basic configuration files for the mod, independent of themes. The format of all these configuration files is the same as it is for Forge mods (which is the system used behind the scenes).

Currently the only use for settings is in the HUD but support is planned in the future screens customization.

Adding settings to your theme can be done by adding a settings.json file in your theme's root. The format of this file should be a JSON array with nested objects defined as such :

key: String
type: String
defaultValue: any
comment: String
  • key : resource location with format category:identifier. This key should be unique per theme. A theme cannot currently access settings defined by another theme
  • type : any of
    • string (currently unsupported in settings UI)
    • boolean
    • int (currently unsupported in settings UI)
    • double (currently unsupported in settings UI)
    • choice
    • resourceLocation (currently unsupported in settings UI)
  • defaultValue : the default value to use for this setting
  • comment : will be displayed to the user when hovering in the UI (TODO : localization), and as comment in the config

In addition to those, depending on the type of setting used some additional parameters are available. Until formal documentation is written, please refer to Setting.

[
  {
    "key": "hud:remove_hpxp",
    "type": "boolean",
    "defaultValue": false,
    "comment": "Whether to remove HP & XP from showing on the HUD"
  },
  {
    "key": "hud:vertical_hotbar",
    "type": "boolean",
    "defaultValue": true,
    "comment": "Whether to show a vertical hotbar (true = vertical, false = horizontal)"
  },
  {
    "key": "hud:health_offset_x",
    "type": "double",
    "defaultValue": 4.0,
    "min": 0.0,
    "comment": "Offset on the X axis for the health bar"
  },
  {
    "key": "hud:health_offset_y",
    "type": "double",
    "defaultValue": 4.0,
    "min": 0.0,
    "comment": "Offset on the y axis for the health bar"
  },
  {
    "key": "hud:hide_exp",
    "type": "boolean",
    "defaultValue": false,
    "comment": "Hide experience section of the HUD"
  },
  {
    "key": "hud:hide_hp",
    "type": "boolean",
    "defaultValue": false,
    "comment": "Hide health numbers section of the HUD"
  }
]

Usage

Settings can be used in the HUD miniscripts by using settings.<type>(key). For example : settings.double("hud:health_offset_x")

Legacy themes : this feature is unsupported for legacy themes (it might technically work, but is untested and therefore unsupported. If you are adding custom settings anyway, you might as well update your pack format 😉)

Theme HUD

Themes can define a custom HUD using a XML or JSON-formatted file. The file is expected in the theme root with the name hud.xml (XML format) or hud.json (JSON format). Please note that values in most fields can be expressed as lightweight scripts, regardless of the format you choose.

Legacy themes : both HUD formats are supported in legacy themes

XML Format

The XML format has documentation in the form of an XML validation schema which can be found here. This schema can be used for making tools more useful (by enabling smarter auto-completion and validation) as well as to find out what is available and get a short description for all the properties, fields, ...

JSON Format

The JSON format is currently undocumented 🙃 please look at the built-in themes to find out anything about it at this stage. This will be improved, along with making a tool available to automatically convert XML format HUDs to JSON format.

Theme screens

Screens customization is currently in very early work-in-progress. The current long-term idea would be to use heavyweight scripting to assemble elements to build screens, while using something similar to the HUD format to define individual elements (using higher-performance lightweight scripting).

Hardcoded paths

Update : hardcoded paths are deprecated and should not be used anymore as more advanced screen customization is in the works (but not yet documented). This will be fully released in an upcoming version.

Until we finish designing more advanced screens customization, some specific paths can be used to customize some screen elements. Any non-customized resource defined here will currently default to the SAO theme's equivalent. These include the following (relative to the theme texture root) :

  • ./gui.png used for menu root categories and player character sheet
  • ./slot.png used for the background of Icon+Label elements
  • ./entities.png used for the entity health bars and crystals
  • ./particlelarge.png used for the death particles
  • ./status_icons/*.png used for status icons (currently only for use in HUD), see the full list here
  • ./menu/icons/*.png used for the menu icons, see the full list here

Legacy themes : this feature is unsupported for legacy themes TODO: restore compatibility for hardcoded path customizations in existing legacy packs

Stylesheet

In addition to hardcoded paths, some customization can be done via a CSS-like file. This will probably get massively reworked (if not scrapped) with the new screen customization design, but in the meantime it is a simple enough way to tweak some colours. The best place to start would be the SAOUI theme's stylesheet, which includes some (hopefully helpful) comments. Note that unlike real CSS, each of the selectors is hardcoded to a specific use case 🙃.

Legacy themes : this feature is supported for legacy themes

Theme scripting

(TODO)

Miniscripts

High-performance scripting of values currently in use in the HUD, Fragments and Widgets. This includes support for using gameplay values, calculus, settings, ...

Informal documentation references :

  • IHudDrawContext : on the way to being deprecated in favour of more structured approach
  • DrawContext : replacement for IHudDrawContext
  • Static libs (TODO)

(TODO)

Heavyweight scripting

(TODO)

Tips for local development

You can add a resource pack as a flat (unzipped) directory, and edit any files you want. To view your changes in-game, you can reload resource packs (F3+T) and everything should behave (including reloading theme-specific settings file). If it doesn't, please report using GitHub Issues or our Discord server !

Warning, error and debug messages are being logged using the saoui logger, or a more specific logger in some cases. TODO: refine and document the different loggers in use

The long-term goal regarding these events is to provide a graphical overview with a list of warning/error events happening during theme loading.