cu_bevymon
cu_bevymon is a Copper monitor frontend that renders the shared TUI monitor UI inside Bevy using bevy_ratatui.
By default, the Bevy windowed monitor uses bundled JetBrains Mono Nerd Font Mono TTF files so the Bevy rendering is much closer to the console monitor than the stock mono_8x13 backend.
It provides:
CuBevyMon: aCuMonitorimplementation backed by the shared monitor modelCuBevyMonPlugin: a Bevy plugin that draws the monitor into a Bevy textureCuBevyMonFontOptions: font sizing for the bundled windowed TUI rendererCuBevyMonTextureandCuBevyMonPanel: the Bevy-backed monitor render surfaceCuBevyMonSurfaceNode,CuBevyMonFocus, andCuBevyMonFocusBorder: helpers for click-to-focus split layoutsspawn_split_layout(...): the shared left/right split shell used by the current examplesCuBevyMonViewportSurface: a camera helper for syncing a 3D viewport to a Bevy UI panel
Design intent:
- reuse the same Ratatui rendering as
cu_consolemon - reuse the same shared
LOGpane, including Copper live logs and optionalstderrcapture - integrate into existing Bevy sims like
cu_rp_balancebotandcu_flight_controller - keep the rendering/backend split clean enough for later browser / wasm work
Recommended app structure:
- keep Copper config backend-agnostic by pointing it at an app-local monitor alias
- pick the actual monitor implementation in Rust with
cfg(feature = "...") - let the Bevy host app decide layout and focus ownership
The existing flight-controller pattern is the recommended one:
// copperconfig.ron
(
id: "monitor",
type: "tasks::monitor::AppMonitor",
)
// src/tasks/monitor.rs
pub type AppMonitor = CuBevyMon;
pub type AppMonitor = CuConsoleMon;
pub type AppMonitor = CuLogMon;
That keeps RON stable while the build target decides whether the app gets a Bevy panel, a terminal TUI, or a lighter real-target monitor.
Standard split-view pattern:
- Keep your sim scene camera app-owned.
- Recommended: render that camera to an offscreen
RenderTarget::Image. - Add
CuBevyMonPlugin::new(model)to the Bevy app. - Create a dedicated
Camera2dfor the split-shell UI. - Call
spawn_split_layout(...)with the scene camera entity and the monitor texture handle. - Add app-specific overlays like loading cards, help panels, or OSD widgets as children of the returned
sim_panel. - Gate sim-control systems on
Res<CuBevyMonFocus>whilecu_bevymonroutes monitor events tocu_tuimon.
Shared shell sketch:
let layout = spawn_split_layout;
commands.entity.with_children;
The cu_bevymon_demo, cu_rp_balancebot, and cu_flight_controller examples all use that shared split shell now. The main app-specific choice is how the left-side scene camera is produced.
Render strategy guidance:
- Use the offscreen
RenderTarget::Image+ViewportNodepath when the sim already has its own UI overlays, picking, or camera behavior. This is the standardized path in the current examples. CuBevyMonViewportSurfacestill exists for simpler panel-clipped window cameras, but it is now the lower-level escape hatch, not the primary documented pattern.
Input model:
- window focus stays with Bevy
- logical panel focus is tracked by
CuBevyMonFocus cu_bevymontranslates Bevy events into backend-neutralcu_tuimon::MonitorUiEvent- monitor bindings live in
cu_tuimon, not in the Bevy adapter
Font behavior:
- the default bundled font set is JetBrains Mono Nerd Font Mono Light / SemiBold / LightItalic
- the default bundled font size is 24 px
- panel resize changes how many rows and columns fit; it does not change the glyph size
- use
CuBevyMonPlugin::with_font_size(...)orCuBevyMonPlugin::with_font_options(...)to tune the Bevy-side font size - use
CuBevyMonPlugin::with_font_options(...)for full control - the bundled font bytes live under
assets/fonts/ - this improves glyph coverage for the powerline tabs, symbols, arrows, and box drawing used by
cu_tuimon - OpenType feature selection like Kitty's
+zeroflag is not currently exposed through this backend