Skip to content
This repository has been archived by the owner on Jul 1, 2024. It is now read-only.

Add light updates #15

Draft
wants to merge 58 commits into
base: main
Choose a base branch
from
Draft
Changes from 1 commit
Commits
Show all changes
58 commits
Select commit Hold shift + click to select a range
d34916c
Add light network packet
DimitriTimoz Nov 8, 2023
f2e9c2e
Array to BitSet ChunkData
DimitriTimoz Nov 8, 2023
657e9f0
Setter HeightMap and Getter WIP
DimitriTimoz Nov 8, 2023
a14c53f
The heightMap
DimitriTimoz Nov 10, 2023
07c1fbf
Fix somethings
DimitriTimoz Nov 10, 2023
addb975
Add heightmap to ChunkColumn (must be tested)
DimitriTimoz Nov 10, 2023
6e43296
Use the height and not the coordinate
DimitriTimoz Nov 11, 2023
d2b5de2
New base & setter when edit block WIP
DimitriTimoz Nov 11, 2023
0263e4e
Add HeightMap is updated impl
DimitriTimoz Nov 11, 2023
12a5ec4
Add SectionLightData structure & setter/getter
DimitriTimoz Nov 11, 2023
a3ecae9
sky light init done
DimitriTimoz Nov 11, 2023
1a57c64
Change is_air_block to is_transparent
DimitriTimoz Nov 11, 2023
97a77a1
Add Test for set and getter
DimitriTimoz Nov 11, 2023
635cef5
Set Layer of light
DimitriTimoz Nov 11, 2023
42a7310
Set region & more
DimitriTimoz Nov 12, 2023
c4b4207
Init skylight FlatChunk
DimitriTimoz Nov 12, 2023
2b46155
Add get_hiest_block_at
DimitriTimoz Nov 12, 2023
6bbf96a
Use more appropriate conversion to Block
DimitriTimoz Nov 12, 2023
ad61f59
WIP explore_sky_light_from_heap
DimitriTimoz Nov 12, 2023
d60d6bc
Fix update light from highest block break
DimitriTimoz Nov 12, 2023
fa8484f
fix heightMap
DimitriTimoz Nov 13, 2023
1e17721
Flat world light update
DimitriTimoz Nov 13, 2023
adfd07f
get network heightMap
DimitriTimoz Nov 13, 2023
9a43a43
Merge branch 'main' into light-updates
DimitriTimoz Nov 13, 2023
9b550c4
Impl default for Slot
DimitriTimoz Nov 13, 2023
ddbe987
Refactor chunk loading and sending code
DimitriTimoz Nov 13, 2023
985da34
Remove get heightMap network
DimitriTimoz Nov 14, 2023
366c161
wip pose block & update light
DimitriTimoz Nov 14, 2023
903eaa1
roll back
DimitriTimoz Nov 14, 2023
8409239
fix load amount chunk
DimitriTimoz Nov 18, 2023
dbfccb3
Flat world update sky light
DimitriTimoz Nov 18, 2023
aa5b002
Fix clear light from
DimitriTimoz Nov 18, 2023
ead4294
backpropagation of light to edit
DimitriTimoz Nov 18, 2023
2bebed7
Refactor sky light calculations and add unit tests
DimitriTimoz Nov 18, 2023
7b45ce0
A bit closer
DimitriTimoz Nov 19, 2023
9c51cba
merge main
DimitriTimoz Nov 19, 2023
7ec12c5
Back to clean code
DimitriTimoz Nov 19, 2023
8df445e
Put architecture
DimitriTimoz Nov 19, 2023
eb13f2e
WIP abstraction
DimitriTimoz Nov 19, 2023
76ec292
Abstraction set block
DimitriTimoz Nov 22, 2023
8573b33
Fix compile
DimitriTimoz Nov 22, 2023
8b213f5
Await the light updating
DimitriTimoz Nov 22, 2023
cfc501b
Fix warnings
DimitriTimoz Nov 22, 2023
2f60466
add abstraction signatures
DimitriTimoz Nov 22, 2023
a9f16a1
Refactor LightManager to use world_map parameter
DimitriTimoz Nov 22, 2023
b52d854
sorry
DimitriTimoz Dec 21, 2023
d868965
Do compile it
DimitriTimoz Dec 23, 2023
7f656b2
Init independant light
DimitriTimoz Dec 23, 2023
34d2e14
Merge pull request #98 from Mubelotix/main
DimitriTimoz Dec 23, 2023
dee1745
Tracing
DimitriTimoz Dec 23, 2023
94ebe62
some instruments
DimitriTimoz Dec 24, 2023
05ed0fd
tracy p64
DimitriTimoz Dec 24, 2023
2ee546e
enable tracing with feature
DimitriTimoz Dec 24, 2023
b596e28
line feeding
DimitriTimoz Dec 24, 2023
111270c
player tick span
DimitriTimoz Dec 24, 2023
2eb5b4d
span in feature
DimitriTimoz Dec 24, 2023
a610fdf
Merge branch 'light-updates' into tracing-system
DimitriTimoz Dec 24, 2023
75cf2f5
Merge pull request #100 from Mubelotix/tracing-system
DimitriTimoz Dec 24, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
some instruments
DimitriTimoz committed Dec 24, 2023
commit 94ebe622c47b74ffb3dbffe3d75f414e492257d6
1 change: 1 addition & 0 deletions minecraft-entities-derive/examples/main.rs
Original file line number Diff line number Diff line change
@@ -17,6 +17,7 @@ enum AnyEntity {
Cow(Cow),
}

