Traluno▶ Back to the layout

A Desk, Not a Menu

The controls that drive the layout are levers and switches on the front of the table, operated with the mouse. Putting them in the world instead of in the UI cost a lot and was worth it.

Every setting that changes how the layout runs — train speed, clock speed, which routes are live, whether the crossing gates are on automatic — could have been a slider in a panel. Panels are quick to build, easy to lay out, and legible at any resolution.

Instead there is a control desk along the front edge of the table, with real levers you drag and real switches you flip, and no panel at all.

Why

Because a model railway has one.

That is the whole justification and it is stronger than it sounds. The subject matter of this game is not "trains". It is "a model railway in a hobby room", and a model railway's controller is a physical object that sits on the baseboard where the operator stands. Replacing it with a menu would be modelling the trains and not the hobby.

There is a second reason that only became clear later. A lever has a position, and the position is visible from across the room. You can see at a glance that the clock is running fast because the lever is forward. A slider inside a panel you have closed communicates nothing at all when it is closed, which is most of the time.

What it cost

Hit testing. A button in a UI layer is a rectangle in screen space. A button on the desk is a small three-dimensional object seen at an angle, and clicking it means casting a ray from the cursor into the scene and finding what it hit. That machinery had to exist anyway for placing track, so this was cheaper than it might have been.

Drag semantics in three dimensions. A lever moves along an arc, and the mouse moves in a plane. Mapping one to the other so that dragging feels like pulling the lever — rather than like solving a geometry problem — took several attempts. The answer that worked is to project the cursor onto the plane the lever swings in and take the angle, which sounds obvious and is the third thing I tried.

Legibility at distance. The desk is at the bottom of the screen, small, and viewed at a shallow angle. Everything on it has to be readable at that size, which rules out most of what a UI would do.

Labels in front, always

The single most useful thing learned from building it: a label behind a control is invisible.

The levers stand about nine units tall. Anything printed on the desk surface behind a lever is hidden by the lever itself from every viewpoint above the desk, which is every viewpoint a standing player has. This is not a subtle occlusion issue — the label is simply gone, at all times, and it took an embarrassingly long time to work out why the labels I had definitely drawn were not there.

So labels go in front of their control, between the control and the player. The brand name and the zone captions ended up on the vertical front apron of the desk for the same reason: it is the one surface guaranteed to face the camera.

The general form of this rule: in a three-dimensional interface, the question "where does this text go" has a different answer than in a flat one, and the answer is always "on the surface facing the viewer", not "next to the thing it describes".

The canvas colour trap

The desk labels are drawn to a canvas texture. Colours in the rest of the engine are numbers, because that is what the renderer wants for a material.

Assigning a number to a canvas fill style does nothing. It does not throw, it does not warn, it silently leaves the previous fill in place — so the labels came out in whatever colour had been set last, which was usually black on a dark desk.

Canvas wants CSS colour strings. The two systems look interchangeable at the call site and are not, and the failure is silent in both directions. Anywhere the engine hands a colour to a canvas, it converts first, and there is a comment saying why.

What did not survive

Not every control earned its place on the desk.

Camera presets were tried as a row of physical buttons and moved back into the top bar. The reason is that a camera preset is not something a railway operator does — it is something a player does, and pretending otherwise made you fumble for a small button to do something you wanted instantly.

That is the line, in retrospect. Controls that belong to the layout go on the desk. Controls that belong to the game — camera, save, shop, help — go in the interface, because they are not part of the fiction and dressing them up as part of it makes them harder to use for no gain.

Getting that boundary wrong in either direction is worse than picking one style and applying it everywhere. A game where everything is diegetic is a game where saving requires walking to a filing cabinet.

  • design
  • ui
  • control desk

◀ All posts