Disco Science


Science labs light up with the colours of the science packs they are consuming, instead of just blue.

Tweaks
27 days ago
0.17 - 2.0
220K

b Factorissimo 2

1 year, 5 months ago

I'm sure it applies to all variants of Factorissimo 2, but I use the notnotmelon fork.

Loaded a save, went into a building to see my labs not lighting up, removed one and got the message to mention it here.

I see multiple discussion posts about mods and unregistered labs but no response and no update in sight.

What would I have to do to fix this myself.

1 year, 5 months ago

I haven’t had the chance to look at the code, but there’s almost certainly a point where Factorissimo is creating a lab without raising the corresponding event for other mods to know about it. If you find that and there’s no good reason for it (in my opinion there is never a good reason for a mod to hide creation but not destruction, or vice versa), then just add the flag for raising the event.

1 year, 5 months ago

Let me know if that explanation isn’t helpful, or if there is anything else you think I might be able to help solve.

1 year, 5 months ago

If that's the case then I suppose I can spend a day learning what it's doing and maybe be able to figure it out. Lua isn't my specialty so no promises. If I find anything I'll be sure to mention it.

1 year, 5 months ago

To give you a clearer sense of what’s happening on my end: Factorio doesn’t have an efficient way for a mod to say “for each lab each frame, do this thing”. Instead, DiscoScience maintains its own list of labs by listening for creation/destruction events. Other mods have the option of raising these events or not, and unfortunately the default is to keep them secret. So what’s probably happening is Factorissimo is creating objects in buildings without raising the event, which is why DiscoScience isn’t lighting them up. When you destroy a lab, the event is raised and DiscoScience sees that it’s out of sync and tells you. Then it does an expensive “get all labs” call in order to get back in sync. I wish I could do this every frame and avoid all this synchronization trouble in the first place, but it kills performance.

1 year, 5 months ago

Are you saying the "get all labs" call tries to rectify any out of sync labs? Because that doesn't appear to happen at all. It's almost like DiscoScience can't see labs within a factory building without you actually going in and placing them each time. I take it the "get all labs" call only gets ones on the main "nauvis" layer and not any others?

1 year, 5 months ago

Ok I’ve had a couple minutes to look at this. There are likely two problems:

First, I see Factorissimo2 has several calls to create_entity which do not raise events to let other mods know about new buildings. I haven’t read through the context but that could very well be causing the problem I suspected.

Second, there’s the fact that DiscoScience only looks for labs on nauvis. From what I’ve read, Factorio’s API explicitly doesn’t allow you to iterate through all surfaces. I’m not sure why this is, but if that’s the case it means that compatibility with other multi-surface mods needs to be done on a case-by-case basis. I’ll have to think about whether that makes sense to do.

1 year, 5 months ago

Note that the second issue should not be a problem if:

  1. Factorissimo raises events for all labs it creates and destroys.
  2. You have DiscoScience enabled from the beginning of your game.

This will avoid DS needing to rely on find_entities_filtered(), which as you pointed out is only being called for nauvis.

1 year, 5 months ago
(updated 1 year, 5 months ago)

Awesome stuff. Even if it's just the case of forking Factorissimo again to make it work with DS I'm ok with that*. I'm going to put a post on notnotmelon's fork as he appears to be updating his version and ask if it is possible to provide the potential fix. Original was last updated a year and a half ago :/

** Kind of, fingered crossed notnotmelon can do something to help

1 year, 5 months ago

About the surfaces check, can you not just loop through game.surfaces? Might add a bit of overhead, but its an expensive call anyway

for sur in pairs(game.surfaces) do
local game_surface = game.get_surface(sur)
game.print(game_surface.name)
end

prints all surface names for me. I imagine you can just do the same thing for your "get all labs" call

1 year, 5 months ago

The docs for game.surfaces say:
Iterating this table with pairs() will only iterate the array part of the table. Iterating with ipairs() will not work at all.

1 year, 5 months ago

But maybe the array part of the table is all I need? I don’t actually know what that means.

1 year, 5 months ago
(updated 1 year, 5 months ago)

I managed to get the reload labs fixed to get ALL labs across all surfaces, I can create a PR if you need it.

But it made me think, is there anyway to get all the labs on all surfaces when the game loads rather than having to rely on mods raising the create event?

EDIT: My fix appears to be hit and miss. So I'll leave the PR for now.
EDIT2: Fixed my fix

1 year, 5 months ago

Awesome! A PR would be welcome!

1 year, 5 months ago

Sent the PR, fingers crossed it is ok

1 year, 5 months ago

Cheers, I’ll probably be able to look at it on the weekend.

6 months ago

Thanks for the fix. It is in 1.1.4

New response