#[derive(Debug)]
pub struct Handler<T> {
uuid: Eid,
world: Arc<Mutex<()>>,
2 changes: 1 addition & 1 deletion minecraft-server/Cargo.toml
Original file line number Diff line number Diff line change
@@ -17,7 +17,7 @@ tracy-client = { version = "0.16.4", features = ["enable"] }
tracing-tracy = { version = "0.10.4", features = ["enable", "system-tracing"] }
tracing-subscriber = "0.3.18"
log = "0.4.17"
tracing = "0.1"
tracing = { version = "0.1", features = ["attributes"] }

[features]
default = []
3 changes: 3 additions & 0 deletions minecraft-server/src/entities/entity.rs
Original file line number Diff line number Diff line change
@@ -7,6 +7,8 @@ use super::*;
init(self, server_msg_rcvr: BroadcastReceiver<ServerMessage>);
}
)]

#[derive(Debug)]
pub struct Entity {
pub position: Position,
pub velocity: Translation,
@@ -29,6 +31,7 @@ pub struct Entity {
}

impl Handler<Entity> {
#[instrument(skip_all)]
pub async fn init(self, server_msg_rcvr: BroadcastReceiver<ServerMessage>) {
self.insert_task("newton", tokio::spawn(newton_task(self.clone(), server_msg_rcvr))).await;
}
7 changes: 7 additions & 0 deletions minecraft-server/src/entities/player.rs
Original file line number Diff line number Diff line change
@@ -87,6 +87,7 @@ impl Player {
}

impl Handler<Player> {
#[instrument(skip_all)]
async fn update_center_chunk(self) {
let Some((old_center_chunk, new_center_chunk, render_distance)) = self.mutate(|player| {
let old_center_chunk = player.center_chunk.clone();
@@ -172,6 +173,7 @@ impl Handler<Player> {
}
}

#[instrument(skip_all)]
async fn send_packet<'a>(&self, packet: PlayClientbound<'a>) {
let packet = packet.serialize_minecraft_packet().unwrap();
let packets_sent = self.mutate(|player| {
@@ -185,6 +187,7 @@ impl Handler<Player> {
packet_sender.send(packet).await.unwrap();
}

#[instrument(skip_all)]
async fn on_server_message(self, message: ServerMessage) {
use ServerMessage::*;
match message {
@@ -201,6 +204,7 @@ impl Handler<Player> {
}
}

#[instrument(skip_all)]
async fn on_world_change(self, change: WorldChange) {
match change {
WorldChange::Block(position, block) => {
@@ -293,6 +297,7 @@ impl Handler<Player> {
}
}

#[instrument(skip_all)]
async fn on_packet<'a>(mut self, packet: PlayServerbound<'a>) {
use PlayServerbound::*;
match packet {
@@ -367,6 +372,7 @@ impl Handler<Player> {
}
}

#[instrument(skip_all)]
async fn handle_player(h: Handler<Player>, uuid: UUID, stream: TcpStream, packet_receiver: MpscReceiver<Vec<u8>>, server_msg_rcvr: BroadcastReceiver<ServerMessage>, change_receiver: MpscReceiver<WorldChange>) {
let r = handle_player_inner(h.clone(), stream, packet_receiver, server_msg_rcvr, change_receiver).await;
match r {
@@ -376,6 +382,7 @@ async fn handle_player(h: Handler<Player>, uuid: UUID, stream: TcpStream, packet
h.world.remove_loader(uuid).await;
}

#[instrument(skip_all)]
async fn handle_player_inner(h: Handler<Player>, stream: TcpStream, mut packet_receiver: MpscReceiver<Vec<u8>>, mut server_msg_rcvr: BroadcastReceiver<ServerMessage>, mut change_receiver: MpscReceiver<WorldChange>) -> Result<(), ()> {
let (mut reader_stream, mut writer_stream) = stream.into_split();

1 change: 0 additions & 1 deletion minecraft-server/src/main.rs
Original file line number Diff line number Diff line change
@@ -37,7 +37,6 @@ async fn main() {
tracing::subscriber::set_global_default(subscriber)
.expect("setting up tracing");


env_logger::init();

let server = ServerBehavior::init().await;
2 changes: 2 additions & 0 deletions minecraft-server/src/player_handler/connect.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
use super::*;


#[instrument(skip_all)]
pub async fn handle_connection(
mut stream: TcpStream,
addr: SocketAddr,
2 changes: 2 additions & 0 deletions minecraft-server/src/player_handler/handshake.rs
Original file line number Diff line number Diff line change
@@ -14,6 +14,8 @@ pub struct PlayerInfo {
pub allow_server_listing: bool,
}


#[instrument(skip_all)]
pub async fn handshake(stream: &mut TcpStream, logged_in_player_info: LoggedInPlayerInfo, world: &'static World) -> Result<(PlayerInfo, MpscReceiver<WorldChange>), ()> {
// Receive client informations
let packet = receive_packet(stream).await?;
1 change: 1 addition & 0 deletions minecraft-server/src/player_handler/login.rs
Original file line number Diff line number Diff line change
@@ -6,6 +6,7 @@ pub struct LoggedInPlayerInfo {
pub(super) uuid: u128,
}

#[instrument(skip_all)]
pub async fn login(stream: &mut TcpStream, addr: SocketAddr) -> Result<LoggedInPlayerInfo, ()> {
// Receive login start
let packet = receive_packet(stream).await?;
3 changes: 3 additions & 0 deletions minecraft-server/src/player_handler/network.rs
Original file line number Diff line number Diff line change
@@ -48,20 +48,23 @@ pub async fn receive_packet_split(stream: &mut OwnedReadHalf) -> Result<Vec<u8>,
Ok(data)
}

#[instrument]
pub async fn send_packet_raw(stream: &mut TcpStream, packet: &[u8]) {
let length = VarInt::from(packet.len());
stream.write_all(length.serialize_minecraft_packet().unwrap().as_slice()).await.unwrap();
stream.write_all(packet).await.unwrap();
stream.flush().await.unwrap();
}

#[instrument]
pub async fn send_packet_raw_split(stream: &mut OwnedWriteHalf, packet: &[u8]) {
let length = VarInt::from(packet.len());
stream.write_all(length.serialize_minecraft_packet().unwrap().as_slice()).await.unwrap();
stream.write_all(packet).await.unwrap();
stream.flush().await.unwrap();
}

#[instrument(skip_all)]
pub async fn send_packet<'a, P: MinecraftPacketPart<'a>>(stream: &mut TcpStream, packet: P) {
let packet = packet.serialize_minecraft_packet().unwrap();
send_packet_raw(stream, packet.as_slice()).await;
1 change: 1 addition & 0 deletions minecraft-server/src/player_handler/status.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use super::*;

#[instrument(skip_all)]
pub async fn status(stream: &mut TcpStream) -> Result<(), ()> {
loop {
let packet = receive_packet(stream).await?;
2 changes: 1 addition & 1 deletion minecraft-server/src/prelude.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
pub use crate::{entities::*, player_handler::*, server_behavior::*, world::*};
pub use futures::FutureExt;
pub use tracing::{debug, error, info, trace, warn};
pub use tracing::{debug, error, info, trace, warn, instrument};
pub use minecraft_protocol::{
components::{
chat::ChatMode,
9 changes: 8 additions & 1 deletion minecraft-server/src/world/ecs.rs
Original file line number Diff line number Diff line change
@@ -6,6 +6,7 @@ use tokio::sync::RwLock;
pub type EntityTask = Pin<Box<dyn Future<Output = ()> + Send + Sync + 'static>>;
pub type EntityTaskHandle = tokio::task::JoinHandle<()>;


pub struct Entities {
eid_counter: std::sync::atomic::AtomicU32,
uuid_counter: std::sync::atomic::AtomicU64,
@@ -30,12 +31,14 @@ impl Entities {
}

/// Observe an entity through a closure
#[instrument(skip_all)]
pub(super) async fn observe_entity<R>(&self, eid: Eid, observer: impl FnOnce(&AnyEntity) -> R) -> Option<R> {
self.entities.read().await.get(&eid).map(observer)
}

/// Observe entities in a chunk through a closure
/// That closure will be applied to each entity, and the results will be returned in a vector
#[instrument(skip_all)]
pub(super) async fn observe_entities<R>(&self, chunk: ChunkColumnPosition, mut observer: impl FnMut(&AnyEntity) -> Option<R>) -> Vec<R> {
let entities = self.entities.read().await;
let chunks = self.chunks.read().await;
@@ -52,6 +55,7 @@ impl Entities {
}

/// Mutate an entity through a closure
#[instrument(skip_all)]
pub(super) async fn mutate_entity<R>(&self, eid: Eid, mutator: impl FnOnce(&mut AnyEntity) -> (R, EntityChanges)) -> Option<(R, EntityChanges)> {
let mut entities = self.entities.write().await;

@@ -72,6 +76,7 @@ impl Entities {
}
}

#[instrument(skip_all)]
pub(super) async fn spawn_entity<E>(&self, entity: AnyEntity, world: &'static World, receiver: BroadcastReceiver<ServerMessage>) -> (Eid, UUID)
where AnyEntity: TryAsEntityRef<E>, Handler<E>: EntityExt
{
@@ -90,7 +95,8 @@ impl Entities {
h.init(receiver).await;
(eid, uuid)
}


#[instrument(skip_all)]
pub(super) async fn insert_entity_task(&self, eid: Eid, name: &'static str, handle: EntityTaskHandle) {
let mut entity_tasks = self.entity_tasks.write().await;
let old = entity_tasks.entry(eid).or_insert(HashMap::new()).insert(name, handle);
@@ -100,6 +106,7 @@ impl Entities {
}

/// Remove an entity
#[instrument(skip_all)]
pub(super) async fn remove_entity(&self, eid: Eid) -> Option<AnyEntity> {
let entity = self.entities.write().await.remove(&eid);
let mut chunks = self.chunks.write().await;
3 changes: 2 additions & 1 deletion minecraft-server/src/world/loading_manager.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
use crate::prelude::*;

#[derive(Default)]
#[derive(Default, Debug)]
pub(super) struct WorldLoadingManager {
loaded_chunks: HashMap<UUID, HashSet<ChunkColumnPosition>>,
loader_entities: HashMap<ChunkColumnPosition, HashSet<UUID>>,
}

impl WorldLoadingManager {
#[instrument(skip_all)]
pub(super) fn update_loaded_chunks(&mut self, uuid: UUID, loaded_chunks: HashSet<ChunkColumnPosition>) {
let loaded_before = self.loaded_chunks.entry(uuid).or_default();
for just_unloaded in loaded_before.difference(&loaded_chunks) {
6 changes: 6 additions & 0 deletions minecraft-server/src/world/map.rs
Original file line number Diff line number Diff line change
@@ -52,6 +52,7 @@ impl Chunk {
&self.data
}

#[instrument(skip_all)]
fn get_block(&self, position: BlockPositionInChunk) -> BlockWithState {
match &self.data.blocks {
PalettedData::Paletted { palette, indexed } => {
@@ -72,6 +73,7 @@ impl Chunk {
}

// TODO edit block_count in data
#[instrument(skip_all)]
fn set_block(&mut self, position: BlockPositionInChunk, block: BlockWithState) {
let block_state_id = block.block_state_id().unwrap_or_else(|| {
error!("Tried to set block with invalid state {block:?}. Placing air"); 0
@@ -230,6 +232,7 @@ impl WorldMap {
WorldMap { shard_count, shards }
}

#[instrument(skip_all)]
pub async fn get_block(&self, position: BlockPosition) -> BlockWithState {
async fn inner_get_block(s: &WorldMap, position: BlockPosition) -> Option<BlockWithState> {
let chunk_position = position.chunk();
@@ -256,6 +259,7 @@ impl WorldMap {
Some(chunk.as_network_chunk().clone())
}

#[instrument(skip_all)]
pub async fn set_block(&self, position: BlockPosition, block: BlockWithState) {
async fn inner_get_block(s: &WorldMap, position: BlockPosition, block: BlockWithState) -> Option<()> {
let chunk_position = position.chunk();
@@ -271,6 +275,7 @@ impl WorldMap {
inner_get_block(self, position, block).await;
}

#[instrument(skip_all)]
pub async fn try_move(&self, object: &CollisionShape, movement: &Translation) -> Translation {
// TODO(perf): Optimize Map.try_move by preventing block double-checking
// Also lock the map only once
@@ -288,6 +293,7 @@ impl WorldMap {
movement.clone() // Would be more logic if it returned validated, but this way we avoid precision errors
}

#[instrument(skip_all)]
pub async fn load(&self, position: ChunkColumnPosition) {
let chunk = ChunkColumn::flat(); // TODO: load from disk
let shard = position.shard(self.shard_count);