Skip to content

Add BSN scene writer: serialize ECS World to .bsn text#23639

Draft
jbuehler23 wants to merge 3 commits intobevyengine:mainfrom
jbuehler23:bsn-writer-catalog
Draft

Add BSN scene writer: serialize ECS World to .bsn text#23639
jbuehler23 wants to merge 3 commits intobevyengine:mainfrom
jbuehler23:bsn-writer-catalog

Conversation

@jbuehler23
Copy link
Copy Markdown
Contributor

@jbuehler23 jbuehler23 commented Apr 3, 2026

Objective

Addresses item 1 in #23637 and fills the gap called out in #23630: writing a World to BSN

Solution

Adds a BSN writer module to bevy_scene2 that serializes ECS entities and components to valid .bsn text.

Key features:

  • Configurable component filtering via BsnWriterConfig
  • Somewhat-sensible defaults that skip internal Bevy runtime components
  • Field-level default-diffing (only emits fields that differ from defaults)
  • Full enum variant serialization (unit, struct, and tuple variants with field data)
  • Handle to asset path resolution
  • Entity hierarchy preservation via Children blocks
  • Multi-root scene support

Example

See examples/scene/bsn_writer.rs. Press S for default output, D for custom config that also skips camera components.

Output from pressing D (custom config skipping camera internals):

bevy_ecs::hierarchy::Children [
    #Floor
    bevy_mesh::components::Mesh3d(...)
    bevy_pbr::mesh_material::MeshMaterial3d<...>(...)
    bsn_writer::CollisionShape::Box {
        width: 10.0,
        height: 0.1,
        depth: 10.0,
    }
    bevy_ecs::hierarchy::Children [
        #Cube
        bevy_transform::components::transform::Transform {
            translation: glam::Vec3 {
                x: 0.0,
                y: 0.5,
                z: 0.0,
            },
        }
        bevy_mesh::components::Mesh3d(...)
        bevy_pbr::mesh_material::MeshMaterial3d<...>(...)
        bsn_writer::CollisionShape::Sphere {
            radius: 0.5,
        }
    ]
    ,
    #Camera
    bevy_transform::components::transform::Transform {
        translation: glam::Vec3 { x: 0.0, y: 5.0, z: 10.0 },
        rotation: glam::Quat { x: -0.22, y: 0.0, z: 0.0, w: 0.97 },
    }
    ,
    #Light
    bevy_transform::components::transform::Transform {
        rotation: glam::Quat { x: -0.46, y: 0.21, z: -0.11, w: 0.85 },
    }
]

Things to note:

  • Transform only emits non-default fields (Light has no translation/scale, Cube has no rotation/scale)
  • Enum struct variants include field data (CollisionShape::Box { width: 10.0, ... })
  • Custom config strips camera internals while keeping transforms

Follow-up

I plan to wrap this in an ergonomic API (e.g. SceneDocument) in a subsequent PR, but wanted to land the core serialization first. The full roadmap is tracked in #23637.

Testing

Used in Jackdaw for scene save/load, copy/paste, and asset catalog serialization.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 3, 2026

The generated examples/README.md is out of sync with the example metadata in Cargo.toml or the example readme template. Please run cargo run -p build-templated-pages -- update examples to update it, and commit the file change.

@jbuehler23 jbuehler23 force-pushed the bsn-writer-catalog branch 6 times, most recently from 4ae3966 to bab14ea Compare April 3, 2026 12:40
@jbuehler23 jbuehler23 force-pushed the bsn-writer-catalog branch from 6309691 to 896606f Compare April 3, 2026 12:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: No status

Development

Successfully merging this pull request may close these issues.

2 participants