JMonkeyEngine 3.8.0

Please offer congratulations and support to @yaRnMcDonuts, our release manager for JMonkeyEngine 3.8.0

19 Likes

Very good. Congratulations to our new release manager, welcome!
It doesn’t seem like an easy job, but I hope you do it great!

3 Likes

Good luck @yaRnMcDonuts and thank you in advance for managing the release

4 Likes

A huge round of applause for @yaRnMcDonuts, This release is a fantastic achievement, and we’re so grateful for all the hard work and dedication he poured into it

2 Likes

I appreciate your enthusiasm. However, note that the 3.8.0 release hasn’t appeared yet, not even an alpha version. There’s still plenty of work to be done, and we’re grateful to Ryan for volunteering to undertake it.

Sorry if I misled you.

1 Like

Congratulations @yaRnMcDonuts, and Best of luck!

2 Likes

It was misunderstanding from me :sweat_smile:
I am looking forward to the first release from @yaRnMcDonuts :v:

2 Likes

Congratulations @yaRnMcDonuts! We look forward to the release :slight_smile:

2 Likes

Thank you all for your support and congratulations. I look forward to releasing the next version!

I’ve already begun looking through PRs and hope to include as many important bug fixes and new features as possible, however this will of course require a lot of help from the community testing the alpha and beta releases when the time comes.

I am already keeping a a list of test-cases that are all related to new features or bug fixes that will be in 3.8. This should make it easier for users with less time on their hands to help test the most important aspects of each new alpha/beta release.

I also notice there are some useful PRs that have been sitting around un-merged for a long time, often times waiting for the author and/or reviewer to return to make some minor final changes, but in many cases it looks like the author may not return to make these changes. So I hope to get things moving again with some of these, and will likely be posting to the forums here to request help reviewing and finishing off some of these PRs in the near future.

And finally, I have plans to include some major changes to the PBR shaders in this upcoming release. PBRLighting will be benefiting from a (potentially very important and visually apparent) bug fix (#2334) as well as some refactoring, and the PBR Terrain shaders will be getting some major improvements that will allow for rendering many more terrains of varied detail in the far distance.

I also plan to initiate a deeper discussion about jme’s terrains in another thread soon. I know that many jme users have valid issues with jme’s terrain system and that it is far from perfect, but aside from voxel libraries, there really have not been any realistic alternatives provided in a long time. So I would also like to address some of the terrain library’s shortcomings and potentially provide some fixes in the future if possible.

15 Likes

Thank you, @yaRnMcDonuts!

3 Likes

I don’t know if Jme-3.8.0 is closed for new features. However, I managed to solve these old issues a while ago.

With a simple API that is very basic to the fact that is based on the model of the interrupt routines. The API is a standalone project on Jector. However, I could re-design it to be integrated as a part of the engine if needed. I have no idea how much are these issues valuable or should have an impact… You can find an example here, it gives full control on executing tasks within threads in concurrency or completely in parallel.

5 Likes

I will probably close 3.8 to new features in early February after atleast one more alpha release, so there should still be time.

This is beyond my area of expertise, so I personally might not be much help reviewing or testing your contribution. But I expect some other jme users should be able to help with reviewing and merging in time for 3.8

5 Likes

Never mind, I will try to get the approval of the community later on 3.9 maybe if necessary.

If all you are concerned is asset loading, i use:

<K,R> void loadAsync(Function<K,R> function, K key, Consumer<R> consumer){
        CompletableFuture.supplyAsync(() -> function.apply(key)).thenAccept(result -> enqueue(() -> consumer.accept(result)));
 }

which allows usage like:

Node node = new Node();
loadAsync(assetManager::loadModel, "Models/demonHandsLeft.glb", node::attachChild);

While i agree it should be documented that such stuff is possible i would not add any code if its just for assetloading.

4 Likes

The issue also addresses some other stuff that is similar to asset loading. That is why Jector is built for a generic use in addition to the point of having a controlled concurrency over tasks from different threads.

Here is the full list that is required to be compatible:

"Multithreading is an important issue right now. Taking advantage of it in
jME3 is critical. Some areas where multithreading can be used:

  • Skeleton animation, mesh skinning
  • Particle update
  • Physics
  • Networking
  • Input polling
  • OGG/Audio streaming
  • Resource loading
  • Terrain streaming"
1 Like

I agree with you, and i see reasoning and the problems that come with/from it, since i am currently working on exactly this problem outside of jme.

Assetloading is quite the exception here since it uses blocking operation and works on safe data by default.

First of all concurrency is not free. Efficiency is going down due to synchronisation. I have nearly double the cpu usage for nearly the same framerate in async mode for an empty update loop. It takes considerable time to spin up the thread, and to sync back.

Lets take input polling as example, and dismiss the requirement that it has to run on the main thread:
You can start the polling process after rendering has completed, but you need the results before you start updating the gamelogic to not introduce an additional frame of input lag. This leads to basically

wait(async(pollInput))

Unfortuantely in the core updateloop i have found very little that is possible to really do async. The biggest gain i found (and it’s the only reason my lib runs slightly faster in async mode) is the graphics update.
instead of:

input(0)->update(0)->render(0)->swap(0)->input(1)->update(1)->render(1)->swap(1)

it is possible to have:

input(0)->update(0)->render(0)->input(1)->update(1)->swap(0)->render(1)

But that already requires that all data the renderer is using is immutable. So it gets a deep rabbit hole quickly. And i am in the 3rd rewrite currently.

Don’t get me wrong, i like the idea. Maybe i am in a bad mood regarding this because i spent the last two months on this topic and was fighting mostly java, threading requirements by native libs and synchronisations issues.

1 Like

It is totally fine, I am also working on Pthreads and Mutexes as a part of the Electrostatic SDK (another trivial project)… But, Jector is much simpler. It’s very similar to the Interrupt Services, and the Android Multithreading Model. It’s very basic to the fact that you could represent the model using a Lambda Calculus Mathematical model.

The model is basically to start as many TaskExecutors as needed, a TaskExecutor is an abstract entity. In most cases, it’s a Java Thread, but could be anything else… For example, a remote process.

Tasks, implemented as WorkerTask, are then registered and mapped to these TaskExecutors entities; tasks are executed when registered on the Threads implementation. When threads are done executing tasks, they could go inactive and thus be claimed by the GC, then new threads could be created again when in demand… Tasks are as well; they could execute in a loop if not stopped.

Tasks have an object to store the return value to be used by other threads or tasks within the same thread. Thread-safe objects are guaranteed by the use of volatile objects. No Mutexes or Thread Locks are involved.

A task from Thread X could control another task from Thread Y; controls are either to start the task, stop it, or poll its value. The same goes for threads. This is very similar to the interrupt, a hardware control signal can interrupt the main process and jump to another interrupt unit… The same goes here but you have to generate both signals, one for stopping the current task, and the other to start the new task.

EDIT:
As for the downside of looping and polling in multithreading that wastes CPU cores, it is a trade off and can be narrowed down either using the novelistic Virtual Threads or through just claiming threads that take long time waiting, and recycle them keeping the tasks to be registered again when another request is made…

A PR is ready for review:

4 Likes