Skip to main content

world_freeze_entities/
world_freeze_entities.rs

1use brdb::{Brdb, EntityChunkSoA, IntoReader, pending::BrPendingFs};
2use std::path::PathBuf;
3
4/// Opens a world and freezes all its entities
5fn main() -> Result<(), Box<dyn std::error::Error>> {
6    let src = PathBuf::from("world.brdb");
7    let dst = PathBuf::from("world_patched.brdb");
8
9    assert!(src.exists());
10
11    let db = Brdb::open(src)?.into_reader();
12
13    let chunks = db.entity_chunk_index()?;
14    let entity_schema = db.entities_schema()?;
15    let global_data = db.global_data()?;
16    let mut chunk_files = vec![];
17
18    for index in chunks {
19        // Entity_chunk loads entities and their entity data
20        let entities = db.entity_chunk(index)?;
21
22        // Re-assemble the soa. using add_entity ensures the extra data is correctly handled
23        let mut soa = EntityChunkSoA::default();
24        for mut e in entities.into_iter() {
25            e.frozen = true;
26            soa.add_entity(&global_data, &e, e.id.unwrap() as u32);
27        }
28
29        chunk_files.push((
30            format!("{index}.mps"),
31            // EntityChunkSoA::to_bytes ensures the extra data is written after the SoA data
32            BrPendingFs::File(Some(soa.to_bytes(&entity_schema)?)),
33        ));
34    }
35
36    let patch = BrPendingFs::Root(vec![(
37        "World".to_owned(),
38        BrPendingFs::Folder(Some(vec![(
39            "0".to_string(),
40            BrPendingFs::Folder(Some(vec![(
41                "Entities".to_string(),
42                BrPendingFs::Folder(Some(vec![(
43                    "Chunks".to_string(),
44                    BrPendingFs::Folder(Some(chunk_files)),
45                )])),
46            )])),
47        )])),
48    )]);
49
50    // Use .to_pending_patch() if you want to update the same world
51    let pending = db.to_pending()?.with_patch(patch)?;
52    if dst.exists() {
53        std::fs::remove_file(&dst)?;
54    }
55    Brdb::new(&dst)?.write_pending("Freeze Entities", pending)?;
56
57    // Ensure entities can be read
58    let db = Brdb::open(dst)?.into_reader();
59    let chunks = db.entity_chunk_index()?;
60    for index in chunks {
61        let _ = db.entity_chunk(index)?;
62    }
63
64    Ok(())
65}