Make it look right
Racelink shows an overlay over the game, in OBS and in previews — always from the first frame. Teach the HUD to fit any size, limit its size in the manifest and add an animation that does not flicker on opening. About 20 minutes.
Diese Anleitung gibt es vorerst nur auf Englisch.
Keep npm run dev and Racelink running, with My HUD on screen.
Stretch the overlay
The player picks the overlay’s size, so the layout never knows it in advance. See how the HUD behaves now:
- Open Layouts and press Arrange overlays.
- Drag My HUD by its bottom-right corner: make it twice as big, then very small.
The pedal bars stretch, and the gear, speed and lap time grow and shrink with the window. Two things in the template’s src/style.css make this work:
#root {
/* … */
container-type: size;
}
.gear {
font-size: clamp(24px, 45cqh, 120px);
}container-type: size- Makes #root a container: inside it, sizes can be measured as a percentage of it.
45cqh- 45% of the container’s height. A taller window, a bigger digit. There is also cqw, a percentage of the width.
clamp(24px, …, 120px)- At least 24 and at most 120 pixels, so the text stays readable and does not balloon.
The template’s paddings and gaps are percentages rather than pixels for the same reason. Do the same in your own elements: the lap time from “Show live data” already uses 12cqh.
Limit the size
A tiny HUD is unreadable and a huge one is pointless. The size field in racelink.overlay.json sets the limits. The template has:
"size": { "default": [360, 120], "min": [200, 80], "max": [1200, 400] },default- Width and height in pixels of a new overlay, when the player adds it to a layout.
min- It cannot be made smaller than this.
max- It cannot be made bigger than this.
See what a limit looks like:
- Change
maxto[600, 200]and save the file. - In edit mode, drag My HUD’s right edge past 600 pixels. The edge turns amber and gives way a little, like rubber, and springs back to the limit when you let go. That is how the player sees the overlay cannot grow further.
If the overlay was bigger than the new limit, Racelink shrinks it to fit. Keep whichever limits suit you: [600, 200] or the original ones.
Two more options that come in handy for other overlays:
- One side fixed
- The same min and max on a side: "min": [200, 120], "max": [1200, 120] keeps the height at 120 and lets only the width change. That edge cannot be dragged in the editor.
"resize": "scale"- For an overlay drawn for one size: "size": { "default": [400, 300], "resize": "scale" }, with no min or max. The window is always 400 × 300, and dragging scales the whole overlay up or down, keeping its proportions, from 0.25× to 4×.
An overlay’s Smaller and Larger buttons in edit mode scale any overlay the same way — as a whole.
Animations without flicker
Animation brings an overlay to life, but not when it opens: if rows slide and fade in every time it appears, the overlay looks half-drawn in previews and in OBS. So for 1.5 seconds after ready the SDK ends every CSS transition and animation at once. The overlay opens in its final look, and after that animations play as usual.
Try it: make the gear digit flash in the throttle colour on every shift.
1. In src/main.ts, above render, add a variable for the gear on screen:
let shownGear = '';2. In render, replace the line if (gear) gear.textContent = … with:
const gearText = car.gear < 0 ? 'R' : car.gear === 0 ? 'N' : String(car.gear);
if (gear && gearText !== shownGear) {
shownGear = gearText;
gear.textContent = gearText;
// Restart the animation: take the class off, let the browser notice, put it back.
gear.classList.remove('shift');
void gear.offsetWidth;
gear.classList.add('shift');
}3. At the end of src/style.css:
.gear.shift {
animation: shift 400ms ease-out;
}
@keyframes shift {
from {
color: var(--throttle);
transform: scale(1.15);
}
}Save. With ?demo the gear flashes on every shift, but not when the page opens, although render in ready sets the gear for the first time too.
To see the difference, turn animations on from the first frame for a moment and reload:
const overlay = createOverlay<Settings>({ defaults: defaultSettings, animateStart: true });Now the gear flashes on opening as well. Remove animateStart: true: an overlay is almost always better without it.
History from the first frame
My HUD has no history, but keep this for later. An overlay that draws the past — a pedal graph of the last seconds, a G-force trail — is empty when it opens: it has seen no past yet. In previews and demo mode that looks broken. That is what overlay.demoHistory is for: a topic’s demo values over the last seconds, oldest first.
overlay.on('ready', () => {
// Empty outside demo mode, so this does nothing with a real game.
for (const { sampledAt, data } of overlay.demoHistory('car', 10)) trace.push(sampledAt, data);
});Here trace is your graph. With a game demoHistory is empty, and the graph fills with live data.
A transparent background
An overlay’s window is transparent: whatever you do not draw shows the game. The template gives html, body and #root background: transparent, and the dark panel is #root’s background with the opacity from the setting. What not to do:
- Do not give
htmlorbodya background — it covers the game with a rectangle. - Do not set
color-scheme, in a<meta>or in CSS: the browser paints the window white or black.
Look at the preview
Racelink shows the overlay in more places than the screen. Open Layouts and select My HUD: the Settings panel has a preview on demo data. Switch to another overlay and back: the HUD should appear finished at once — your colours, no gear flash, no empty spots.
If something goes wrong
- Text does not resize with the window. The element’s font size is in
pxinstead ofcqh, or no element above it hascontainer-type: size. - The edge does not turn amber. Look at the terminal: Racelink does not accept a manifest with a mistake (for example,
minbigger thanmax), and it showsracelink.overlay.json has problems. - The gear flashes only once. The line
void gear.offsetWidth;is missing: without it the browser does not notice the class was taken off, and the animation does not restart.
What you should have
- My HUD is readable in a small window and in a big one.
- At a limit the overlay’s edge turns amber and springs back.
- The gear flashes on a shift, but not when the overlay opens.
- In Racelink’s preview the HUD appears finished at once.