Racelink
Шаги руководства · 03 / 08
  1. 00Перед началом
  2. 01Создайте проект
  3. 02Запустите оверлей
  4. 03Выведите живые данные
  5. 04Добавьте настройки
  6. 05Доведите вид
  7. 06Соберите и проверьте
  8. 07Опубликуйте в Мастерской
  9. 08Выпускайте обновления

// Руководство по оверлеям · 03

Выведите живые данные

Разберём, как код оверлея получает данные игры, где искать нужные поля, и добавим в оверлей время последнего круга. Около 20 минут.

Держите запущенным npm run dev из прошлого шага и откройте в браузере http://localhost:5173/?demo: так результат каждого изменения будет виден сразу.

Как оверлей получает данные

Откройте src/main.ts. Всё общение с Racelink — в двух местах:

src/main.ts
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">:

src/main.ts
  <div class="readout"><strong class="gear">N</strong><span class="speed"></span><span class="lap"></span></div>

2. Под строкой с const speed = … найдите этот элемент и добавьте функцию, которая превращает секунды в привычный вид:

src/main.ts
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 и выведите время в конце функции:

src/main.ts
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:

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), редактор подчеркнёт строку красным:

Ошибка TypeScript
'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.