feather-rs / feather Goto Github PK
View Code? Open in Web Editor NEWA Minecraft server implementation in Rust
License: Apache License 2.0
A Minecraft server implementation in Rust
License: Apache License 2.0
The current script-generated block state ID mappings use an 8000 line long match
statement to find IDs. This is inefficient and is probably compiled to a linear search—a better system would either use a HashMap or a binary search for improved performance.
Depends on #60.
Resolving this issue will also resolve #10 .
This entails:
Regardless of the number of online players, the player count in the status ping is always 0.
Thanks to this code:
https://github.com/caelunshun/feather/blob/25b98de2ec93fc4d7edabb2de36f5da658ac44e6/server/src/entity/component.rs#L75-L79
the FlaggedStorage
containing entity positions is always marked as modified each tick. As a result, the server spams the client with 20 movement packets per entity per second, which causes the client to lag significantly when large quantities of entities are spawned.
amethyst/specs#613 offers a way to bypass this by not triggering the position update event when the position is reset. However, it doesn't seem like this PR will be merged, so it seems necessary to implement our own version of FlaggedStorage
with the capability to temporarily stop recording events.
Lighting will need to be calculated each time a block is updated.
For reference:
Ideally, this would be done multithreaded on a per-chunk basis.
I'm not sure how to correctly handle block updates. We could recalculate the light for the entire chunk, but this is incredibly inefficient.
Roadmap:
This page will be a useful resource.
The current architecture is a mess and uses RefCells and Rcs to get past the borrow checker. A design more like what is explored in https://kyren.github.io/2018/09/14/rustconf-talk.html will likely be significantly more idiomatic.
At the moment, physics checks which check for solid blocks simply check if the block is not air. This does not work correctly with non-solid blocks, such as grass or flowers.
I'm not sure where to obtain the data for whether or not a block is solid. It's possible it'll have to be written manually.
Certain blocks, such as beds, have non-cubic bounding boxes. This should be accounted for in physics calculations.
Currently, status pings which end off at Response rather than having the client send a ping packet remain permanently registered. A timeout should be implemented to deregister these network handles after some period of inactivity.
This only happens on the master
. Whatever the issue was, the architecture rewrite has fixed it.
I noticed that the handling of the Creative Item packet doesn't take into account the "raw slot" logic:
Essentially,
packet.slot
won't match the "inventory slot" properly. For example, "Creative Slot #0" > is not the hotbar, but the helmet slot. This mapping depends on the "top view" and "bottom view" of the inventory (think of the slots in a crafting bench, vs. the slots in a survival inventory with the equipment).In Bukkit, there is this concept of "InventoryView" which has a convert-slot function to handle this.
This is an issue because there is a desync as to which item is currently held by the player: using the "hotbar index" for the inventory slot will give the wrong item.
Originally posted by @Momothereal in #46 (comment)
The codebase has become a little cluttered over the past few weeks. After Anvil world loading is finished, a good amount of time should be spent refactoring.
It appears that the read_position
function isn't working correctly with negative numbers.
I've observed that certain blocks will randomly appear in random locations inside the chunks. Obviously, this shouldn't happen—most of these blocks don't even have ID mappings yet in the server. I have no idea what causes this issue.
The following blocks have been seen so far:
Currently, worlds can be loaded, but they are not saved.
Resolving this issue will require periodic saving of chunk data, entities, level data, and player data to world saves.
Notes:
hematite-nbt
does not support serializing NBT long arrays, which is required for writing chunk data (see PistonDevelopers/hematite_nbt#27). A PR will have to be submitted to them to fix this.Currently, f32
is used instead of f64
at random times, which requires frequent conversion between types. All physics calculations should be switched to f64
.
Vec
will also need to be switched for DVec
.
Yeah... there's a lot of these.
Currently, entity movements, actions, and such are broadcasted to all online players, regardless of distance. Ideally, players would only be notified of entities within their view distance, and entities leaving that radius should be destroyed on the client.
Much of the functionality to do this is already implemented. In particular:
ChunkHolders
type. Given the position of the chunk an entity is in, we can easily find which players can see the chunk using this type. As a result, it is easy to determine which players to send entity actions to.ChunkEntities
, so when a player joins, we can loop over the chunks within the view distance and only send them the entities in those chunks.This implementation consists of a few steps:
fn broadcast_packet<P: Packet>(chunk: ChunkPosition, chunk_holders: &ChunkHolders, entities: &Entities, packet: P, neq: Option<Entity>)
, similar to the structure of send_packet_to_all_players()
.
ChunkHolders
into Util
and having the function be a member function of Util
.This is caused by the fact that the status handling code is on the main server thread, which runs once every 50 milliseconds. To resolve this, part of the initial handler would have to be moved to the IO worker threads.
Note: I generated the world using a 1.13.2 client, and tried the same using a server-generated world. Here's a zip containing the world if it's of any help: world.zip
When I try to join, it hangs on Loading terrain
for a while, displaying the following warnings:
2019-08-19 21:50:14,795 INFO [feather_server::network] Accepting connection from 127.0.0.1:59652
2019-08-19 21:50:15,647 WARN [feather_server::chunk_logic] Failed to load chunk at ChunkPosition { x: -6, z: 6 }: The specified chunk does not exist in the world save
2019-08-19 21:50:15,898 WARN [feather_server::chunk_logic] Failed to load chunk at ChunkPosition { x: -5, z: 6 }: The specified chunk does not exist in the world save
2019-08-19 21:50:16,199 WARN [feather_server::chunk_logic] Failed to load chunk at ChunkPosition { x: -4, z: 6 }: The specified chunk does not exist in the world save
2019-08-19 21:50:16,499 WARN [feather_server::chunk_logic] Failed to load chunk at ChunkPosition { x: -3, z: 6 }: The specified chunk does not exist in the world save
2019-08-19 21:50:16,749 WARN [feather_server::chunk_logic] Failed to load chunk at ChunkPosition { x: -2, z: 6 }: The specified chunk does not exist in the world save
2019-08-19 21:50:17,100 WARN [feather_server::chunk_logic] Failed to load chunk at ChunkPosition { x: -1, z: 6 }: The specified chunk does not exist in the world save
2019-08-19 21:50:17,399 WARN [feather_server::chunk_logic] Failed to load chunk at ChunkPosition { x: 0, z: 6 }: The specified chunk does not exist in the world save
2019-08-19 21:50:17,700 WARN [feather_server::chunk_logic] Failed to load chunk at ChunkPosition { x: 1, z: 6 }: The specified chunk does not exist in the world save
2019-08-19 21:50:17,952 WARN [feather_server::chunk_logic] Failed to load chunk at ChunkPosition { x: 2, z: 6 }: The specified chunk does not exist in the world save
2019-08-19 21:50:18,301 WARN [feather_server::chunk_logic] Failed to load chunk at ChunkPosition { x: 3, z: 6 }: The specified chunk does not exist in the world save
2019-08-19 21:50:18,652 WARN [feather_server::chunk_logic] Failed to load chunk at ChunkPosition { x: 4, z: 6 }: The specified chunk does not exist in the world save
2019-08-19 21:50:18,902 WARN [feather_server::chunk_logic] Failed to load chunk at ChunkPosition { x: 5, z: 6 }: The specified chunk does not exist in the world save
2019-08-19 21:50:19,152 WARN [feather_server::chunk_logic] Failed to load chunk at ChunkPosition { x: 6, z: 6 }: The specified chunk does not exist in the world save
From what I understand, this warning is thrown when a chunk is specified in the region's header, but the chunk's offset
and sector_count
are 0.
After a few seconds, the player gets kicked for "moving too fast". From my debugging, it seems like the player's initial position is 0.0/64.0/0.0
, and the first movement packet gives 8.50/65.0/8.50
Work needed:
I'm not sure exactly why this happens—maybe it has something to do with floating point errors.
Add support for loading player data files (located in world/playerdata/<uuid>.dat
.) This includes loading the player's position and inventory.
Related: #71
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.