— Decía un programador de Unity en un tweet. Y tenía razón. También aplica a Bevy.
El cap. 26 mencionó Tracy en una línea. Eso fue una injusticia. El ecosistema Bevy tiene tres herramientas que, combinadas, te dan visibilidad total sobre lo que está pasando en tu juego mientras corre:
bevy_inspector_egui: un panel flotante de egui con todas las entidades, componentes, recursos y assets, navegables y editables en vivo.App desde fuera (un IDE, un script, otro juego).El editor oficial de Bevy está en desarrollo (el Inspector General working group, anunciado en octubre 2025). Hasta que llegue, este combo de tres es tu día a día.
bevy_inspector_egui: tu ventana al ECS en runtimeInstalación:
# cap-26B — sección 26B.2: Cargo.toml.
[dependencies]
bevy = { version = "0.19", features = ["2d"] }
bevy_inspector_egui = "0.37" # 0.37.0 (jun 2026), compatible con Bevy 0.19.
Setup:
//! cap-26B — sección 26B.2: setup del inspector.
use bevy::prelude::*;
use bevy_inspector_egui::prelude::*;
use bevy_inspector_egui::quick::WorldInspectorPlugin;
fn main() {
App::new()
.add_plugins(DefaultPlugins)
.add_plugins(WorldInspectorPlugin::new()) // ← el inspector.
.run();
}
Eso es todo. Cuando corras tu juego, vas a ver un panel lateral con la jerarquía de entidades, los componentes, los recursos. Click en una entidad, ves sus componentes. Click en un componente con campos editables (un f32, un String, un Vec3), podés modificar el valor en vivo y ver cómo cambia el juego.
Truco: marcar tus componentes con #[derive(Reflect)] para que aparezcan en el inspector:
//! cap-26B — sección 26B.2: componente reflectable.
use bevy::prelude::*;
use bevy::reflect::Reflect;
#[derive(Component, Reflect, Default, Debug, Clone)]
#[reflect(Component)]
struct Health { current: f32, max: f32 }
Sin Reflect, el inspector puede ver que el componente existe pero no puede mostrar sus campos.
Cuidado: el inspector no debe ir en builds de release. Usá una feature flag para activarlo solo en debug:
//! cap-26B — sección 26B.2: feature flag para el inspector.
#[cfg(feature = "debug-inspector")]
use bevy_inspector_egui::quick::WorldInspectorPlugin;
fn main() {
let mut app = App::new();
app.add_plugins(DefaultPlugins);
#[cfg(feature = "debug-inspector")]
app.add_plugins(WorldInspectorPlugin::new());
app.run();
}
Y en Cargo.toml:
[features]
debug-inspector = ["dep:bevy_inspector_egui"]
Build normal: cargo run. Build con inspector: cargo run --features debug-inspector.
Bevy 0.16+ trae BRP built-in. Es una API JSON-RPC 2.0 sobre HTTP (por defecto en 127.0.0.1:15702) que expone el estado del ECS. Cualquier cliente HTTP puede consultar y modificar el mundo.
Setup:
//! cap-26B — sección 26B.3: activar BRP.
use bevy::prelude::*;
use bevy::remote::{RemotePlugin, http::RemoteHttpPlugin};
fn main() {
App::new()
.add_plugins(DefaultPlugins)
.add_plugins(RemotePlugin::default())
.add_plugins(RemoteHttpPlugin::default())
.run();
}
Ahora podés hacer:
# Listar los tipos de componentes registrados (método `bevy/list`).
curl -X POST http://127.0.0.1:15702 \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","method":"bevy/list","params":{},"id":1}'
# Obtener el componente Transform de la entidad 42 (método `bevy/get`).
curl -X POST http://127.0.0.1:15702 \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","method":"bevy/get","params":{"entity":42,"components":["bevy_transform::components::transform::Transform"]},"id":1}'
Pero el caso real es usar un cliente que sepa de BRP. Los más útiles:
splo.vscode-bevy-inspector (extensión de VSCode): ves entidades, componentes, recursos, y podés modificarlos en vivo. Funciona con Bevy 0.15+ (algunas features requieren 0.16+).bevy_brp o similares.0.7.3 (mayo 2026), repo KyosukeIshizu1008/berryscode (con "s"). Hecho por un tercero, no oficial. https://lib.rs/crates/berryscode.La potencia de BRP: podés escribir scripts en Python o Node que controlen tu juego. Tests E2E, bots de prueba, demos automatizadas.
# cap-26B — sección 26B.3: script Python que mueve al player con `bevy/insert`.
import requests
def move_player(entity_id, x, y):
requests.post("http://127.0.0.1:15702", json={
"jsonrpc": "2.0",
"method": "bevy/insert",
"params": {
"entity": entity_id,
"components": {
"bevy_transform::components::transform::Transform": {
"translation": [x, y, 0.0]
}
}
},
"id": 1
})
move_player(42, 100.0, 50.0)
Cuidado: BRP permite modificar el estado del juego desde fuera. No lo actives en builds de release o en juegos en producción. Solo en builds de desarrollo.
Nota v4.0 —
#[reflect(Resource)]cambió en 0.19: en Bevy 0.19,ReflectResourcepasa a ser un ZST (zero-sized type) y#[reflect(Resource)]también refleja el traitComponent. Esto rompe código que usabaReflectResourcedirectamente (típicamente en BRP ybevy_world_serialization). Si tu proyecto usaba BRP y migras a 0.19, usaReflectComponenten su lugar. El error de compilación es confuso: "expected ReflectResource, found ReflectComponent" o similar. La solución: cambiarReflectResourceporReflectComponenten tu registro de tipos.
Tracy es un profiler de tiempo real que muestra cuánto tarda cada sistema, cada frame, cada evento. Se activa con una feature de Bevy.
# cap-26B — sección 26B.4: Cargo.toml.
[dependencies]
bevy = { version = "0.19", features = ["2d", "trace_tracy"] }
# cap-26B — sección 26B.4: instalar el cliente Tracy.
# macOS:
brew install tracy
# Linux (build from source): ver Tracy docs.
# Windows: binarios en el sitio oficial.
Ejecutar:
# 1. Abrir el cliente Tracy (tracy GUI).
# 2. En otra terminal, correr tu juego.
cargo run --release --features bevy/trace_tracy
# 3. Tracy se conecta automáticamente, ves los frames en vivo.
Lo que ves:
bevy/trace_tracy_memory, también ves allocaciones.Para un Bevy dev, Tracy es lo que muestra la verdad. Tu juego va a 60 fps pero un sistema come 15 ms. Ves eso en Tracy, no en el "FPS counter" del HUD.
Caveat oficial: para medir GPU, Tracy da solo una "vista de alto nivel". El
MTPC(mean time per call) de Tracy para GPU es la métrica confiable. Mirar frames individuales puede ser engañoso porque la GPU los submuestrea.
Para que Tracy sepa cuánto tarda tu sistema, Bevy ya lo mide automáticamente (todos los sistemas tienen un span). Para spans custom dentro de un sistema, usás bevy::log::info_span! o tracing::span!.
//! cap-26B — sección 26B.5: span custom dentro de un sistema.
use bevy::prelude::*;
use bevy::log::{info_span, info};
use tracing::Instrument;
fn heavy_system(
mut q: Query<&mut Transform>,
) {
let _span = info_span!("heavy_system").entered();
for mut t in q.iter_mut() {
let _iter_span = info_span!("update_one_transform").entered();
// ...trabajo pesado...
}
}
Tracy muestra "heavy_system" como un span, con un sub-span "update_one_transform" por iteración. Click en uno, ves la duración. Útil para encontrar "qué parte del sistema es la lenta".
bevy_simple_subsecond_systemHasta ahora hemos hablado de hot-reload de assets (texturas, sonidos, mallas) en 26B anterior. Eso está bien, pero el verdadero freno del dev-loop de Bevy no son los assets: es la recompilación. Estás ajustando la gravedad del salto del jugador: 0.5, 0.6, 0.55, 0.45. Cuatro valores. Cuatro Ctrl+C, cuatro cargo run, 30 segundos cada uno. Dos minutos para probar cuatro números. Si te equivocas, vuelta a empezar. Multiplica por 50 valores al día y tienes un día laboral perdido en compilación.
Analogía absurda: el dev-loop clásico de Rust es como cocinar pasta desde el trigo. Coges la espiga, la mueles, haces la masa, la hierves, la sirves. Tarda 30 minutos. Subsecond es como tener pasta precocida en la nevera: tú solo la calientas 90 segundos en el microondas y la sirves. No es tan buena como la hecha en el momento, pero cuando estás iterando una salsa, no quieres esperar media hora por cada prueba.
bevy_simple_subsecond_system (de TheBevyFlock: james-jdm-dev, ToasterRoaster y compañía, diciembre 2024) usa la tecnología Dioxus subsecond para recompilar una función aislada y reemplazar su cuerpo en memoria mientras el juego sigue corriendo. Sin reinicio, sin recompilación completa, sin pérdida de estado. Funciona gracias a dos pilares: (1) el compilador de Rust tiene un modo "single function recompile" experimental; (2) Dioxus lo envuelve en un crate que sabe cómo parchear binarios en ejecución. Bevy se integra con un plugin que expone un sistema Subsecond que detecta cambios en los archivos y los aplica.
Setup paso a paso:
cargo install dioxus-cli --version 0.7.0-alpha.1. Esto trae el binario dx que sabe cómo parchear.rust-toolchain.toml con channel = "nightly". Subsecond usa features unstable del compilador.Cargo.toml:# cap-26B — sección 26B.5b: Cargo.toml para subsecond.
[dependencies]
bevy = "0.19"
bevy_simple_subsecond_system = { version = "0.2", features = ["subsecond"] }
dioxus = { version = "0.7.0-alpha.1", features = ["subsecond"] }
#[subsecond::hot]://! cap-26B — sección 26B.5b: anotar un sistema.
use bevy::prelude::*;
use bevy_simple_subsecond_system::subsecond;
#[subsecond::hot]
fn ajustar_salto(
time: Res<Time>,
mut query: Query<&mut Movement>,
) {
for mut m in &mut query {
// Editá el 0.5 en vivo y mirá el cambio.
m.velocity.y += -9.8 * 0.5 * time.delta_secs();
}
}
dx run (no cargo run): dx run --bin my_game. La CLI compila con hot-patch habilitado.Limitaciones importantes:
&mut Query<...> por otra cosa, no funciona.[dev-dependencies] o detrás de un #[cfg(debug_assertions)].Cuándo NO usarlo:
Cuándo SÍ usarlo:
bevy_simple_subsecond_system es experimental (alpha, en pleno desarrollo). Úsalo sabiendo que puede romper entre versiones. Pero cuando funciona, es la diferencia entre ajustar 10 valores en 10 minutos y ajustar 10 valores en 10 segundos. La elección, como siempre, es tuya.
RenderDoc es una herramienta libre de captura de frames GPU. La instalás, abrís tu juego desde RenderDoc, capturás un frame, y podés:
# cap-26B — sección 26B.6: RenderDoc.
# 1. Instalar RenderDoc (https://renderdoc.org/).
# 2. Abrir RenderDoc, hacer click en "Launch App".
# 3. Tu juego se inicia, RenderDoc captura cada frame.
# 4. Presionar F12 (o el botón de captura) en el momento que querés.
# 5. Inspeccionar.
Para Bevy, RenderDoc funciona con Vulkan/Metal/DX12 (todos los backends que wgpu soporta). No funciona con WebGPU directamente (para eso, las DevTools de Chrome con --enable-unsafe-webgpu).
Casos de uso:
wgpu tracing: ver lo que la GPU hacePara un debug más fino de la GPU, Bevy 0.18+ integra tracing de wgpu. Activás la feature bevy/trace y los spans de wgpu aparecen en Tracy y en los logs.
# cap-26B — sección 26B.7: tracing completo.
[dependencies]
bevy = { version = "0.19", features = ["2d", "trace", "trace_tracy"] }
Cuidado: trace produce muchos spans. Útil cuando estás debug de GPU; molesto en el día a día.
El 27 de octubre de 2025, el blog "This Week in Bevy" anunció la formación del Inspector General working group, un grupo de trabajo dedicado a construir un inspector de entidades nativo para Bevy. Es el equivalente Bevy del Inspector de Unity o el Outliner de Unreal.
A fecha de esta edición (principios de 2026), el grupo está activo, hay propuestas, pero no hay release. Lo que se puede decir:
bevy_inspector_egui: integración con el asset graph, system graph, query visualizer.Mientras tanto, bevy_inspector_egui es el camino. Cuando el Inspector General llegue, probablemente haya un periodo de transición donde ambos coexisten.
Un flujo de trabajo realista de un Bevy-dev:
cooldown de un ataque de 1.0 a 0.5 sin recompilar.cargo test para la lógica; CI los corre automáticamente.El setup de un dev Bevy serio:
# cap-26B — sección 26B.9: setup de un dev.
cargo install tracy # profiler.
cargo install bve # bevy-cli (cuando esté estable).
# Editor: VSCode con rust-analyzer + splo.vscode-bevy-inspector.
# O: Neovim con rust-tools + un plugin de BRP.
# O: RustRover con plugin Bevy (cuando exista).
El cap. 26 te enseñó técnicas de optimización (batching, LOD, culling, asset streaming). El orden importa:
1. Mide (Tracy, RenderDoc, FPS counter).
2. Identifica el cuello de botella.
3. Optimiza SOLO eso.
4. Vuelve a medir.
5. Repetir hasta que el frame budget esté cómodo.
El error clásico: optimizar todo a la vez "para que vaya más rápido". Resultado: código complicado, bugs nuevos, y a veces más lento. Optimiza lo que se mide, no lo que se siente lento.
bevy_inspector_egui: crate que añade un panel egui al juego con entidades, componentes, recursos.
Reflect: trait de Bevy que permite serializar, deserializar, e inspeccionar un struct.
WorldInspectorPlugin: plugin de `bevy_inspector_egui` que añade el panel por defecto.
BRP (Bevy Remote Protocol): API JSON-RPC 2.0 sobre HTTP (endpoint único) para controlar un App Bevy desde fuera. Métodos: bevy/query, bevy/get, bevy/spawn, bevy/despawn, bevy/list, bevy/insert, bevy/remove.
RemotePlugin: plugin de Bevy que habilita BRP (parte servidor).
RemoteHttpPlugin: plugin que expone BRP sobre HTTP (por defecto en 127.0.0.1:15702).
Inspector General: working group de Bevy que está construyendo un inspector nativo.
Editor oficial Bevy: el que el Inspector General está construyendo. Aún no hay release.
Tracy: profiler de Rust en tiempo real. Ve CPU, GPU, memoria, eventos.
trace_tracy (feature): feature de Bevy que conecta el tracing interno con Tracy.
trace (feature): feature de Bevy que activa spans de tracing.
trace_chrome (feature): feature que exporta tracing a Chrome tracing format (Perfetto).
bevy/trace_tracy_memory: feature que suma tracking de memoria a Tracy.
RenderDoc: herramienta libre de captura de frames GPU. Estándar de la industria.
Vulkan / Metal / DX12: APIs gráficas modernas. wgpu las abstrae.
wgpu: librería de Rust que Bevy usa para renderizar.
Span: un "intervalo" de tiempo que Tracy mide. Se crea con `info_span!` o `tracing::span!`.
MTPC (Mean Time Per Call): métrica de Tracy para ver tiempo promedio por llamada. Útil para GPU.
RenderDoc (Baldur Karlsson, 2014) — antes de RenderDoc, debuggear shaders era cuestión de "agregar prints" al shader y ver el resultado. RenderDoc popularizó la captura de frame como flujo de trabajo. Hoy es estándar en la industria.
Tracy (Bartosz Taudul — wolfpld, 2017) — antes de Tracy, el profiling en Rust era rudimentario. Tracy popularizó el "frame profiler" con captura remota (tu juego en una máquina, Tracy en otra). Hoy es la opción dominante. (Nota: el handle wolfpld y el email del autor, wolf@nereid.pl, han confundido a algunos lectores que lo atribuyen a Wolfgang Engel; son personas distintas. Wolfgang Engel es autor de la serie de libros GPU Pro / GPU Zen y editor gráfico de Crytek, no tiene nada que ver con Tracy.)
bevy_inspector_egui (Jakob Hellermann, 2022) — el primer inspector serio para Bevy. Mantenido activamente. La comunidad lo adoptó rápido porque era el "missing piece" del flujo diario.
Bevy Remote Protocol (Bevy 0.16, 2024) — la primera versión oficial de BRP. El equipo de Bevy lo construyó inspirándose en el feedback de la comunidad sobre lo difícil que era debuggear sin un inspector oficial.
Inspector General (Bevy working group, 2025) — el reconocimiento oficial de que Bevy necesita un editor/integrated-debugger. Anunciado en This Week in Bevy #X de octubre 2025. A fecha de esta edición, sin release.
splo.vscode-bevy-inspector (splo, 2024) — la extensión de VSCode que usa BRP. Una de las mejores integraciones de un editor con Bevy hasta ahora.
BerrysCode (2025, crate publicado como berryscode 0.7.3) — primer IDE dedicado a Bevy, descrito como "The IDE built for the Bevy game engine". Repo: KyosukeIshizu1008/berryscode. Hecho por un tercero, no oficial. Usa BRP y bevy_inspector_egui por debajo.
Chrome Tracing (Chromium project, 2010) — el formato JSON que exporta la feature `bevy/trace_chrome`. Compatible con `ui.perfetto.dev` (la versión moderna de Chrome tracing).
❌ Compilar el inspector en builds de release.
✅ Feature flag `debug-inspector`, activada solo en builds de dev.
💡 Por qué: el inspector añade 1-3 MB al binario y 5-10% de overhead. En producción, no querés eso.
❌ Activar BRP en un juego publicado.
✅ BRP solo en builds de desarrollo.
💡 Por qué: BRP permite a cualquiera con acceso HTTP modificar tu juego. Un atacante podría romper tu estado o leer datos sensibles. Nunca.
❌ Mirar el framerate y optimizar.
✅ Mirar Tracy, encontrar el sistema lento, optimizar ESO.
💡 Por qué: el framerate te dice "algo está mal". Tracy te dice QUÉ. Sin profiling, optimizás a ciegas.
❌ Asumir que el Inspector General ya existe.
✅ A fecha de esta edición (2026), sigue en desarrollo. Usá `bevy_inspector_egui`.
💡 Por qué: el working group se formó en octubre 2025. Sin release público. La promesa de que "ya hay un editor" esprematura.
Problema: tu juego va a 30 fps en una máquina decente. No sabés por qué. Probás cosas al azar. Rompés algo que funcionaba. No avanzás.
Solución: usá las herramientas. Mirá los datos. Optimizá lo que se mide.
1. ¿CPU o GPU bound? → Tracy, ver CPU time vs GPU time.
2. ¿Qué sistema? → Tracy, ordenar por duración.
3. ¿Qué draw call? → RenderDoc, lista de draws.
4. ¿Qué shader? → Tracy + RenderDoc + log de compilación WGSL.
5. ¿Qué evento? → Tracy event log.
Cuándo sí:
Cuándo no:
bevy_inspector_egui y su uso con Reflect.splo.vscode-bevy-inspector, el IDE BerrysCode, scripts Python/Node).wgpu tracing para bajo nivel.Capítulo 27 (intermedio): patrones avanzados de Bevy. Sistemas como plugins, asset hot-reload, BRP, scripting de datos. Y un bonus: cómo estructurar un proyecto Bevy que va a vivir más de 6 meses. Spoiler: si no separás lib.rs y main.rs desde el día uno, lo vas a lamentar.