chunk_saving_auto/
chunk_saving_auto.rs1use bevy::prelude::*;
6use chunky_bevy::prelude::*;
7use serde::{Deserialize, Serialize};
8
9fn main() {
10 App::new()
11 .add_plugins(DefaultPlugins)
12 .add_plugins(ChunkyPlugin::default())
13 .add_plugins(
14 ChunkSavingPlugin::new("saves/auto_world")
15 .with_auto_save()
16 .with_auto_load(),
17 )
18 .register_chunk_data::<TerrainData>()
19 .insert_resource(ChunkUnloadLimit { max_chunks: 50 })
21 .insert_resource(ChunkUnloadByDistance)
22 .add_systems(Startup, setup)
23 .add_systems(Update, (move_loader, show_info, visualize_chunks))
24 .run();
25}
26
27#[derive(Component, Serialize, Deserialize, Clone, Debug)]
28struct TerrainData {
29 height: f32,
30 moisture: f32,
31}
32
33fn setup(mut commands: Commands) {
34 commands.spawn((
36 Camera3d::default(),
37 Transform::from_xyz(0.0, 100.0, 0.0).looking_at(Vec3::ZERO, Vec3::Z),
38 ));
39
40 commands.spawn((
42 Transform::default(),
43 ChunkLoader(IVec3::new(3, 0, 3)),
44 ChunkUnloadRadius(IVec3::new(5, 0, 5)),
45 Mover,
46 ));
47
48 info!("WASD to move loader. Chunks auto-save on unload, auto-load on spawn.");
49}
50
51#[derive(Component)]
52struct Mover;
53
54fn move_loader(
55 keys: Res<ButtonInput<KeyCode>>,
56 time: Res<Time>,
57 mut movers: Query<&mut Transform, With<Mover>>,
58) {
59 let speed = 30.0;
60 let mut dir = Vec3::ZERO;
61
62 if keys.pressed(KeyCode::KeyW) {
63 dir.z -= 1.0;
64 }
65 if keys.pressed(KeyCode::KeyS) {
66 dir.z += 1.0;
67 }
68 if keys.pressed(KeyCode::KeyA) {
69 dir.x -= 1.0;
70 }
71 if keys.pressed(KeyCode::KeyD) {
72 dir.x += 1.0;
73 }
74
75 if dir != Vec3::ZERO {
76 let delta = dir.normalize() * speed * time.delta_secs();
77 for mut transform in movers.iter_mut() {
78 transform.translation += delta;
79 }
80 }
81}
82
83fn show_info(
84 chunks: Query<&ChunkPos, With<Chunk>>,
85 movers: Query<&Transform, With<Mover>>,
86 chunk_manager: Res<ChunkManager>,
87) {
88 static mut FRAME: u32 = 0;
90 unsafe {
91 FRAME += 1;
92 if FRAME % 120 != 0 {
93 return;
94 }
95 }
96
97 let count = chunks.iter().count();
98 if let Ok(transform) = movers.single() {
99 let loader_chunk = chunk_manager.get_chunk_pos(&transform.translation);
100 info!(
101 "Loader at chunk {:?}, {} chunks loaded",
102 loader_chunk, count
103 );
104 }
105}
106
107fn visualize_chunks(
108 chunks: Query<(&ChunkPos, Option<&TerrainData>), With<Chunk>>,
109 movers: Query<&Transform, With<Mover>>,
110 mut gizmos: Gizmos,
111) {
112 let chunk_size = 10.0;
113
114 for (pos, terrain) in chunks.iter() {
115 let world_pos = pos.0.as_vec3() * chunk_size + Vec3::new(5.0, 0.0, 5.0);
116
117 let color = if terrain.is_some() {
118 Color::srgb(0.2, 0.8, 0.2)
119 } else {
120 Color::srgb(0.5, 0.5, 0.5)
121 };
122
123 gizmos.rect(
124 Isometry3d::new(
125 world_pos,
126 Quat::from_rotation_x(std::f32::consts::FRAC_PI_2),
127 ),
128 Vec2::splat(chunk_size - 0.5),
129 color,
130 );
131 }
132
133 if let Ok(transform) = movers.single() {
135 gizmos.sphere(
136 Isometry3d::from_translation(transform.translation),
137 2.0,
138 Color::srgb(1.0, 1.0, 0.0),
139 );
140 }
141}