huin / chunkymonkey

(unmaintained) Minecraft Beta multiplayer server
MIT License
115 stars 16 forks source link

Discuss/design modding capabilities #38

Open ghost opened 13 years ago

ghost commented 13 years ago

At some point chunkymonkey needs modding capabilities. I write this down to consider this in the issue #30 about concurrency design.

I am just writing down some ideas and information.

Here is a list of possible language bindings for Go; https://bitbucket.org/rj/golang-javascriptcore/ - This is a wrapper for WebKit's javascript engine for Go http://github.com/afitz/golua - Go wrapper for LUA's C API cgo https://bitbucket.org/binet/go-python - go bindings for CPython C-API lib

Pure Go can only be supported if the end-user compiles Go and chunkymonkey by himself. This way he could patch the source code.

Another idea is to have modules which run independent from chunkymonkey and communicate over network with chunkymonkey. With this idea all languages are supported if they have network support. The downside is probably execution speed.

huin commented 13 years ago

That's a longer list than I'd been aware of, I think I'd only seen golua. There are likely pros and cons for each choice of language, and modders would likely have input as well.

For having modules running independently from the server this would very likely be a speed problems for certain modding scenarios. If something needs to perform repeated queries over a network then that quickly becomes expensive for network latency, and for introducing a lot of events to be handled at both ends. However, it might be avoidable by locating the logic close to or inside the component that it interacts with most often.

Extreme and possibly obvious example would be to recommend that components of a mod that affect block behaviour should be implemented as a hook inside a goroutine that handles chunk(s).

A counter example might be a mod component that affects mass mob behaviour. It might run quite happily as a separate process, and delegate commands to its mob armies remotely - then only relatively simple code need be implemented in the server to implement the "commands" that the mobs can carry out.

An example of where modding can be separated out pretty much completely is in terrain generation. The mod implements a hook that generates chunk(s) when the server requests them.

ghost commented 13 years ago

(After I fixed some problems with my computer and Linux I got to think about Chunkymonkey a bit more.)

Here is a list of possible mods I can think of which would required event hook ups and issue commands to alternate the world:

Permission/Area protection: Would require to hook into chunk objects to prevent or allow destruction attempts of chunks from players.

NPC mods: Full control over NPC's, like: Creation, destruction, property changes (hp, speed, position), Spawn rate, movement, attack,...

RPG like mods: Full control over players, like: Changing properties(hp, walk-speed, use of tools), teleporting, inventory, ...

Weather control mods: Creation, destruction of different weather types.

World generators: Complete control over chunks.

Admin mods: Access to server commands.

Mods which require a command line based interface: Chat: Send and manipulation of chat-messages.

Most mods also need to know about the general server events like starting, stopping, saving, player events (joining, leaving, kicking,...), ...

So overall mods would need to hook up and issue commands in all areas.

About the language issue. I would like to implement a mod system for Go first, so all mods would be written in Go. This way a "mod" could be implemented which exports all events and commands to another language.

I will think about how to implement events which can be used by mods. I need to catch up some source code changes and architecture changes.. I also need to know if two different goroutines waiting for data from a channel get the same new data or just one of the waiting goroutines.

huin commented 13 years ago

Ah, I wondered what had happened to you :) - I'll put you back on the contributor list.

Some good thoughts there, I broadly agree with them as features.

Although on the subject of player control, walk-speed is tricky. We can't really control it directly - the client just informs the server of its new positions and the server can move the client to positions. Although we could impose some sort of movement speed restriction on them, based on their movements, and move them back if they move too fast, but that's likely to be tricky and ugly :(

Implementing in Go first makes a lot of sense to me for the reasons you give.

On one point - I actually replayed packet logs against the server when I'd already logged in, and due to a bug I'd accidentally introduced, the server got the player entity IDs confused. The packet logs replayed the movement and look directions of the original player recording, which had the somewhat spooky effect of moving my player around the world, and controlling where I was looking. Afterwards I realised what a neat trick that could be for cinematic intros (think Half-Life style).

For world generation - I've actually just started a branch for chunk generation. It's pretty early days, but in theory should be quite pluggable.

A basic command has been introduced (/give). The command "framework" is very weak - a minimal subset to do what I needed at the time to test furnaces.

The server architecture has changed a bit - there's much more use of channel communications now. I still need to remove a lock from the player, but that should be a far more mechanical and less involved process than it would have been.

Two goroutines listening to the same channel (is that your question?) will only receive one copy of data between them (i.e only one will get it). Let me know if you have any questions. I should probably document the architecture some more, but not sure on a good place to start or how to approach it :/