FortressCraft Evolved

FortressCraft Evolved

steveman0's Blueprint Builder
DrunkRJa 2 Sep, 2022 @ 2:38am
Bug: Getting only half of blocks requested from the freight system (I have a fix)
Hey steveman0!

First of all, thank you for the amazing work with the blueprint builder mod. It is really fun to use and it made the game much less tedious in some aspects! I know I am quite late to the party and you've probably moved on to other projects, but I am still going to try :)

I have been using the builder to build quite large rooms (with only the paste), using the fright system. I noticed that every time I start the build, only a part of the room is being built.
The system says that the build is not completed, but there is nothing requested from the freight system.

The problem was happening when the paste was brought by the carts assigned to the station that is managed by the builder.

The cause is pretty interesting. Each time a cart would load paste at the source station it would decrease the requested items at the builder station. Then, when it would bring the paste back to the station connected to the builder, the builder itself would decrease the number of requested items as well. It means that each delivery would decrease the number of requested items twice.

I made a fix locally. Essentially, just making a copy of the NeededItems that the BlueprintBuilder returns so that the CartMob cannot modify it. It seems to work for me now. So I was wandering if you would be interested to incorporate this fix into the workshop build.

I wanted to create a pull request in GitHub but it seems that the sources there are quite outdated so it does not make much sense.
< >
Showing 1-9 of 9 comments
steveman0  [developer] 2 Sep, 2022 @ 4:18am 
Oh, interesting. I'll have a look into this perhaps tomorrow. I recall someone reporting this or something like this before and I don't think I ever tracked it down. If I'm reading this right, it sounds like the issue is a shared reference problem. Now that I have a clue of the cause, I can probably reason through the code and fix it.

(Sorry I never ended up properly syncing my source on github).
steveman0  [developer] 2 Sep, 2022 @ 4:33am 
Ok, I was able to make a quick change and push now. Hopefully I didn't break anything in the hotfix.
DrunkRJa 2 Sep, 2022 @ 6:59am 
I've tested your fix with a small setup and it work perfectly fine! I will test is with a bigger building project in a bit. Thank you very much for such a quick response.
steveman0  [developer] 2 Sep, 2022 @ 10:08am 
Thank you for digging into the code and finding it. This is a nasty case that I could have looked at a dozen times and overlooked the implications of passing the original reference through the interface.
DrunkRJa 5 Sep, 2022 @ 6:51am 
Hi steveman0!

Sorry to bother you again, but I may have found a fix for the https://steamhost.cn/steamcommunity_com/workshop/filedetails/discussion/903287164/1742266800325548307/ issue.

I was "lucky" enough to have this problem easily reproducible in my save. It looks like that the easiest way to get a complete freeze is to select a blueprint, then quickly close all menus and remove the builder block. Probably 1 in 10 attempts should get frozen.

I did some log-based debugging and it seems that the problem occurs when the hologram gets cleared. In particular, almost always in OnDelete() method at the "UnityEngine.Object.Destroy(gameObject);" line. I am not exactly sure why but it only happends when called from OnDelete. Rotating and changing blueprints don't cause the issue, even though it may clear the hologram (with GameObjects) as well.

So my assumption is that the OnDelete() method is called from a different thread which somehow causes a dead-lock in Unity thread, or something. I am not very familiar with Unity.

So I tried to run it in a different thread that is managed by Unity (again, my asumtion) by using a MonoBegavior.StartCoroutine() method. This change seems to have helped, and now I am not able to cause a dead-lock by removing the builder, on my machine™ :)

Here are my changes:

BlueprintBuilderMod.cs
... public override ModCreateSegmentEntityResults CreateSegmentEntity(ModCreateSegmentEntityParameters parameters) ... - modCreateSegmentEntityResults.Entity = new BlueprintBuilder(parameters); + modCreateSegmentEntityResults.Entity = new BlueprintBuilder(parameters, this); ...

BlueprintBuilder.cs
... + private readonly BlueprintBuilderMod Mod; ... - public BlueprintBuilder(ModCreateSegmentEntityParameters parameters) + public BlueprintBuilder(ModCreateSegmentEntityParameters parameters, BlueprintBuilderMod mod) ... + public IEnumerator<YieldInstruction> ClearHologramCoRoutine() + { + yield return null; + ClearHologram(); + } ... public override void OnDelete() ... - if (Hologram != null) - { - GameObject[,,] hologram = Hologram; - foreach (GameObject gameObject in hologram) - { - if (gameObject != null) - { - UnityEngine.Object.Destroy(gameObject); - } - } - Hologram = null; - } + Mod.StartCoroutine(ClearHologramCoRoutine()); ...

I hope it makes sense.
steveman0  [developer] 5 Sep, 2022 @ 8:13pm 
Hmm, not sure I understand... OnDelete will always be called on the UnityThread. If it wasn't the crash would be the more obvious one indicating that unity objects aren't accessible from other threads. It wouldn't freeze, just give an error and terminate the thread.
Last edited by steveman0; 5 Sep, 2022 @ 8:13pm
DrunkRJa 6 Sep, 2022 @ 2:16am 
Unfortunately I am not able to provide a better explanation. This is the first time I am trying to do anything with Unity. In the message above I explained my way of reasoning about this issue and how I came up with the changes that seem to be helpful. I could as well be completely wrong :)

I had tried calling
UnityEngine.Object.Destroy(gameObject, .5f);
just to give it a slight delay. That didn't really help, it would only cause the freeze a bit later.

The fact is that after implementing the CoRoutine I cannot reproduce the freeze anymore. It definitely changes something, but I have no idea what it is an how to understand it better.

If you would like to investigate it a bit more, I will be happy to run some additional tests or provide more information.

In case you'd rather leave it as is, it is fine. I just wanted to share the potential fix with you, because it seems to be affecting only some people and could be hard to detect.
Last edited by DrunkRJa; 6 Sep, 2022 @ 2:17am
steveman0  [developer] 6 Sep, 2022 @ 1:53pm 
I'm reluctant to implement any fix that isn't clearly a fix. Taking the same method call and shuffling it elsewhere in Unity is unlikely to address whatever the root cause is and may just end up causing other problems. The kind of crash that's occuring is a driver / unmanaged memory issue. It's possible that shuffling it around may prevent the crash but cause more catastrophic memory corruption under the hood. Fail fast, fail loud. Rather not risk being responsible for other major game issues. DJ already gets blamed for too many mod / engine issues.
DrunkRJa 7 Sep, 2022 @ 2:17am 
Fair enough. Thank you for the explanation. The fact that it works on my machine does not mean that it wouldn't break the game for other people. I am happy with how things work locally right now, so that is enough for me :)
< >
Showing 1-9 of 9 comments
Per page: 1530 50