How about only updating half of the objects every second frame? Or a quarter of them every fourth frame? This way you reduce the work.
As for "how can we check for tens of thousands of collisions per frame": First of all, remember that using GDScript incurs a penalty because it's an interpreted language. If you wrote the same code in C++ (maybe as a GDNative "script"), chances are you would get better performance.
Second, if you know your game has to check for tens of thousands of collisions between objects, you'll most likely arrange your data structures in a way that will make collision checking trivial (but might make other things more difficult). Naive collision checking runs in O(n^2), because you check every object against all the others. So the first order of business would be to see that we don't do 10'000 * 10'000 collision checks. If I had to write a game like that from scratch (without a pre-existing game engine), I'd most likely subdivide my game into a grid, record each grid's contents and then do collision checks per grid, which should turn out to yield a smaller total.
But: I don't actually see any large number of collision checks being performed from trailers of games such as Factorio (which I haven't played, so please forgive me if I get the game mechanics totally wrong). Instead it looks like the main mechanic of the game is that each object is transported along by a conveyor belt, taken off the belt by a robot arm and put on another belt or in a factory machine. This is completely different from the collision check problem because we know exactly at which points objects will interact with each other. So whenever we put an object on a conveyor belt, we can add it to a list of objects that will need to be processed at a given future time by a given robot arm (for example), and we know the exact time because the conveyor belt (seems to) run with a fixed, known speed.
So I'd assume that the answer to the question "how do they process so many objects at once" is that they don't: These games probably know exactly which objects will need to be processed in which frames by which robot arms, which means that each individual frame doesn't have to process tens of thousands of objects - it will only have to process the objects that are scheduled to be processed in that frame (to be put on a new conveyor belt, unloaded from a train, but into a factory machine etc).
So I'm back to my original suggestion: Don't process every single object every single frame.
You write that there is "no real fustrum culling fix for calculations", but I think that's wrong. It seems to me that most of what happens in the game is deterministic (there might be fun random stuff like conveyor belt malfunctions that the player needs to fix etc, but these things only need to appear random to the player - they might be planned events from the perspective of the game). So it should be possible for each object to calculate it's state and position for any given time - including when and where it will reappear on the screen. So the game could stop updating "unimportant" stuff like an objects game world position etc as long as it's not visible. The game would only have to process interactions with other objects, and as I've said before, it's known in advance when these happen, and which objects interact. Also, these interactions are much less frequent than game position updates. So you can save a large amount of processing power by not having to update game world positions dozens of times per second for off-screen objects.