Coder Social home page Coder Social logo

feather-rs / feather Goto Github PK

View Code? Open in Web Editor NEW
2.6K 55.0 146.0 10.97 MB

A Minecraft server implementation in Rust

License: Apache License 2.0

Rust 99.56% Shell 0.01% Python 0.43% PowerShell 0.01%
minecraft rust minecraft-server-software minecraft-server gamedev ecs

feather's Introduction

Feather

build Discord

A Minecraft server implementation written in Rust.

Note: This project is currently inactive. Consider contributing to valence instead.

Supported Minecraft versions

Feather supports 1.16.5 clients and world saves. We do not currently have plans to support multiple versions at once, but we may consider this in the future.

Goals

The Feather project aims to provide a Minecraft server that is fast, modular, and paired with an ergonomic plugin API.

Our mid-term goal is to make Feather usable on hub and minigame servers. The limited set of gameplay features available in Feather is not a problem for such servers that require a small subset of vanilla functionality. On the other hand, Feather's modularity and performance lends itself to these types of servers. Therefore, our current focus is on building a rich plugin API to enable these use cases.

In the long term, Feather could be used on larger, more survival-like servers, where its performance should allow many players to simultaneously play on the same world requiring very few resources.

Ecosystem

The Feather ecosystem consists of several repositories:

  • libcraft, a set of Rust crates providing Minecraft functionality.
  • quill, our work-in-progress plugin API. Quill plugins are written in Rust and compiled to WebAssembly. Feather runs them in a sandboxed WebAssembly VM.
  • feather, the server software built on top of libcraft and quill.

Performance

Comparisons to vanilla performance will be extremely misleading, because Feather implements so few features. But if you really want them:

  • Feather can handle 1,000,000 entities spawned by a plugin before it starts to max out the CPU. The vanilla server will croak long before then.
  • Feather can handle 500 concurrent player connections with each player walking in a random direction.

These results will change after more features are implemented in Feather, so take them with a grain of salt.

Memory usage in Feather is proportional to the number of loaded chunks, not player counts. In the 500 player test, the server uses ~40 MiB of RAM until the players start to spread out. In the 1,000,000 entities test, it uses 400 MiB of RAM without any chunks loaded.

Running

We offer precompiled binaries for Windows, Linux, and macOS at GitHub Actions. NB: Do NOT use github releases, they are majorly outdated

To run Feather:

  • Extract the downloaded archive.
  • Run the binary.
    • On Linux and macOS: ./feather-server in the server directory
    • On Windows: double-click feather-server.exe

The server will create a configuration file (config.toml) which you can modify.

Feather will generate a world by default. If you want to load a vanilla world, copy the world save to the server directory under the name "world" (by default).

Warning: Feather world persistence is fairly new and will likely cause problems when attempting to open Feather worlds in vanilla. Do not let Feather touch worlds you care about unless they have been backed up.

Compiling

If you are on another platform, compile the server yourself to try it out:

git clone https://github.com/feather-rs/feather
cd feather
cargo build --release

Compiling from source requires the latest stable version of Rust. Older Rust versions may be able to compile Feather, but they are not guaranteed to keep working.

The server executable will be located in target/release.

Architecture

For contributors, we have a work-in-progress explanation of Feather's architecture here.

FAQ

  • Is Feather production ready?

Not yet. There are numerous bugs and missing features which have yet to be resolved, and the codebase has not been tested enough to consider the server production ready.

  • How can I contribute?

Check out our issue tracker to find out what needs to be worked on. Feel free to join our Discord and ask questions whenever you need. Thanks for your interest in contributing!

  • Are there other ways I can help?

Yes! We're always looking for people to test out the server and find bugs. If you find anything that doesn't seem right to you, please submit an issue on the issue tracker.

feather's People

Contributors

ambeeeeee avatar aramperes avatar caelunshun avatar defman avatar deliquescence avatar dependabot-preview[bot] avatar devmattrick avatar ecorous avatar fussballandy avatar iaiao avatar kallekankaanpaa avatar kirawi avatar koskja avatar leelvyn avatar lewis-carson avatar masplus avatar miro-andrin avatar nobbele avatar onbjerg avatar oxkitsune avatar paumava avatar ponaskovas avatar qualterz avatar redrield avatar schuwi avatar ssttevee avatar thijsray avatar toiglak avatar tracreed avatar wazner avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

feather's Issues

Anvil world persistence

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.

Player count incorrect

Regardless of the number of online players, the player count in the status ping is always 0.

Player data loading

Add support for loading player data files (located in world/playerdata/<uuid>.dat.) This includes loading the player's position and inventory.

Related: #71

Basic physics support

This entails:

  • Implementing velocities, gravity, drag in both air and liquids, and collisions between blocks and entities.
  • Ensuring that physics calculations remain in sync with the client.

Blocks randomly appear inside chunks which have been populated only with stone

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:

  • Diamond ore
  • Gold ore
  • Iron ore
  • Diamond block
  • Emerald block
  • Grey clay

World generation

Roadmap:

  • Support superflat world generation as a base foundation. (#108)
  • Support basic world generation using Perlin noise (#120)
  • Additional features:
    • Biomes
    • Grass, shrubs
    • Snow
    • Cacti
    • Ores
    • Trees (in progress at #138)
    • Caves
    • Structures (villages, mineshafts, ...)
    • Flowers
    • Lakes
    • Rivers
    • Ocean variety

This page will be a useful resource.

Only broadcast entity actions to players who can see them

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:

  • The chunks a player keeps loaded (and thus those within their view distance) are already stored in the 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.
  • The entities for each chunk are stored in 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:

  • Implement a convenient way to broadcast packets to players who can see a given chunk. This would probably take the form of e.g. 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().
    • It might be slightly annoying to have to pass all those parameters to the function. For cleanliness, it's possible to investigate moving ChunkHolders into Util and having the function be a member function of Util.
  • Detect when a player leaves a chunk and destroy entities client-side in chunks which are no longer within the view distance.
  • Only send the inventories, positions, etc. of entities within the view distance when a player joins.

Correctly handle inventory indexing

I noticed that the handling of the Creative Item packet doesn't take into account the "raw slot" logic:

https://github.com/caelunshun/feather/blob/d3d05d34eefe2047c374a66266e35715ebd9e2b1/server/src/player/inventory.rs#L184-L191

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)

Issues with joining server / loading terrain

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

Status ping shows as 50ms on localhost

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.

Entity position update event is always triggered each tick

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.

Implement timeouts

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.

Correctly support non-solid blocks

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.

Improve performance of block state ID mappings

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.

Support for multiple protocol versions

Work needed:

  • Packet ID mappings for each supported protocol
  • Block state ID mappings for each supported protocol
  • Packet write() function needs to take a protocol version so different versions can have varying packets
  • Rewrite packet derive macro to support multiple versions

Clean up code

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.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.