Quote:
Originally Posted by
fubeca150
I was getting on to post this same thing. You already told us exactly what the problem was a few pages ago, but I'll expound so-as to not take more dev time in this thread.
Thanks for the thorough explanation!
Quote:
Render thread is always single-threaded in every UI framework, including QT, C# WPF, Xamarin, and other game engines.
Not a problem as long as other tasks than rendering can be sourced to different threads.
Quote:
In the case of FGU, this is based on information coming from the LUA engine once the main playing area is displayed.
We welcome FPS drops (aka energy-saving) when nothing happens. We can live with fps drops when something is calculated. We don't like input/output freezing to 0 fps, though.
Quote:
The initial load of FGU from the launcher shows a progress bar because at that point in time the LUA state machine can run in its thread, and the UI render thread doesn't care what the LUA state machine is doing -- yet.
I assume this is "LOAD PART 1" then, where a mono thread is doing the work?!
Quote:
In the launching mode it would only care to know when the LUA engine is ready.
When is this mode entered with FGU? After PART 1 and before PART 2?
Quote:
Once the transition to "the game" happens, everything has to come via the LUA engine because that's where all the state is.
Is this where PART 2 begins and modules are loaded by the main thread?
Quote:
When you start loading modules, now you're in a state where your render thread is directly dependent upon the LUA engine, which is busy loading your module state and blocking further requests until it's done.
In FGU the "render thread" is the same as the "LUA engine" thread. Do both have to run in the same thread with Unity? The LUA engine cannot do its thing in its own thread while the main thread remains animated? Digital stone ages, but let's assume from this point on that this is the case.
So the rendering pipeline waits for the LUA engine to give feedback. Why does the LUA engine not do this? I know it is busy loading and processing scripts, but how expensive can it be to sent a short ping to the rendering engine every once in a while?
Quote:
That's why it goes white screen at that point, and white screen is just the OS specific way of letting you know the program isn't rendering or accepting input.
Of course this is the OS trying to make sense of it. It begins with a blue circle mouse-pointer animation, then turns into a white screen and finally into a "not responding" message. All defined by timeouts set within the OS.
Quote:
Going to another scripting engine isn't a solution when part of the problem is maintaining backwards compatibility, and most of the problem is contention over locked resources (in this case the LUA state engine).
And here we get to the point where single-thread design is not the main culprit. FGU's blatant slowness compared to FGC when loading the very same LUA scripts is. Why would the same LUA module take 1-2 seconds to load in FGC, but 6-7 seconds to load in FGU (including a short output freeze)? If this was better optimized then we wouldn't have to think too much about multi-threading anything script-loading related.
Quote:
This is one reason that immutable (or Frozen) state is what you want to work with in the UI layer (and arguably in as many places as possible but that claim sparks a religious debate).
If the rendering and LUA engines cannot be handled asynchronously in different threads then the LUA engine should work in a way that keeps the UI responsive. This will introduce cost, hopefully not too much, though. But again the possible solution also suffers from the current lack of optimization to bring FGU to at least match FGC. Opening an image allocates to much (more) private memory in FGU that I am not surprised that so many more CPU cycles are necessary to handle these thing. All that extra data wants to be processed.
Quote:
The way many of the UI rendering engines get away with threading for processing on something OTHER than the render thread is that they dispatch state changes to the UI layer. So while it appears that the program is responsive, it might not be doing anything useful other than placating the user by letting them know it's busy and not in the process of crashing.
Which is important. Even back in the days of DOS applications kept the cursor animated to announce to users that they did not freeze. We still have animated hour-glasses, circles and beachballs to that effect. And there is a reason why keyboards come with an input buffer to allow users further input even when the data cannot be processed immediately.
Quote:
In the case of FGU, though, even if you could figure out a way to create such a dispatcher between LUA and the Unity code layers, you still have a major problem to overcome, namely "exactly what am I supposed to dispatch?"
Drawing character sheets/windows and anything that does not need further expressions calculations would be a start. The missing numbers can be filled out once they are finished being calculated. Instead of monolithically displaying everything in one go there always is the option of displaying things progressively.
Quote:
FGU's rulesets, modules, and extensions have a ton of expression based stuff. Value1 = value2 * value3. So if Value3 changes, it needs to dispatch notice of anything that subscribes to it. Most game related expressions aren't that simple. Even calculating a character's main attributes is a series of expressions in an "all games supported" engine like FG, and everything else builds off of the results of those expressions.
But are these expressions and the calculations behind it really expensive? Character sheet based stuff seems like very simple math with small numbers to me. We are not talking calculating 3D raytracing rendering scenes here.
Quote:
Creating a dynamic subscription dispatcher is a lot of work to do to avoid hitching, and a very difficult architectural change. It's also pretty special case, so probably wouldn't be available on the Unity store. And it's also completely understandable why it would not be included in a complete rebuild of FG.
I would think that a rebuild is just the opportunity to design these kind of things from the ground up, instead of trying to tack them on later. It also seems that you are telling me that modern UI frameworks do not come with readily available tools to set this up?! Quite a shame.
Quote:
So far the only times I've seen noticeable hitching have been when opening a list (which is so much better now than it was a few months ago), when loading all the modules I want to use when setting up my campaign for the first time, and when players are connecting.
I am on a strong 9900K based computer, but still see dropouts happening, mostly shorter than the "not responding" timeout. Waiting for one-time load stuff is fine by me, although I am still unhappy that performance is so much worse compared to FGC for doing the same things. It's the in-between short drops in responsiveness that make the experience less pleasant.
And then there is the regular dropouts when new features like LoS are used. This is something where Moon Wizard stated that they are considering multi-threading for the calculations of LoS. I would welcome this.
Then again, he also stated that networking is already multi-threaded, but I still got up to half a minute delays when starting Launcher, because the whole UI was waiting for networking to answer. Instead the UI should have started and told me in a meaningful way that networking is still busy doing its thing. These are design/concept problems that come before the code and UI framework hurdles. It sometimes seems as if the developers forget that there are people in front of their expensive computer hardware waiting to get information about what the heck is going on and whether they should rather get a hot drink meanwhile.