# bevy_trenchbroom [![crates.io](https://img.shields.io/crates/v/bevy_trenchbroom)](https://crates.io/crates/bevy_trenchbroom) [![docs.rs](https://docs.rs/bevy_trenchbroom/badge.svg)](https://docs.rs/bevy_trenchbroom) Quake level loading for Bevy! More specifically, integration and support for the following workflows: - TrenchBroom -> .map -> Bevy - TrenchBroom -> .map -> ericw-tools -> .bsp -> Bevy Arcane Dimensions - Tears of the False God .bsp loaded and rendered in Bevy

> NOTICE: This crate is on low maintenance/life support. I love working in TrenchBroom, but I only have so much time, and would like to instead allocate it to Bevy editor tooling that feels as good to use as TrenchBroom. > > I'll still update to new Bevy versions until said tooling is realized, but I almost certainly won't add any new major features. # Quickstart - Add the `bevy_trenchbroom` to your project: `cargo add bevy_trenchbroom`. - Add `TrenchBroomPlugins` with a supplied `TrenchBroomConfig` to your app like so: ```rust no_run use bevy::prelude::*; use bevy_trenchbroom::prelude::*; fn main() { App::new() // ... .add_plugins(TrenchBroomPlugins(TrenchBroomConfig::new("your_game_name"))) // ... ; } ``` You can configure `TrenchBroomConfig` through a builder syntax. Quake's entity classes are treated as an analog to Bevy's components. Here is an example of a simple point class: ```rust use bevy::prelude::*; use bevy_trenchbroom::prelude::*; #[point_class] #[derive(Default)] struct MyClass { property_a: f32, property_b: String, } ``` Now just run your game once, and it should automatically be available in TrenchBroom! For more comprehensive documentation on this topic, see [the manual](https://docs.rs/bevy_trenchbroom/latest/bevy_trenchbroom/manual/index.html). ## Loading maps Now that you have your environment setup, and have assumedly created your map, loading it is pretty easy. ```rust use bevy::prelude::*; use bevy_trenchbroom::prelude::*; // app.add_systems(Startup, spawn_test_map) fn spawn_test_map( mut commands: Commands, asset_server: Res, ) { commands.spawn(WorldAssetRoot(asset_server.load("maps/test.map#Scene"))); // Or, if you're using BSPs. commands.spawn(WorldAssetRoot(asset_server.load("maps/test.bsp#Scene"))); } ``` ## Materials and `bevy_materialize` Because Bevy's material system so heavily relies on generics, storing and inserting arbitrary materials at runtime is challenging. To this end, i've created the [bevy_materialize crate](https://github.com/Noxmore/bevy_materialize), which `bevy_trenchbroom` uses. `TrenchBroomPlugins` Automatically adds `MaterializePlugin` with the default `toml` deserializer. If you wish to use a different deserializer, add your own `MaterializePlugin` before adding `TrenchBroomPlugins`. Texture loaders for loose and embedded textures can be changed in `TrenchBroomConfig`. The default loader for loose textures first looks for `.`. `` is also defined in your config, and is "toml" by default. If the file can't be found, it then tries to load `.` into a `StandardMaterial` as a fallback. `` can similarly changed in your config. The fallback is very useful because if you have a bunch of simple textures where the material file would look something like ```toml [material] base_color_texture = "example.png" ``` it can get a bit repetitive. You can also configure the rest of the properties of the default material in `MaterializePlugin`. ## BSP `bevy_trenchbroom` supports BSP loading via the [qbsp](https://github.com/Noxmore/qbsp) crate when the `bsp` feature is activated. For more information, please see [the manual](https://docs.rs/bevy_trenchbroom/latest/bevy_trenchbroom/manual/index.html#bsp). ## Physics/Collisions `bevy_trenchbroom` supports [avian3d](https://crates.io/crates/avian3d) to easily add colliders when spawning geometry. Other physics engines aren't built-in, but can be integrated by enabling the `physics-integration` feature, implementing the `PhysicsBackend` trait, and adding it through `TrenchBroomPhysicsPlugin`. To use the Avian integration, enable the `avian_f32` feature (or `avian_f64` if you use double-precision). Now you can either call `convex_collider` or `trimesh_collider` on your class's `SceneHooks` to create the respective type of collider(s) with said geometry. TIP: If you want Brush entities to have a collider by *default*, you can add this to your `TrenchBroomConfig`: ```rust ignore .default_solid_scene_hooks(|| SceneHooks::new().convex_collider()) ``` ## Multiplayer For dedicated servers `bevy_trenchbroom` supports headless mode by turning off its `client` feature. e.g. ```toml bevy_trenchbroom = { version = "...", default-features = false } ``` # Migration Guide See the [Migration Guide](https://github.com/Noxmore/bevy_trenchbroom/blob/main/Migration%20Guide.md) when updating between versions! # Version support table | Bevy | bevy_trenchbroom | TrenchBroom | ericw-tools | Avian | |------|------------------|---------------|---------------|-------| | 0.19 | 0.14 | 2026.1 | 2.0.0-alpha11 | 0.7 | | 0.18 | 0.12-0.13 | 2025.4 | 2.0.0-alpha10 | 0.5 | | 0.17 | 0.10-0.11 | 2025.3 | 2.0.0-alpha10 | 0.4 | | 0.16 | 0.8-0.9 | 2025.3 | 2.0.0-alpha9 | N/A | | 0.15 | 0.6-0.7 | 2025.1-2025.2 | N/A | N/A | | 0.14 | 0.4-0.5 | 2024.1 | N/A | N/A | | 0.13 | 0.1-0.3 | 2024.1 | N/A | N/A | There is a good chance other versions of TrenchBroom and ericw-tools will work, especially close ones, these are just the versions we officially support.