View Health & Watchdog
IVPrismaUI8::GetViewHealth exposes framework-observed health for a Prisma view. In PrismaUI_F4 2.1.0 those observations come from the in-process Ultralight 1.4.0 backend, not from a legacy-runtime renderer subprocess.
Use view health for diagnostics and bounded recovery. Do not treat it as a substitute for IsValid() or build an infinite recreate loop around it.
Public states
The ABI keeps these values:
enum class ViewHealth : int {
kUnknown = -1,
kCreating = 0,
kDomReady = 1,
kLive = 2,
kLoadFailed = 3,
kDomReadyTimeout = 4,
kUnresponsive = 5,
kJsError = 6,
};
kUnknown
The public API returns this when it cannot provide a known health state for the supplied handle/backend state.
Check IsValid(view) separately when the distinction matters.
kCreating
The view has been admitted/created but has not yet reached the DOM-ready/live state.
Do not focus a view in this state. The 2.1.0 focus path rejects a view unless its health is kDomReady or kLive.
kDomReady
The page has reached DOM-ready and the framework has published that state. Consumer DOM-ready callbacks are queued to the game thread.
This is a valid state for focus and normal JS bridge work.
kLive
The view completed the normal load path and is live.
kLoadFailed
The current page/view load failed or the framework rejected the main document/navigation. Examples include a missing/invalid view, failed Ultralight load, or an attempted top-level navigation outside the trusted document boundary.
Treat repeated kLoadFailed as a configuration/content problem until proven otherwise. Check PrismaUI_F4.log, view paths, and bundled assets before automatically recreating forever.
kDomReadyTimeout
Retained in the public health ABI for a page that fails to reach DOM-ready within the framework's allowed lifecycle window.
If it is reported, capture console/log evidence and recreate only with a bounded retry policy.
kUnresponsive
Retained in the public health ABI for an unresponsive view condition.
Do not interpret this as “the legacy-runtime subprocess crashed.” PrismaUI 2.1.0 is in-process Ultralight. Log the state and collect framework diagnostics before deciding whether to recreate.
kJsError
The public representation of a JavaScript/script-error health condition. For example, an Invoke evaluation exception can move the backend into its script-error state.
Use RegisterConsoleCallback and the Invoke result to diagnose the actual exception.
Querying health
if (!g_api || !g_view || !g_api->IsValid(g_view)) {
return;
}
const auto health = g_api->GetViewHealth(g_view);
Health is most useful at low frequency or when you already have a reason to diagnose a view. There is no need to poll it every render frame for a normal menu.
A simple bounded check:
using VH = PRISMA_UI_API::ViewHealth;
switch (g_api->GetViewHealth(g_view)) {
case VH::kDomReady:
case VH::kLive:
break;
case VH::kCreating:
// Still starting. Do not focus yet.
break;
case VH::kLoadFailed:
case VH::kDomReadyTimeout:
logger::error("Prisma view failed to become live");
break;
case VH::kUnresponsive:
logger::error("Prisma view became unresponsive");
break;
case VH::kJsError:
logger::warn("Prisma view reported a JavaScript error");
break;
case VH::kUnknown:
default:
break;
}
Console diagnostics
RegisterConsoleCallback is the primary in-game replacement for old legacy-runtime DevTools-oriented debugging instructions.
g_api->RegisterConsoleCallback(g_view,
[](PrismaView view,
PRISMA_UI_API::ConsoleMessageLevel level,
const char* message) {
logger::info("[Prisma JS][{}][{}] {}",
view,
static_cast<int>(level),
message ? message : "");
});
Console callbacks are delivered on the game thread in 2.1.0.
Also inspect:
Documents\My Games\Fallout4\F4SE\PrismaUI_F4.log
The framework records rejected navigation, runtime preflight failures, JS errors, focus failures, and other lifecycle diagnostics there.
Recovery pattern
A failed handle can be destroyed and recreated, but keep retries bounded:
void RecreateView()
{
if (!g_api) return;
if (g_view && g_api->IsValid(g_view)) {
g_api->Unfocus(g_view);
g_api->Hide(g_view);
g_api->Destroy(g_view);
}
g_view = 0;
g_view = g_api->CreateView("MyPlugin/index.html", OnDomReady);
if (g_view) {
g_api->SetViewRole(g_view, PRISMA_UI_API::ViewRole::kPanel);
g_api->Hide(g_view);
}
}
Do not immediately recreate forever on every update. A bad HTML path, missing asset, blocked navigation, or repeatable JS startup error will simply reproduce the same failure.
Important 2.1.0 differences from older watchdog docs
- There is no production legacy-runtime renderer subprocess to diagnose.
- Do not tell users to inspect legacy-runtime crash logs.
- Do not describe every view as an iframe in a shared legacy-runtime shell.
- Do not rely on external previous browser runtime DevTools. The V1 inspector API is unsupported under Ultralight 2.1.0.
- Use framework logs,
RegisterConsoleCallback,Invokeerrors,IsValid, andGetViewHealthinstead.