mirror of
https://github.com/Noratrieb/game-wip-dontplay.git
synced 2026-01-17 04:45:02 +01:00
First phase of serialization
This commit is contained in:
parent
aed3e86a17
commit
6896698883
7 changed files with 152 additions and 15 deletions
45
Cargo.lock
generated
45
Cargo.lock
generated
|
|
@ -136,6 +136,9 @@ name = "cc"
|
||||||
version = "1.0.79"
|
version = "1.0.79"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f"
|
checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f"
|
||||||
|
dependencies = [
|
||||||
|
"jobserver",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cfg-expr"
|
name = "cfg-expr"
|
||||||
|
|
@ -550,6 +553,15 @@ dependencies = [
|
||||||
"windows-sys 0.48.0",
|
"windows-sys 0.48.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "jobserver"
|
||||||
|
version = "0.1.26"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "936cfd212a0155903bcbc060e316fb6cc7cbf2e1907329391ebadc1fe0ce77c2"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "js-sys"
|
name = "js-sys"
|
||||||
version = "0.3.61"
|
version = "0.3.61"
|
||||||
|
|
@ -631,6 +643,7 @@ dependencies = [
|
||||||
"sfml",
|
"sfml",
|
||||||
"sfml-xt",
|
"sfml-xt",
|
||||||
"worldgen",
|
"worldgen",
|
||||||
|
"zstd",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -929,9 +942,9 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "s2dc"
|
name = "s2dc"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/crumblingstatue/s2dc.git#468ab3ca6de2d05f1eb5cdd8d869055d9157fb76"
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"num-traits",
|
"num-traits",
|
||||||
|
"serde",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -1404,3 +1417,33 @@ name = "worldgen"
|
||||||
version = "0.5.3"
|
version = "0.5.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a9b77fba24c873b60af296c1f0c5639114186d1ac3c99f880a7bb590bdc04065"
|
checksum = "a9b77fba24c873b60af296c1f0c5639114186d1ac3c99f880a7bb590bdc04065"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "zstd"
|
||||||
|
version = "0.12.3+zstd.1.5.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "76eea132fb024e0e13fd9c2f5d5d595d8a967aa72382ac2f9d39fcc95afd0806"
|
||||||
|
dependencies = [
|
||||||
|
"zstd-safe",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "zstd-safe"
|
||||||
|
version = "6.0.5+zstd.1.5.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d56d9e60b4b1758206c238a10165fbcae3ca37b01744e394c463463f6529d23b"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
"zstd-sys",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "zstd-sys"
|
||||||
|
version = "2.0.8+zstd.1.5.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5556e6ee25d32df2586c098bbfa278803692a20d0ab9565e049480d52707ec8c"
|
||||||
|
dependencies = [
|
||||||
|
"cc",
|
||||||
|
"libc",
|
||||||
|
"pkg-config",
|
||||||
|
]
|
||||||
|
|
|
||||||
|
|
@ -21,9 +21,12 @@ rmp-serde = "1.1.1"
|
||||||
serde = { version = "1.0.159", features = ["derive"] }
|
serde = { version = "1.0.159", features = ["derive"] }
|
||||||
log = "0.4.17"
|
log = "0.4.17"
|
||||||
env_logger = "0.10.0"
|
env_logger = "0.10.0"
|
||||||
|
zstd = "0.12.3"
|
||||||
|
|
||||||
[dependencies.s2dc]
|
[dependencies.s2dc]
|
||||||
git = "https://github.com/crumblingstatue/s2dc.git"
|
#git = "https://github.com/crumblingstatue/s2dc.git"
|
||||||
|
path = "/home/dew/projects/github/s2dc"
|
||||||
|
features = ["serde"]
|
||||||
|
|
||||||
[dependencies.sfml-xt]
|
[dependencies.sfml-xt]
|
||||||
git = "https://github.com/crumblingstatue/sfml-xt.git"
|
git = "https://github.com/crumblingstatue/sfml-xt.git"
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ Each folder has:
|
||||||
- Subfolder for regions (regions/)
|
- Subfolder for regions (regions/)
|
||||||
|
|
||||||
Each region subfolder has:
|
Each region subfolder has:
|
||||||
r.x.y.dat files for each chunk, where x and y are the region coordinates.
|
x.y.rgn files for each chunk, where x and y are the region coordinates.
|
||||||
|
|
||||||
# Regions
|
# Regions
|
||||||
A region stores multiple chunks in a single file for more optimized storage.
|
A region stores multiple chunks in a single file for more optimized storage.
|
||||||
|
|
|
||||||
14
src/app.rs
14
src/app.rs
|
|
@ -18,7 +18,6 @@ use crate::{
|
||||||
input::Input,
|
input::Input,
|
||||||
math::{center_offset, TILE_SIZE},
|
math::{center_offset, TILE_SIZE},
|
||||||
res::Res,
|
res::Res,
|
||||||
world::{ChkPosSc, TPosSc, CHUNK_EXTENT, REGION_CHUNK_EXTENT},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Application level state (includes game and ui state, etc.)
|
/// Application level state (includes game and ui state, etc.)
|
||||||
|
|
@ -74,6 +73,7 @@ impl App {
|
||||||
gamedebug_core::inc_frame();
|
gamedebug_core::inc_frame();
|
||||||
}
|
}
|
||||||
self.game.tile_db.try_save();
|
self.game.tile_db.try_save();
|
||||||
|
self.game.world.save();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn do_event_handling(&mut self) {
|
fn do_event_handling(&mut self) {
|
||||||
|
|
@ -215,14 +215,10 @@ impl App {
|
||||||
mouse_tpos.y,
|
mouse_tpos.y,
|
||||||
self.game.world.tile_at_mut(mouse_tpos, &self.game.worldgen)
|
self.game.world.tile_at_mut(mouse_tpos, &self.game.worldgen)
|
||||||
);
|
);
|
||||||
let m_chk_x = (mouse_tpos.x / CHUNK_EXTENT as TPosSc) as ChkPosSc;
|
let m_chk = mouse_tpos.to_chunk();
|
||||||
let m_chk_y = (mouse_tpos.y / CHUNK_EXTENT as TPosSc) as ChkPosSc;
|
imm!("@ chunk {}, {}", m_chk.x, m_chk.y);
|
||||||
imm!("@ chunk {m_chk_x}, {m_chk_y}");
|
let (m_chk_x, m_chk_y) = m_chk.region();
|
||||||
imm!(
|
imm!("@ region {m_chk_x}, {m_chk_y}");
|
||||||
"@ region {}, {}",
|
|
||||||
m_chk_x / REGION_CHUNK_EXTENT as ChkPosSc,
|
|
||||||
m_chk_y / REGION_CHUNK_EXTENT as ChkPosSc
|
|
||||||
);
|
|
||||||
if self.debug.freecam && self.input.pressed(Key::P) {
|
if self.debug.freecam && self.input.pressed(Key::P) {
|
||||||
self.game.world.player.col_en.en.pos.x = wpos.x as i32;
|
self.game.world.player.col_en.en.pos.x = wpos.x as i32;
|
||||||
self.game.world.player.col_en.en.pos.y = wpos.y as i32;
|
self.game.world.player.col_en.en.pos.y = wpos.y as i32;
|
||||||
|
|
|
||||||
|
|
@ -142,7 +142,7 @@ impl Default for GameState {
|
||||||
spawn_point.y -= 1104;
|
spawn_point.y -= 1104;
|
||||||
Self {
|
Self {
|
||||||
camera_offset: spawn_point,
|
camera_offset: spawn_point,
|
||||||
world: World::new(spawn_point),
|
world: World::new(spawn_point, "TestWorld"),
|
||||||
gravity: 0.55,
|
gravity: 0.55,
|
||||||
tile_to_place: 1,
|
tile_to_place: 1,
|
||||||
current_biome: Biome::Surface,
|
current_biome: Biome::Surface,
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,13 @@
|
||||||
use egui_inspect::{derive::Inspect, inspect};
|
use egui_inspect::{derive::Inspect, inspect};
|
||||||
use s2dc::{vec2, MobileEntity};
|
use s2dc::{vec2, MobileEntity};
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
math::{WorldPos, TILE_SIZE},
|
math::{WorldPos, TILE_SIZE},
|
||||||
world::{TPosSc, TilePos},
|
world::{TPosSc, TilePos},
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Debug, Inspect)]
|
#[derive(Debug, Inspect, Serialize, Deserialize)]
|
||||||
pub struct Player {
|
pub struct Player {
|
||||||
#[inspect_with(inspect_mobile_entity)]
|
#[inspect_with(inspect_mobile_entity)]
|
||||||
pub col_en: MobileEntity,
|
pub col_en: MobileEntity,
|
||||||
|
|
@ -50,4 +51,11 @@ impl Player {
|
||||||
pub fn feet_y(&self) -> i32 {
|
pub fn feet_y(&self) -> i32 {
|
||||||
self.col_en.en.pos.y + self.col_en.en.bb.y
|
self.col_en.en.pos.y + self.col_en.en.bb.y
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) fn save(&self) {
|
||||||
|
log::info!(
|
||||||
|
"{:?}",
|
||||||
|
std::fs::write("player.dat", rmp_serde::to_vec(self).unwrap())
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
89
src/world.rs
89
src/world.rs
|
|
@ -1,5 +1,8 @@
|
||||||
|
use std::path::Path;
|
||||||
|
|
||||||
use egui_inspect::derive::Inspect;
|
use egui_inspect::derive::Inspect;
|
||||||
use fnv::FnvHashMap;
|
use fnv::FnvHashMap;
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
use crate::{math::WorldPos, player::Player, worldgen::Worldgen};
|
use crate::{math::WorldPos, player::Player, worldgen::Worldgen};
|
||||||
|
|
||||||
|
|
@ -11,6 +14,23 @@ pub struct ChunkPos {
|
||||||
pub y: ChkPosSc,
|
pub y: ChkPosSc,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl ChunkPos {
|
||||||
|
/// Returns the region this chunk position belongs to
|
||||||
|
pub fn region(&self) -> (u8, u8) {
|
||||||
|
(
|
||||||
|
(self.x / REGION_CHUNK_EXTENT as ChkPosSc) as u8,
|
||||||
|
(self.y / REGION_CHUNK_EXTENT as ChkPosSc) as u8,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
/// Returns the local position in the region (0-7)
|
||||||
|
pub fn local(&self) -> (u8, u8) {
|
||||||
|
(
|
||||||
|
(self.x % REGION_CHUNK_EXTENT as ChkPosSc) as u8,
|
||||||
|
(self.y % REGION_CHUNK_EXTENT as ChkPosSc) as u8,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Inspect)]
|
#[derive(Debug, Inspect)]
|
||||||
pub struct World {
|
pub struct World {
|
||||||
/// The currently loaded chunks
|
/// The currently loaded chunks
|
||||||
|
|
@ -19,16 +39,79 @@ pub struct World {
|
||||||
/// In other words, the age of the world.
|
/// In other words, the age of the world.
|
||||||
pub ticks: u64,
|
pub ticks: u64,
|
||||||
pub player: Player,
|
pub player: Player,
|
||||||
|
pub name: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl World {
|
impl World {
|
||||||
pub fn new(spawn_point: WorldPos) -> Self {
|
pub fn new(spawn_point: WorldPos, name: &str) -> Self {
|
||||||
Self {
|
Self {
|
||||||
chunks: Default::default(),
|
chunks: Default::default(),
|
||||||
ticks: Default::default(),
|
ticks: Default::default(),
|
||||||
player: Player::new_at(spawn_point),
|
player: Player::new_at(spawn_point),
|
||||||
|
name: name.to_string(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
pub fn save(&self) {
|
||||||
|
log::info!("{:?}", std::fs::create_dir(&self.name));
|
||||||
|
std::env::set_current_dir(&self.name).unwrap();
|
||||||
|
self.save_meta();
|
||||||
|
self.player.save();
|
||||||
|
self.save_chunks();
|
||||||
|
}
|
||||||
|
pub fn save_meta(&self) {
|
||||||
|
let meta = WorldMetaSave {
|
||||||
|
name: self.name.clone(),
|
||||||
|
ticks: self.ticks,
|
||||||
|
};
|
||||||
|
log::info!(
|
||||||
|
"{:?}",
|
||||||
|
std::fs::write("world.dat", rmp_serde::to_vec(&meta).unwrap())
|
||||||
|
);
|
||||||
|
}
|
||||||
|
pub fn save_chunks(&self) {
|
||||||
|
for (pos, chk) in self.chunks.iter() {
|
||||||
|
let (reg_x, reg_y) = pos.region();
|
||||||
|
let reg_file_name = format!("{reg_x}.{reg_y}.rgn");
|
||||||
|
dbg!(®_file_name);
|
||||||
|
if !Path::new(®_file_name).exists() {
|
||||||
|
log::info!(
|
||||||
|
"{:?}",
|
||||||
|
std::fs::write(®_file_name, zstd::encode_all(&[][..], 0).unwrap())
|
||||||
|
);
|
||||||
|
}
|
||||||
|
let mut decomp = zstd::decode_all(&std::fs::read(®_file_name).unwrap()[..]).unwrap();
|
||||||
|
let (loc_x, loc_y) = pos.local();
|
||||||
|
dbg!(loc_x, loc_y);
|
||||||
|
let loc_idx = (loc_y * REGION_CHUNK_EXTENT) + loc_x;
|
||||||
|
dbg!(loc_idx);
|
||||||
|
let byte_idx = loc_idx as usize * CHUNK_BYTES;
|
||||||
|
dbg!(byte_idx);
|
||||||
|
let end_idx = byte_idx + CHUNK_BYTES;
|
||||||
|
dbg!(end_idx);
|
||||||
|
if decomp.len() < end_idx + 1 {
|
||||||
|
decomp.resize(end_idx + 1, 0);
|
||||||
|
}
|
||||||
|
for (i, tile) in chk.tiles.iter().enumerate() {
|
||||||
|
let off = byte_idx + (i * TILE_BYTES);
|
||||||
|
decomp[off..off + 2].copy_from_slice(&tile.bg.to_le_bytes());
|
||||||
|
decomp[off + 2..off + 4].copy_from_slice(&tile.mid.to_le_bytes());
|
||||||
|
decomp[off + 4..off + 6].copy_from_slice(&tile.fg.to_le_bytes());
|
||||||
|
}
|
||||||
|
log::info!(
|
||||||
|
"{:?}",
|
||||||
|
std::fs::write(®_file_name, zstd::encode_all(&decomp[..], 0).unwrap())
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const CHUNK_BYTES: usize = CHUNK_N_TILES * TILE_BYTES;
|
||||||
|
const TILE_BYTES: usize = 3 * 2;
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize)]
|
||||||
|
struct WorldMetaSave {
|
||||||
|
name: String,
|
||||||
|
ticks: u64,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl World {
|
impl World {
|
||||||
|
|
@ -72,6 +155,10 @@ impl TilePos {
|
||||||
};
|
};
|
||||||
(chk, local)
|
(chk, local)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) fn to_chunk(self) -> ChunkPos {
|
||||||
|
self.to_chunk_and_local().0
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn chk_pos(tile: TPosSc) -> ChkPosSc {
|
fn chk_pos(tile: TPosSc) -> ChkPosSc {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue