diff --git a/server/src/services/replayEngineV2.js b/server/src/services/replayEngineV2.js
index 9fc441cd..cfd5ab89 100644
--- a/server/src/services/replayEngineV2.js
+++ b/server/src/services/replayEngineV2.js
@@ -27,7 +27,7 @@ const TARGET_FPS = Math.max(10, Number.parseInt(process.env.REPLAY_TARGET_FPS ||
const MAX_WIDTH = Math.max(320, Number.parseInt(process.env.REPLAY_MAX_WIDTH || '1280', 10));
const MAX_HEIGHT = Math.max(180, Number.parseInt(process.env.REPLAY_MAX_HEIGHT || '720', 10));
const MAX_BYTES = Math.floor(Number.parseFloat(process.env.REPLAY_MAX_OUTPUT_MB || '9.5') * 1024 * 1024);
-const SIDEBAR_WIDTH = Math.max(200, Number.parseInt(process.env.REPLAY_SIDEBAR_WIDTH || '290', 10));
+const SIDEBAR_WIDTH = Math.max(180, Number.parseInt(process.env.REPLAY_SIDEBAR_WIDTH || '250', 10));
const events = new EventEmitter();
@@ -424,7 +424,7 @@ function escapeXml(text) {
.replace(/'/g, ''');
}
-function wrapTextLines(text, maxChars = 28) {
+function wrapTextLines(text, maxChars = 24) {
const words = String(text || '').split(/\s+/).filter(Boolean);
const lines = [];
let current = '';
@@ -473,10 +473,10 @@ function renderSidebarSvg({
driverBatteryLines,
chatLines,
}) {
- const titleParts = wrapTextLines(title, 22).slice(0, 4).map((line) => escapeXml(line));
+ const titleParts = wrapTextLines(title, 20).slice(0, 4).map((line) => escapeXml(line));
const statLines = driverBatteryLines.slice(0, 8).map((line) => escapeXml(line));
const normalizedChats = chatLines.slice(-12).map((entry) => {
- const wrapped = wrapTextLines(entry.text || '', 24).slice(0, 3).map((line) => escapeXml(line));
+ const wrapped = wrapTextLines(entry.text || '', 20).slice(0, 4).map((line) => escapeXml(line));
const nick = escapeXml(entry.nickname || 'user');
const roverId = escapeXml(entry.roverId || '');
const roverRgb = hexToRgb(entry.roverColor || '');
@@ -496,68 +496,68 @@ function renderSidebarSvg({
const shapes = [];
const textRows = [];
- const pad = 8;
+ const pad = 5;
const cardX = pad;
const cardW = width - pad * 2;
- let y = 8;
+ let y = 5;
// Title card
- const titleCardH = Math.max(56, 18 + titleParts.length * 22);
- shapes.push(``);
- let ty = y + 28;
+ const titleCardH = Math.max(42, 12 + titleParts.length * 18);
+ shapes.push(``);
+ let ty = y + 18;
for (const part of titleParts) {
- textRows.push(`${part}`);
- ty += 22;
+ textRows.push(`${part}`);
+ ty += 18;
}
- y += titleCardH + 6;
+ y += titleCardH + 4;
// Drivers card
const driverLines = statLines.length ? statLines : ['No active drivers'];
- const driversCardH = 24 + driverLines.length * 18 + 8;
- shapes.push(``);
- textRows.push(`Drivers`);
- let dy = y + 44;
+ const driversCardH = 20 + driverLines.length * 16 + 6;
+ shapes.push(``);
+ textRows.push(`Drivers`);
+ let dy = y + 32;
for (const line of driverLines) {
- textRows.push(`${line}`);
- dy += 20;
+ textRows.push(`${line}`);
+ dy += 16;
}
- y += driversCardH + 6;
+ y += driversCardH + 4;
// Chat card
- const chatCardH = Math.max(80, height - y - 8);
- shapes.push(``);
- textRows.push(`Chat`);
+ const chatCardH = Math.max(80, height - y - 5);
+ shapes.push(``);
+ textRows.push(`Chat`);
- let cy = y + 34;
- const bubbleX = cardX + 8;
- const bubbleW = cardW - 16;
+ let cy = y + 22;
+ const bubbleX = cardX + 5;
+ const bubbleW = cardW - 10;
if (!normalizedChats.length) {
- textRows.push(`No chat in replay window`);
+ textRows.push(`No chat in replay window`);
} else {
for (let i = 0; i < normalizedChats.length; i += 1) {
const block = normalizedChats[i];
- const bubbleH = 26 + block.wrapped.length * 16;
- if (cy + bubbleH + 6 > y + chatCardH - 8) break;
+ const bubbleH = 20 + block.wrapped.length * 14;
+ if (cy + bubbleH + 4 > y + chatCardH - 5) break;
shapes.push(
- ``,
+ ``,
);
- textRows.push(`${block.nick}`);
+ textRows.push(`${block.nick}`);
if (block.fromDiscord) {
- textRows.push(`◈`);
+ textRows.push(`◈`);
}
if (block.roverId) {
- const badgeTextX = bubbleX + bubbleW - 70;
+ const badgeTextX = bubbleX + bubbleW - 56;
shapes.push(
- ``,
+ ``,
);
- textRows.push(`${block.roverId}`);
+ textRows.push(`${block.roverId}`);
}
- let by = cy + 32;
+ let by = cy + 25;
for (const line of block.wrapped) {
- textRows.push(`${line}`);
- by += 16;
+ textRows.push(`${line}`);
+ by += 14;
}
- cy += bubbleH + 6;
+ cy += bubbleH + 4;
}
}
@@ -570,19 +570,18 @@ function renderSidebarSvg({
-
${shapes.join('\n ')}
${textRows.join('\n ')}
@@ -604,7 +603,7 @@ async function renderSidebarVideo({
const secondCount = Math.max(1, Math.ceil(durationSec));
for (let second = 0; second < secondCount; second += 1) {
const sliceEndMs = windowStartMs + (second + 1) * 1000;
- const visibleChat = chatEvents.filter((entry) => entry.ts <= sliceEndMs).slice(-10).map((entry) => entry.text);
+ const visibleChat = chatEvents.filter((entry) => entry.ts <= sliceEndMs).slice(-10);
const svg = renderSidebarSvg({
width: SIDEBAR_WIDTH,
height,