import { Instance } from "./Instance.js"; import { BO3ScriptSignal } from "../core/BO3ScriptSignal.js"; export class DebugTextService extends Instance { constructor() { super("DebugTextService"); this.isClient = true; // Mark client-only this._renderService = null; this._networkService = null; this._lastBytes = 0; this._bps = 0; this._lastMeasure = performance.now(); // Tracks text lines this._lines = []; // Hook into render loop later } OnAddedToScene(parent) { const dm = this.GetDataModel(); // Get references to RenderService and NetworkService this._renderService = dm.GetService("RenderService"); this._networkService = dm.GetService("NetworkService"); if (!this._renderService) { console.warn("[DebugTextService] No RenderService found!"); return; } // Initialize debug text array this._renderService.debugText = []; // Hook into RenderStepped this._renderService.RenderStepped.Connect((dt) => this._onRenderStep(dt)); } // Called each RenderStepped frame (~60fps) _onRenderStep(dt) { this._lines.length = 0; // clear // === Network stats === if (this._networkService) { const now = performance.now(); const bytesNow = this._networkService.totalBytes || 0; const deltaBytes = bytesNow - this._lastBytes; const deltaTime = (now - this._lastMeasure) / 1000; if (deltaTime > 0.25) { // smooth every 250ms this._bps = deltaBytes / deltaTime; this._lastBytes = bytesNow; this._lastMeasure = now; } this._lines.push( `Net: ${(this._bps / 1024).toFixed(2)} KB/s` ); } // === Instance tree summary === const dm = this.GetDataModel(); if (dm && dm.Children) { const totalInstances = this._countInstances(dm); this._lines.push(`Instances: ${totalInstances}`); } // === Misc stats === if (this._renderService.physicsWorld) { const bodies = this._renderService.physicsWorld.bodies.length; this._lines.push(`Physics Bodies: ${bodies}`); } // === Output === this._renderService.debugText.length = 0; this._renderService.debugText.push(...this._lines); // Generate instance tree (for future use) const instanceTree = this._generateTree(dm); // Push this to text overlay if needed this._renderService.debugText.push(...instanceTree); } _countInstances(instance) { let count = 1; if (!instance.Children) return count; for (const child of instance.Children) { count += this._countInstances(child); } return count; } _generateTree(instance, depth = 0) { let lines = []; const indent = " ".repeat(depth); lines.push(`${indent}- ${instance.ClassName} (${instance.Name}) [${instance.InstanceId}]`); if (instance.Children) { for (const child of instance.Children) { lines.push(...this._generateTree(child, depth + 1)); } } return lines; } } // Displays debug text overlay on screen with network and instance stats