Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Coroutines functionalities in the context of Minecraft #34

Open
Peanuuutz opened this issue Aug 11, 2022 · 9 comments
Open

Coroutines functionalities in the context of Minecraft #34

Peanuuutz opened this issue Aug 11, 2022 · 9 comments

Comments

@Peanuuutz
Copy link
Contributor

Peanuuutz commented Aug 11, 2022

This thread is all about upcoming coroutine functionalities. Please share your thoughts regarding the following topics.

Topic 1 - Dispatchers.Main
Soon we would have Dispatchers.Main been implemented as a supplement to other dispatchers. A few questions I'd like to ask before diving into it.

Q1: We need to specify how the dispatcher runs actually, because unlike the official implementations, there's no ready-to-use event loop, but only tick, render forming some kind of "event loop". Maybe QSL lifecycle events could be used.

So I'm looking into kotlinx.coroutine for reference. However only UI related implementations (Android Event Loop, JavaFX, Swing) are found.

Q2: Do we really need main dispatcher on the server side? Usually it is for UI and is confined to only one thread. What is the usage?

Q3: Usually main dispatcher implements Delay for time related tasks. While real time is used among other main dispatcher implementations, Minecraft has a special time unit which is tick. Should we consider a tick based Delay implementation?

@Cypher121
Copy link
Contributor

Q1 and Q2 are an interesting consideration. Android, JavaFX, and Swing are all GUI frameworks. In their contexts, thread safety is only needed when drawing onto the view. Minecraft, however, has both rendering and worlds requiring synchronization, with worlds having a server and client running in parallel. Any of them can pass for a Main context, though my expectation would probably be to find server being referred to as such.

Perhaps it'd be a better idea to add Server, Client, and Render as Dispatchers extensions instead.

As for delays, the question here is behavior on dispatchers that don't implement Delay: the docs don't seem to state it explicitly, but the delay handler in this case is the DefaultDelay. I could only track down the execution so far after that. However, it'll eventually have to come back to the dispatcher and dispatch anyway, so the behavior will likely end up being rounding up to the nearest tick.

I say implementing Delay, warning that it shouldn't be used in logs (can't do deprecation as we don't control the delay(Duration) and delay(Int) functions themselves, and pointing towards a separate method that takes ticks would be the cleaner option that tells the users their delays are being rounded to ticks and to specify that upfront.

@SilverAndro
Copy link
Contributor

SilverAndro commented Aug 11, 2022

Perhaps it'd be a better idea to add Server, Client, and Render as Dispatchers extensions instead.

Is there a meaningful difference between server and client?

The both only have a single thread for computation afaik, with client just running an integrated server

@Peanuuutz
Copy link
Contributor Author

Peanuuutz commented Aug 12, 2022

Is there a meaningful difference between server and client?

The both only have a single thread for computation afaik, with client just running an integrated server

In this case, one difference is how the dispatcher functions. I'm considering the following implementation: maintain an internal task queue for each main dispatcher, and when certain event happens like XxxTickEvents.START/END, these scheduled tasks get executed. So the difference here is where the tasks run. For example, client may run tasks that are still available outside gameplay like screen rendering.

@Peanuuutz
Copy link
Contributor Author

Peanuuutz commented Aug 12, 2022

Perhaps it'd be a better idea to add Server, Client, and Render as Dispatchers extensions instead.

This is what I mean to do at first place. (Can you explain the reason to seperate Render and Client? I didn't find minecraft seperating these two contexts)

I say implementing Delay, warning that it shouldn't be used in logs (can't do deprecation as we don't control the delay(Duration) and delay(Int) functions themselves, and pointing towards a separate method that takes ticks would be the cleaner option that tells the users their delays are being rounded to ticks and to specify that upfront.

A seperate function for ticks is needed so users don't get confused by the behavior. Normal delay would most likely round up to the nearest tick if going for my suppose specified in the previous comment.

@Cypher121
Copy link
Contributor

Can you explain the reason to seperate Render and Client? I didn't find minecraft seperating these two contexts)

My impression was client-side rendering and world ticks still run on separate threads, so they are separate contexts. I might be wrong on that, but if so, running rendering code on a world thread would slow the ticks down, while vice versa would result in concurrent modification.

@SilverAndro
Copy link
Contributor

SilverAndro commented Jan 24, 2023

Bringing this up again, for Q1 something that would make sense would be the ability attach jobs to specific objects with their own lifecycles

so, i.e, you could attach a Job/coroutine to a player, delay for "ticks" (running the job as part of the player tick?) and if the player disconnects from a server, close their CoroutineScope so that anything attached gets the ability to clean up automatically when it makes sense

Ive had a few cases now where my Jobs are doing something in relation to a world, and I need to spend a bunch of time hooking it up to the start and stop events

@Peanuuutz Peanuuutz changed the title About Minecraft Dispatchers.Main Coroutines functionalities in the context of Minecraft Jan 25, 2023
@Peanuuutz
Copy link
Contributor Author

Generalize this topic in order to welcome other coroutine related ideas.

@Peanuuutz
Copy link
Contributor Author

Peanuuutz commented Jan 25, 2023

Bringing this up again, for Q1 something that would make sense would be the ability attach jobs to specific objects with their own lifecycles

so, i.e, you could attach a ...

A CoroutineScope could be created for an object with the corresponding lifecycle based CoroutineContext.

@SilverAndro
Copy link
Contributor

Something that occurred to me, is there any we can write this where it wont explode with those various "Minecraft but with more threads" projects?

They are, unfortunately, somewhat popular and I suspect we'll run into issues at some point with them.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants