it dont even need to be caused by another thread.
Technically, as i noted it happends when you modify Node in incorrect"frame workflow time".
Here is part of JME update loop:
@Override
public void update() {
if (prof!=null) prof.appStep(AppStep.BeginFrame);
super.update(); // makes sure to execute AppTasks
if (speed == 0 || paused) {
return;
}
float tpf = timer.getTimePerFrame() * speed;
// update states
if (prof!=null) prof.appStep(AppStep.StateManagerUpdate);
stateManager.update(tpf);
// simple update and root node
simpleUpdate(tpf);
if (prof!=null) prof.appStep(AppStep.SpatialUpdate);
rootNode.updateLogicalState(tpf);
guiNode.updateLogicalState(tpf);
rootNode.updateGeometricState();
guiNode.updateGeometricState();
// render states
if (prof!=null) prof.appStep(AppStep.StateManagerRender);
stateManager.render(renderManager);
if (prof!=null) prof.appStep(AppStep.RenderFrame);
renderManager.render(tpf, context.isRenderable());
simpleRender(renderManager);
stateManager.postRender();
if (prof!=null) prof.appStep(AppStep.EndFrame);
}
when you will execute something that modify Nodes After calls:
rootNode.updateLogicalState(tpf);
guiNode.updateLogicalState(tpf);
rootNode.updateGeometricState();
guiNode.updateGeometricState();
it will cause this issue for sure.
so as i see it is possible even in same thread, when you modify Nodes using simpleRender methods instead of simpleUpdate. Or some other methods that just execute after this lines.
Its same about another Thread ofc, because it depends when it will be executed, before or after calls. So if you are using multithread you should use JME synchronize loop call Queues.
like:
app.enqueue(() -> {
//do something
});
(longer version if lower java version, i dont remember now)
anyway in this code everything executed after
rootNode.updateGeometricState();
will cause this issue.
I hope someone will verify me, because i dont check this long time.
about:
The bit I understand less is “Problem spatial name: Root Node”
it just mean this error is about this node, so like said above, this node in updateLoop was not ready for updates (so after this rootNode.updateGeometricState(); call)
btw. “Spatial” is everything, so ti can be Node, or Geometry or something else. Its like entity.
that rootnode was added to something else (which would obviously be a bit weird), or something else.
ofc it would be odd, because app thread manage if rootNode was ready for update or not.
I can also guess, you could yse OffScreen render methods and use rootNode there that could cause some issue?
Its a big game and this happens rarely and seemingly at random so diagnosing it is going to be tricky
Yes, if big game it would be hard to find.
But i have some guess:
- you use offScreen rendering using rootNode
- you modify rootNode in some calls like render()
- you have multithread and you modify rootNode in thread without queue