Выведите живые данные
Разберём, как код оверлея получает данные игры, где искать нужные поля, и добавим в оверлей время последнего круга. Около 20 минут.
Держите запущенным npm run dev из прошлого шага и откройте в браузере http://localhost:5173/?demo: так результат каждого изменения будет виден сразу.
Как оверлей получает данные
Откройте src/main.ts. Всё общение с Racelink — в двух местах:
const overlay = createOverlay<Settings>({ defaults: defaultSettings });
// …
overlay.on('telemetry', (telemetry) => {
if (overlay.ready) render(telemetry);
});createOverlayподключается к Racelink (или включает демо-данные) и возвращает объектoverlay.overlay.on('telemetry', …)вызывает вашу функцию при каждом поступлении новых данных. В шаблоне она передаёт их вrender, а та обновляет страницу.
Данные разложены по темам: car — педали, скорость, передача; timing — время кругов; fuel — топливо; drivers — все машины в сессии; weather — погода, и другие. Каждая тема приходит со своей частотой: car — до 60 раз в секунду, timing — 4, weather — 1.
Где искать поля
Полный путь к значению — тема и поле через точку. Найти нужное поле можно тремя способами.
- Studio → Данные API
- В Racelink откройте Studio и вкладку Данные API: все поля с описанием, частотой и текущим значением. Есть поиск по пути и описанию и переключатель Только поля текущей игры. Клик по пути копирует его, а правый клик → Копировать как код даёт готовую строку вроде
overlay.telemetry.car.rpm. Без игры значения пустые, но список полей есть всегда. - Справочник полей
- Файл
node_modules/@racelink/overlay/docs/reference/fields.mdв вашем проекте: все поля, их типы, единицы и игры, в которых они заполнены. В VS Code откройте его и нажмите Ctrl + Shift + V, чтобы увидеть таблицы. - Подсказки редактора
- SDK написан на TypeScript, поэтому редактор знает все поля. Напишите
car.внутриrender— VS Code покажет список полей; если он не появился, нажмите Ctrl + Space.
Добавьте время последнего круга
В справочнике или в «Данных API» найдите timing.lap.lastSeconds: время последнего круга в секундах, тип number | null. Выведем его под скоростью. Для этого — четыре изменения в src/main.ts и src/style.css.
1. Добавьте элемент для круга в разметку, после <span class="speed">:
<div class="readout"><strong class="gear">N</strong><span class="speed"></span><span class="lap"></span></div>2. Под строкой с const speed = … найдите этот элемент и добавьте функцию, которая превращает секунды в привычный вид:
const lap = root.querySelector<HTMLElement>('.lap');
// Lap time as 1:42.315; a dash while there is none.
const formatLap = (seconds: number | null): string => {
if (seconds === null) return '—';
const minutes = Math.floor(seconds / 60);
return `${minutes}:${(seconds - minutes * 60).toFixed(3).padStart(6, '0')}`;
};3. В render возьмите кроме car ещё тему timing и выведите время в конце функции:
const render = ({ car, timing }: TelemetryTopics): void => {
// …the existing lines stay as they are…
if (lap) lap.textContent = formatLap(timing.lap.lastSeconds);
};4. Добавьте стиль в конец src/style.css:
.lap {
font-size: clamp(10px, 12cqh, 28px);
font-variant-numeric: tabular-nums;
opacity: 0.8;
}Сохраните оба файла. С ?demo под скоростью появится время вроде 1:44.200. Уберите ?demo из адреса: если Racelink запущен, а игры нет, вместо времени будет прочерк. font-variant-numeric: tabular-nums делает цифры одной ширины, чтобы время не дрожало, когда меняется.
Значения, которых нет
Прочерк — не случайность. Не каждая игра даёт каждое значение, и не в каждый момент: до первого пройденного круга последнего времени ещё нет, а в Assetto Corsa Rally Racelink время круга не передаёт. Такое значение равно null. Поле при этом существует всегда, в любой игре, поэтому коду достаточно обработать null.
TypeScript следит за этим сам. Если написать timing.lap.lastSeconds.toFixed(3), редактор подчеркнёт строку красным:
'timing.lap.lastSeconds' is possibly 'null'.Это значит: «здесь может быть null, решите, что показать в этом случае». Обычно показывают прочерк или прячут элемент. В справочнике у таких полей тип number | null, а в колонке Games видно, в каких играх поле заполнено.
Единицы одинаковы во всех играх
Racelink переводит данные каждой игры в одни единицы, поэтому один и тот же код работает везде. Единица часто видна в имени поля:
- Скорость
- км/ч — car.speedKph
- Педали
- от 0 до 1 — car.throttle, car.brake
- Время
- секунды — timing.lap.lastSeconds
- Топливо
- литры — fuel.levelLiters
- Температура
- °C — weather.trackTemperatureC
- Углы
- радианы — car.headingRad
Если игрок предпочитает мили в час, переводите при показе, как шаблон делает со скоростью. Данные от этого не меняются.
Если что-то пошло не так
- Ничего не изменилось. Проверьте, что сохранили оба файла и что
npm run devещё работает. - Оверлей пропал, в консоли браузера
Cannot read properties of undefined— опечатка в пути, напримерtiming.lapsвместоtiming.lap. Такие опечатки VS Code тоже подчёркивает красным. - Время не меняется. Так и должно быть: последний круг меняется раз за круг, в демо — примерно раз в 1 минуту 44 секунды.
Что должно получиться
- С
?demoпод скоростью видно время последнего круга. - Без игры и без ?demo вместо времени — прочерк, а оверлей работает.
- Вы нашли поле
timing.lap.lastSecondsв справочнике или в Studio → «Данные API». - В VS Code нет красных подчёркиваний в src/main.ts.