PistonDevelopers / hematite_server

A Minecraft server clone
http://hematite.piston.rs/
MIT License
141 stars 16 forks source link

Add singleplayer support to the protocol #97

Open fenhl opened 8 years ago

fenhl commented 8 years ago

In order to support singleplayer mode (which is a big step towards getting this integrated into the client), the protocol API needs to be redesigned in such a way that would allow a local client to share the memory representing the data structures used in the protocol, removing encoding/decoding overhead.

I have occasionally been hacking at this in the past few months, but so far haven't been able to come up with a good API design.

bvssvni commented 8 years ago

The question is whether the overhead is acceptable or not. If gameplay is fast enough for multi-player, then it might be an idea to just use a server with a single player in single-player mode.

RichardlL commented 8 years ago

I agree with @bvssvni Most computers have at least two cores these day.

  1. The first thread would host the client
  2. The other would host the server.

If thread 1 can communicate encode with an remote server, it can communicate with a local one.

If the processor can handle thread 1, it can handle thread two. Running a minecraft server alone with a single remote client is less resource intensive than running a client connected to a remote server

The only use case for this optimization would be:

So hypothetically, this person would only be able to connect locally, but not be capable enough to connect to server for this optimization to be applicable.

Sure it's useless encoding/decoding, but

This will spur adoption, and allow both projects to be developed independently of each other. They will also end up compatible with each other.

Honestly seems like a case of premature optimization to me.

I say just stick with the official Protocol, sure it sucks, but its still official

Any reason we are targeting 1.8.3 instead of 1.8.8?

fenhl commented 8 years ago

1.8.3 was the latest release when we started working on stuff. We should be targeting 1.8.8 now (although there haven't been any significant changes to the protocol).

Note that I am not proposing any modifications to how Hematite implements the protocol itself, the Hematite client would still communicate normally with all servers, including Hematite servers. The only change would be for singleplayer. If done correctly, this could improve both tick speed and memory usage in singleplayer mode, without any added code complexity. This is very similar to how Notchian implements singleplayer, except without the risks of data races because of Rust's guarantees.

toqueteos commented 8 years ago

@fenhl Do you mind editing the issue with a ToDo list of things we want to support?

fenhl commented 8 years ago

I don't have any detailed plans on how to implement this. Suggestions welcome.

toqueteos commented 8 years ago

Let's see... Our shopping list, order somewhat relevant, should have:

  1. Login (online-mode=false). Done in #40! :tada:
  2. Implement concept of world. Dimensions ticking in sync! Example: http://is.gd/oGH1Yr (this is example code, a real version wouldn't clone every world on every tick ofc)
  3. Keep track of entity positions. Just the player's position with some simple checks (moving too fast, send Disconnect packet) should be enough to get going. Example: HashMap<String, Position> which will come handy when we start adding more entities.
  4. A working chunk loader. Once we know where the player is we can load and unload his/her surroundings.
  5. Chat. Basically just echoing back whatever the player writes. This would allow people to start working on commands.
  6. Time handling. Having /time working would be great, also time being updated accordingly every now and then just to keep players in sync.
  7. Basic inventory handling. Moving items around in their inventory, including bottom bar.
  8. Digging mechanics. This involves actually breaking blocks and spawning entities so the player can pick them up. Quite a milestone.
  9. Dropping items. We already had the inventory working and know how to spawn entities, should be easy.
  10. Illumination. If we start breaking blocks, we should update lighting accordingly?

This seems like a good start unless I'm missing something.

EDIT: Go to #109 if you want to talk about any of these, this issue is NOT about single player functionality.

RichardlL commented 8 years ago

We could use a plan for world ownership.

We could possibly spawn a thread for each core deviding it up between threads.

As in #100, but this might be a simpler way to implement it.

The master would manage a Hash-map/index of chunks, which corresponds to transmitters.

All player threads would have access to the hash-map through a read lock. For unloaded chunks, the players would send the request to the master thread, which could decide which thread to delegate the new chunk to.

If an action in one chunk affected another, one chunk would message the other.

For example, if Toqueteos causes a tnt explosion on edge of chunk A,

Toqueteos's thread would look up in the hashmap chunk A's channel, notify chunk A's thread, and chunk A thread could notify any surrounding chunks if needed.

Updates could be managed by the chunk thread notifying players that have it loaded.

This would make the requests a-sync, but It could be added on top of another library if we wanted map generation/computation to be also.

fenhl commented 8 years ago

@toqueteos those are all out of scope for this issue. I'm simply trying to add an API to the protocol which uses shared memory instead of TCP.

toqueteos commented 8 years ago

Woops, seems like I totally missunderstood this issue. I've opened #109 so we can track functionality and future contributors can help on our next steps.