Shynixn / MCCoroutine

MCCoroutine is a library, which adds extensive support for Kotlin Coroutines for Minecraft Server environments.
Other
208 stars 19 forks source link

Using MinecraftServer in Minestom #97

Closed bananasmoothii closed 1 year ago

bananasmoothii commented 1 year ago

Hi, you recently implemented MCCoroutines for Minestom and I'd like to firstly thank you for that.

But there is a little issue on the implementation of server.launch { }: in Minestom, we usually don't store any MinecraftServer instance because every method in that class is static. That means that instead of server.launch { }, we should be able to do MinecraftServer.launch { }.

Unfortunately, MinecraftServer is a java class and doesn't have any companion object, so making an extension function for the companion object is impossible. A workaround would be to change fun MinecraftServer.launch to just fun minecraftServerLaunch.

For now, I am using this:

private var minecraftServer = MinecraftServer()

fun minecraftServerLaunch(
    context: CoroutineContext = minecraftServer.minecraftDispatcher,
    start: CoroutineStart = CoroutineStart.DEFAULT,
    block: suspend CoroutineScope.() -> Unit
): Job = minecraftServer.launch(context, start, block)
Shynixn commented 1 year ago

As far as I have understand the minestom approach, you always "build a server yourself" by initializing a MinecraftServer instance. This can be seen on this wiki page https://wiki.minestom.net/setup/your-first-server.

Here you call MinecraftServer minecraftServer = MinecraftServer.init();. This means you do actually have a minecraft server instance. MCCoroutine simply needs a lifecycle instance (the coroutine session is created and disposed along with it) where MinecraftServer makes the most sense in this context.

You are free to move the MinecraftServer instance to a static (or companion) field because it does not make any difference in this case.

bananasmoothii commented 1 year ago

Yeah... There is a flaw in Minestom's design so there is no real way around it. You have to make a MinecraftServer instance indeed, but you use it just to call .init() and .start()

Shynixn commented 1 year ago

A coroutine needs to live in a scope. For Kotlin, these are called Coroutine Scopes. See https://kotlinlang.org/api/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines/-coroutine-scope/

For Minestom, I have implemented 2 scope types. ExtensionScope and MinecraftServerScope. Kotlin Coroutines offers the GlobalScope per default, which allows to do something like GlobalScope.launch. To indicate that the coroutine lives in the scope of the entire MinecraftServer (start/stop) it makes sense to bind the scope to it. Therefore, I have added the launch function to the MinecraftServer instance.

I think technically, it makes sense to indicate scopes on API level.

~

You are free to add your own launch extension function or move the MinecraftServer instance to a companion object of your main class. I do not care.