Modders & Developers

Build on top of the radio

Channel 19 runs alongside American Truck Simulator and Euro Truck Simulator 2 rather than inside them. The telemetry plugin that reads your truck also serves a small HTTP API on localhost — and anything on your machine can talk to it. Overlays, stream widgets, dashboards, a physical CB set wired to an Arduino: it's all the same handful of endpoints.

Nothing to sign up for. The API is local, unauthenticated and running whenever the plugin is loaded. Install the plugin, start the game, and curl it.

The Local API

The plugin serves on http://127.0.0.1:18919. No authentication, because it never leaves the machine — which is also why you should not forward that port anywhere.

MethodPathWhat it does
GET/statusPlugin version, whether the game is connected, current truckpoll at 2 Hz
GET/telemetrySpeed, engine, camera, PTT state and current channelpoll at 10 Hz
POST/input/pttPush the transmit key down or let it up
POST/input/channelChange the channel, 1 through 40
GET/overlay/configWhere the in-cab set is mounted and how it is scaled
POST/overlay/configMove it, resize it, save the calibration

What /telemetry gives you

{
  "speed_kmh": 65.5,
  "engine_on": true,
  "cabin_camera_active": true,
  "truck_id": "peterbilt.579",
  "player_id": "steam_76561198000000000",
  "session_id": "session_abc123",
  "ptt_down": false,
  "current_channel": 19,
  "timestamp": 1706123456
}

Fields can come back empty when the game hasn't reported them —player_id and session_id in particular. Treat every value as optional and you'll not get caught out when someone is sitting in a menu.

Try it

curl http://127.0.0.1:18919/status

If that comes back, you're in business. If it doesn't, check %Documents%\American Truck Simulator\channel19\plugin.log — the plugin writes there on startup, including when port 18919 was already taken.

Building a Faceplate

The client's radio is artwork plus a layout, not code. Every set puts its knobs somewhere different, so the positions travel with the picture — swap the image alone and the hit targets end up over the wrong part of it. Build a new set and it appears in the picker next to the three that ship.

Where it goes

One folder per faceplate, inside %AppData%\Channel19\faceplates:

%AppData%\Channel19\faceplates\
└─ my-set\
   ├─ faceplate.json    name, description, control positions
   └─ shell.png         the artwork

The folder name becomes the id if you leave id out, and the id doubles as the name if you leave that out too. Artwork defaults to shell.png beside the manifest; point imageUri at something else if you'd rather. A missing image or an id that clashes with an existing set means the faceplate is skipped and a line goes in the client log — it won't take the picker down with it.

The design space

Every rectangle is in a fixed 1362 × 402 coordinate space, and your artwork is scaled to fit it. That means you can draw at whatever resolution you like — 2724 × 804 if you want it crisp on a big monitor — and still describe positions in the same numbers. Match the 1362:402 aspect or the art gets letterboxed.

faceplate.json

This is Classic Chrome's actual layout, so it's a working starting point — drop your own art in and nudge the numbers.

{
  "id": "my-set",
  "name": "My Set",
  "description": "Brushed panel, amber backlight.",

  "displayOuter":  { "x": 162,  "y": 64,  "width": 876, "height": 144 },
  "displaySafe":   { "x": 620,  "y": 76,  "width": 400, "height": 120 },
  "smeter":        { "x": 190,  "y": 104, "width": 380, "height": 64  },

  "channelKnob":   { "x": 586,  "y": 226, "width": 148, "height": 148 },
  "volKnob":       { "x": 258,  "y": 258, "width": 84,  "height": 84  },
  "sqlKnob":       { "x": 398,  "y": 258, "width": 84,  "height": 84  },
  "gainKnob":      { "x": 858,  "y": 258, "width": 84,  "height": 84  },
  "micKnob":       { "x": 998,  "y": 258, "width": 84,  "height": 84  },
  "powerButton":   { "x": 1146, "y": 262, "width": 68,  "height": 68  },

  "valueTextPlacement": "above",
  "valueTextColor": "#FFFFB59B",
  "lcdCoreColor": "#FFFF7A00",
  "lcdGlowColor": "#66FF7A00"
}

What each rect drives

FieldWhat sits there
displayOuterThe glass as a whole — the lit area behind the readout
displaySafeThe part of the glass text can occupy without being clipped
smeterThe signal meter
channelKnobThe big selector, 1 through 40
volKnobVolume
sqlKnobSquelch — the noise gate
gainKnobRF gain, receiver sensitivity
micKnobYour outgoing level
powerButtonKills the set, hiss and display with it

Getting it to look right

  • valueTextPlacement is "below", "above" or "hidden". If your art already paints labels under the knobs, put the values above them — or hide them and let the artwork do the talking.
  • Colours are hex ARGB, not RGB: #FFFFB59B is opaque. A light panel needs a dark valueTextColor or the readouts vanish.
  • lcdCoreColor and lcdGlowColor set the backlight, so a green- or amber-lit set doesn't have to wear the default red.
  • displaySafe sits inside displayOuter: outer is the glass, safe is where text is guaranteed not to be clipped by a bezel.
  • Leave any rect out and that control keeps the position from the built-in layout, which is handy while you're roughing one in.

If you build one worth sharing, post it in the Discord — the good ones should ship with the client.

How the Mod Fits Together

Two pieces, and they're deliberately separable:

  • The telemetry plugin — C++ against the SCS Telemetry SDK, dropped into bin\win_x64\plugins\. It reads the game and serves the API above. It does not modify the game.
  • The in-cab overlay — the CB set rendered in the world, mounted on the dash, overhead or passenger side, with its position saved through /overlay/config.

The plugin registers standard SCS telemetry channels and never checks which game it's in, which is why the same build works for both titles.

A Few Ground Rules

Short list, and none of it is lawyer-speak:

  • Don't expose the local API to the network. It has no auth by design.
  • Don't feed it invented telemetry to place yourself somewhere you aren't. Proximity audio is the whole point, and faking position ruins it for the people around you.
  • Don't ship a modified plugin as though it were ours. Fork it, name it something else, say what you changed.

Beyond that: build what you want, charge for it if you like, and you don't need our permission.

Getting Help

There's no developer mailing list — the Discord is where this happens. Ask in the help channels, or say you're building something and a moderator will point you at the right room.

Join the Discord · The desktop client · How it works

Channel 19 is an independent service. It is not affiliated with or endorsed by SCS Software, American Truck Simulator, Euro Truck Simulator, or Discord. The SCS Telemetry SDK is SCS Software's, and their terms apply to it.