Repository navigation
Mobile UI
What makes ClassicUO's mouse-and-keyboard interface playable with fingers,
and how the client decides which defaults a platform gets. Sources:
docs\ui\mobile_playability.md (the verified / written / missing table),
docs\ui\grid_container.md, src\Configuration\PlatformDefaults.cs, and the
commit messages of the work/ui chain, each of which names what was seen on
the device.
One table in Configuration\PlatformDefaults.cs holds every profile default
that differs by platform. Desktop has one set (version 5: a full-size world and wheel zoom); everything
else on the desktop is exactly upstream's. Mobile gets a full-size borderless world, pinch zoom kept, large
and scaled containers, grid containers, fitted container placement and the
low-power background. Web gets a full-size world and wheel zoom. The platform
comes from OS.HasFeature (mobile, web); UO_PROFILE_PLATFORM overrides
it on the desktop for checks.
Profile.ProfileVersion records which table a profile has seen. Each entry
in the table carries a since version. When a profile is loaded that is
below the current version (a new one, or one saved before an entry existed),
every field that still holds upstream's default takes the platform's
value; a field the player changed is kept. The player never has their own
choice overwritten.
| Version | Added |
|---|---|
| 1 | The table itself: window, zoom and container sizes for Mobile and Web. |
| 2 |
FitContainerPlacement on Mobile. |
| 3 |
GridContainers on Mobile. |
| 4 | The canvas background entry, taken by the background branch (see ADR-0016). |
| 5 | Desktop: the world fills the window and the wheel zooms, as on Mobile and Web, instead of upstream's 600x480 world in the corner of a large window. Unticking "Game window full size" under Options gives the smaller, movable world back. |
| 6 |
CanvasBackgroundLowPower on Mobile and Web (ADR-0016). |
Migration from 2 to 3 was verified on the device (commit "GridContainerGump: containers as a grid"), and to 6 by the canvas background work.
src\Input\Touch\TouchInput.cs translates Godot's screen touch, drag and
magnify events into the mouse events GodotInput already consumes, so the
ported game code sees a mouse. Off the touch layer, the desktop path is
unchanged; every hook into ported code is marked PORT DEVIATION (GUO).
| Gesture | Becomes |
|---|---|
| Tap | Left click |
| Second tap | The game's own double click |
| Hold on the world | Held right button: walk, then run |
| Hold on an item | Held left button: pick up, then drag |
| Long press | Right click |
| Pinch | Ctrl + wheel steps (zoom); accumulated from magnify gestures |
| Tap on the gump bar | The top-bar action |
Verified on the device: login by touch alone, hold-to-walk, pinch in and
out, drag, split and drop into the bank, double-tap use (commits "Android:
fullscreen, soft keyboard..." and "GridContainerGump..."). On the desktop,
launchers\dev\touch_probe.bat drives synthetic fingers through the layer
and checks 18 gestures against the shard; --touch enables the layer on the
desktop and --touch-trace logs each gesture decision.
TouchGumpBar.cs is a CanvasLayer overlay along the bottom, drawn with the
top bar's own button art and clilocs: six finger-sized actions. While a
target cursor is up it shows Self and Cancel so a spell or a bandage
can be aimed and a target can be abandoned without a keyboard (commit
"Touch bar: Self and Cancel while a target cursor is up").
A tap on a text field raises the soft keyboard and slides the field's root gump up by what the keyboard covers; the world gump is never moved. The account field asks for the e-mail keyboard and the password field for the password keyboard, the two types an IME must not autocorrect in.
GridContainerGump shows a container as a grid of finger-sized slots instead
of upstream's free-placed items. It is a new gump, not a ContainerGump
subclass: OpenContainer keeps upstream's classic path and then calls
GridContainerGump.ReplaceClassic, the one upstream hunk. The grid polls its
container's contents, saves as GumpType.Container so gumps.xml restores
it through the classic path, pages when it would exceed the screen height,
and has a filter field, a sort toggle and a Classic button. Slots call the
same GameActions as ItemGump.
Options, in the Containers section: "Open containers as a grid of slots"
(GridContainers), a slot size slider from 32 to 80 (GridContainerSlotSize,
default 44) and the fitted placement checkbox. Changing the slot size rebuilds
open grids. The grid takes as many columns (three to six) as fit half the
client width so two containers still sit side by side.
Upstream cascades containers from the top left, which puts the backpack on
the character. With FitContainerPlacement on, ContainerPlacement keeps a
remembered spot unless it covers the character, and otherwise picks the
right-most, top-most free spot inside the client area, below the top bar and
above the touch bar, covering the least of the character and the other open
gumps. Gumps restored from gumps.xml at login are moved off the character
the same way. Off on the desktop, and off whenever "override container
location" is set.
On a phone the touch layer sets the client's whole-number ScreenScale to
fit the display, dividing the OS scale out, without touching the global
setting. Options writes the screen zoom back only when its slider moved, so
pressing Apply for something else does not shrink the UI (commit "Options:
apply the screen zoom only when its slider moved").
docs\ui\mobile_playability.md keeps the table of every interaction a
player needs, marked verified, written or missing. Read it before claiming a
phone is playable; some rows have moved since it was written (target
cancelling is now on the touch bar, but the table still says missing).
Start
- Getting Started
- Configuration
- Launchers and Tools
- What is GUO?
- FAQ
- Known Issues
- Troubleshooting
- Glossary
Builds
Playing
- Servers and Accounts
- Controller
- Mobile UI
- Canvas Background
- Screen Effects
- Asset Store
- Dev Shard
- Server Compatibility
Developing
- Scripted Runs and Probes
- Parity and Drift
- Editor
- World Editing
- Manage Your Shard From the Editor
- Author UO Data
- Building Multis
- Architecture
- Working with AI Agents
- Contributing
Project