Skip to content

Skinning structure

Dean Herbert edited this page May 31, 2021 · 7 revisions

This page attempts to detail the various intricacies of the skinning system internals, including how fallback, transformer and legacy provider logic intertwines.

Classes

LegacySkinTransformer

The legacy transformer classes exist to change the behaviour of skin lookups based on legacy skin configuration or special cases. This is for cases where we don't want to include the legacy logic within the drawable gameplay implementations themselves.

Note that this exclusively exists to allow for per-ruleset logic. Anything which is not specific to a ruleset should instead exist in LegacySkin itself.

SkinProvidingContainer

These containers take in a skin to use as a primary choice, but also fallback to parent ISkinSources using dependency injection. They are used to allow the general flow where skin elements can be provided by (in order of precedence):

  • The beatmap (user toggleable)
  • The user's skin
  • A default implementation (classic or otherwise)

These containers are re-exposes via DI so gameplay / HUD elements sees them as their ISkinSource, after which they will handle any parent lookups.

BeatmapSkinProvidingContainer

A special SkinProvidingContainer which handles the user toggleability of beatmap skinning.

LegacySkin

This is a skin implementation which handles osu-stable skins (generally packaged as .osk files). Logic within this class should be limited to parsing legacy config and deciding whether or not to provide a legacy implementation for a lookup.

Handling legacy fallback lookups

An example case of interest is the osu! HitCircle. The OsuLegacySkinTransformer decides whether a legacy version should be provided, querying for the existence of the hitcircle texture. The transformer's GetTexture lookup is running against the full source hierarchy, meaning it will find a match (because a default needs to be provided eventually).

So it probably doesn't need to check in the first place. Oops.

Lookup for skinning a LegacyMainCirclePiece:

  • Does the BeatmapLegacySkin provide a hitcircle texture?

If so, the LegacyMainCirclePiece should get all resources from the BeatmapLegacySkin, falling back to the DefaultLegacySkin for any missing resources.

  • Does the user have a LegacySkin selected?

If so, the LegacyMainCirclePiece should get all resources from the LegacySkin, falling back to the DefaultLegacySkin for any missing resources.