Continuation - Adding a custom hologram for the locomotive to set a variable in a mixin
259 Replies
It has been attached to this message.
-# Responding to
Crash found in FactoryGame.log
triggered by @The Urban Goose[2025.08.28-13.17.35:139][552]LogBuildGun: Warning: (2) BP_BuildGun_C_2147463161_BuildState::GetHologramCost failed cause no hologram spawned.
In Root Game Instance:

Hmmm, so I think the hologram fails to spawn something
Sadly the top of the callstack says "UnknownFunction" :(
Classic
You sure it's not the game not being able to spawn a hologram at all?
It happens the moment I click the locomotive in the build menu.
Gonna try it with the very last node (the "set" node) disconnected, let's see what happens
(Just making sure the checks are not messing with it for some reason)
Okay, that shouldn't change the hologram
No crash
So it's that node
Gonna try it like this

Okay
Does the crash happen with both vanilla and modded locomotives?
Yeah, happens on the vanilla loco too
Since we're overriting the hologram in general
Still happens
Hmmm, can you show me the full editor window for the custom hologram?

(it's uncompiled cause I deleted a node for the currently unused variable)
Okay, not sure if it matters but try copying the Arrow component from Holo_Locomotive
Also try disconnecting the Exec pin from Configure Vehicle so that the thing does nothing
Done both, trying it now
Still an instant CTD when I select the locomotive (I've been trying it with only the vanilla one for now)
Huh, this is weird
Not doubting you, but could it potentially be the C++ code you wrote?
Maybe something I broke to do with it?
What does the C++ code look like right now?


Missing semicolon on line 18 in FGBUnitHologram?
UFUNCTION
, UCLASS
, UPROPERTY
and the like don't need a semicolon at the endAlright, fair
IIRC, they're macros that expand to absolutely nothing when compiling C++, but that UHT (Unreal Header Tool) uses in order to generate things like reflection code to expose those things to the BP side
Ah, I see, yeah, that makes sense
OH
I think it might be this?

Didn't set that up
nvm, the default locomotive is set up like this as well
I don't know, copy the values from the locomotive hologram
Yeah, I have, it is identical


Yeah I think the only change is the Arrow component
Even that's in there now


I'm trying to replicate the error myself
Here's a thought:
The custom hologram has a definition for a recipe, but that only takes one.
Could it be the fact that the recipe is set to my custom one, while I'm trying to build the train with the default recipe?
That shouldn't matter
I know it's crashing somewhere when spawning the hologram (BeginPlay is mentioned)
But I'm not sure why that would be a problem
And the CDO should apply to the BP_Locomotive class, not instances in the world, so it's not a case of the hologram reference being changed while the game is trying to access it?
There's also this

What is a nullpeter??
I know of nullptr but not nullpeter
That basically means "nullptr"
I guess it's funnier to spell it like that
fair?
I assume that's not it either?
But yes, it means the recipe class passed to
FGRecipe::GetRecipeName
was nullptr (so not valid)
I'm trying to do this but I keep getting distractedAll good lol
Ah, right, the CDO that you edit needs to be saved to a variable in the game instance
Ah
The output of
Get Class Default Object
should go into a variable, then you would use the variable
ExampleMod should be doing it this way too (although ExampleMod uses a sub instance module to keep things tidier)So this then?

Yeah, you can also use a Get VariabΓ±e node for the rightmost connection
Gonna switch back to that in a moment, trying this out first
Same for the == node?
Ope, still crashes
The one going to the equals node is fine
It's just to avoid the long line, lol
Oh you meant to the target on the set node
Yeah, I peronally actually perfer this, makes it easier for me to tell what's happening
Fair enough
And yeah, the crash is still happening
Am about to test myself
Hmmm, for some reason it seems to work over here
Then I'm doing something wrong I guess
No bloody clue what though
I'm only testing a hologram atm
With or without custom C++?
The C++ I wrote
Actually I just thought of another thing:
The vanilla locomotive hologram is based on FGRailroadVehicleHologram

IDK if ours is?
Yeah, the BUnit hologram should be
See header file
Alright, just double checking everything I can think of
At this point I'm tempted to have you DM me the build that's crashing you to see if there's more info in there
As in just DM you the built mod from my mods folder?
Yes, are you using Steam?
Yeah
That works
(if we were using different platforms, you'd need to package for release because C++ gets built separately for Steam and Epic)
Ah
sent
Testing
It's in Tier 6, currently still as a separate milestone (I'd want it as part of the locomotive milestone, but one thing at a time)
I tested the vanilla locomotive and got the crash
Oh yeah, happens on that one as well
Now we know that it's failing in SpawnLightWeightInstanceData
For reference, I made my hologram class by copying
Holo_Locomotive
and then reparenting itCould try that
Still crashing
Hmmm, same 3 UnknownFunction things?
Waiting on the error reporter
So, to be clear, does it crash because of the hologram? Or because of the mixin?
This disappeared
It has been attached to this message.
-# Responding to
Crash found in FactoryGame.log
triggered by @The Urban GooseI'd try disabling the mixin completely just in case (remove from instance module)
Same line numbers so same lightweight crash
Still crashing
Huh, I'm stumped
.-.
I've been doing that a lot lately
Do you do any other changes to the locomotive?
Shouldn't be, no
No other mods installed either, so no possible conflicts
For reference, this is what I tested with


Gonna do that then
I get no crash, and I get logs from
Configure Vehicle
Still crashing...
At this point I think I just broke something somewhere else
Would it make sense to try to make a new project to test?
Just blank project, add the C++ class, add the hologram, and test just that
I would try to make a new mod tbh
Yeah, that's what I was meaning
Ah
I die a little bit inside when people go for the nuclear option of starting from scratch while I'm trying to at least figure out what went wrong
I get that, but this is just so few files, and copying the assets into the folder works
I meant the "let's delete the entire project and start from scratch" approach
I just wanna make sure it's not something with the Linux editor or something like that
Yeah, I meant just the mod folder, I kept everything else
It's just that building takes a while for me, so I hate having to do that
Eh, I can deal with it
You said it works for you on a clean mod with just the hologram, so I'll try that.
If that gets us further, I'll be back to where I was in no time at all
So just so I have the steps clear:
- Copy Holo_Locomotive and rename
- Reparent the copied BP to custom C++ class
- Add CDO for the hologram like in here
Reparent the renamed Holo_Locomotive to custom C++ class
The original should be left as-is
That's what I meant I was just being dumb there
Alright, got distracted but I'm now testing this
Yep, still crashes, so it's something else...
Did you remove your existing mod from the Mods folder?
...
I thought I did, I may have not
Ok, empty mods folder, trying again

Still happening
Ugh, but why?
Same error too
It has been attached to this message.
-# Responding to
Crash found in FactoryGame.log
triggered by @The Urban Goose(For clarity: I copied the mod out of the folder, and made a new one under the same name)
Hmm, can you send me that minimal test case you've made? I'll try to build it locally here and see if that might be it
DMs work
The mod folder from the SML project, yeah?
Yes
done
Had to do some shuffling around to avoid name clashes with the C++ class
We could also rename the C++ class
I renamed it on my end
So no problems there
It's just that I had to do some shuffling around to avoid having a BP asset without its C++ class (then it can't be opened properly anymore)
Ah
Okay, so. Survey says...
It's something about building on Linux. It works fine here.
Hmm
Yeah, was beginning to assume that
Now that is cursed
Yes, yes it is
Is it time for a Mircea ping?
Most likely yes
Are you gonna do it, or do I?
The only other thing I can think of is that we're somehow not using the same headers, but that's weird
I mean if we can check for that somehow, I'm good to check
I can try comparing the DLLs you build against the ones I build
One moment
You'd need my built mod then
one sec
I have them in the Binaries folder
Right, forgot about that
I mean logically there should be a difference, right?
@Mircea (Area Actions) It seems we have a case of a mod that crashes when built on Linux but works fine when built on Windows. Here is the source of a mod that can be used for testing
That's what I'd like to compare
Well, in that case I'll be AFK for a bit, I'll keep an eye on the chat
Okay, I see one difference so far: the vftable for the working case has 302 elements, the vftable for the failing case has 301 elements
Maybe I broke something in the main SML project when trying to recover from the C++ class I mistakenly added to FactoryGame that one time?
I don't know, use git to your advantage
You cloned the SML repo, right?
I did
git status
my beloved
My guess is that the call to SpawnLightWeightInstanceData
(virtual) was actually meant to call something else
The one commit I have is placeholder assets in the locomotive folder (speicifically the particle effect, and the animation blueprint, the latter of which I didn't actually end up needing)
Okay, looks like C++ is not affected
Locomotive physics asset as well, but yeah, only three uasset files that my mods need to reference

Well, two, and one that I thought they did
Can you look for
ShouldUnlockHologramOnBuildStep
in your project? Should be a virtual function in AFGHologram
How, search in C++ classes?
Or where?
oh in Rider
Files are stuff I got from Ghidra that show the difference
Can't find
ShouldUnlockHologramOnBuildStep
in FGHologram.h

Okay, make sure you're using latest master then
https://github.com/satisfactorymodding/SatisfactoryModLoader/blame/4562fdcd7a8e6c06be5dc207eb6d2479e1570302/Source/FactoryGame/Public/Hologram/FGHologram.h#L454
It was added two months ago
Github is doing the thing where the page won't load right, bear with

I'm just showing the blame thing, the file is a bit long

Yeah, but if you look, the header on the website hasn't loaded right
Couldn't interact with anything
No worries
You should check the version you currently have
And my guess is that you should update the modding project
So just drop this in, and replace the one I have, then rebuild the project?
No
But I just cloned it a few days ago?
Which branch did you clone?
Can you run
git log
?
OH, RIGHT
You're using the linux-editor branchYeah
That branch hasn't been updated to the latest SML version
.-.
Hold on, we're going to cherry-pick the header changes
Which is just one commit
So, stash / commit the changed files you have here, then run
git cherry-pick 167d475fbdae796462d4842d2afe3ff27c06cea4
(which is https://github.com/satisfactorymodding/SatisfactoryModLoader/commit/167d475fbdae796462d4842d2afe3ff27c06cea4)(I am also still learning git, so bear with me here)
Pretty sure they are committed, just not pushed, which should be fine, right?
Yeah, that was a screenshot of a commit

I meant that here you have changed DefaultGame.ini and Locomotive_Skeleton.uasset

If you could cherry-pick as-is, I guess it worked because the commit didn't touch any of the modified files
I could cherry pick as is
(Wouldn't have been an issue to lose those changes, don't remember changing the ini and the skeleton is changed cause I had opened it)
They're still there though, so all good
You wouldn't have lost the changes, git would have complained
But yes, that's all cool
You may want to do all the magic spells to build C++ again, then try and see if it crashes
Doing that right now
70 actions, so it's definitely rebuilding stuff

The files touched by the commit, although since it uses unity builds you don't see much going on
Right, build done, starting up the editor now
Editor open, building the mod
Mod build needs 214 actions, so it's doing more
Also yeah, I understood that, and I'm beginning to understand how the C++ workflow works
Don't understand any of the C++ code itself, but at least I can build the project now
I can at least read python and kinda follow that, C++ is just way too cryptic for me to understand most of it right now lol
Mod built, let's see if this works
NO CRASH!!!!
π π π π
\o/
Right, I assume the main mod will build now, gonna go ahead and test with that now
The function I made for the hologram thing is rather simple. It's a virtual function, that overrides the base class' implementation (this concept also exists in Python).
It begins by doing two things at once:
- calls the base class' implementation (with
Super::ConstructVehicle
) and stores the result in a variable named Vehicle
.
- checks if Vehicle
is not nullptr (nullptr evaluates to false, non-nullptr evaluates to true).
If Vehicle
is not nullptr, then it calls the ConfigureVehicle
function that you see in Blueprint (passing Vehicle
as parameter), and returns Vehicle
.
Otherwise (Vehicle
is nullptr), it returns nullptr directly.
The assignment inside the if-statement can be separate, but I prefer having it combined to avoid using something when it may be nullptr (bad things happen).
Python equivalent:
Right, that's everything restored to how it was before we disassembled it for testing, it should work now
@Mircea (Area Actions) Okay, it seems that the root cause was that the
linux-editor
branch wasn't using the latest headers. I've made a PR here: https://github.com/satisfactorymodding/SatisfactoryModLoader/pull/389hmmm, so no crash, but also no B-Unit
Okay, let's revise all the Blueprints
We have to reconnect stuff, and make sure the actor mixin is registered in the game instance module
I have one thing I can test still
Other than that I would've just gone in with print statements
Got to do the dishes now, will check back afterwards
Removed a check that happens for the hologram swap, just gonna swap it without checking for now to see if that's it
Yeah, I still gotta go afk as well, cause I didn't actually end up doing that either
Alright, tested it the Boolean doesn't correctly get set to true, it works if I set it in the editor, but obviously that'll apply to the default Loco as well.
Means the error is here somewhere, specifically the last node which doesn't work right.



Print the value of
mBuiltWithRecipe
(To be clear: not having the branch there also doesn't work)

Oh, so that doesn't work either
no
Have you tried logging the value of the boolean at various points inside the mixin?
I think the boolean is not set in the mixin when
BeginPlay
gets called
Actually
Instead of using a boolean, make a function in the mixin and call itRight, just did it, trying that now

And then Make B-Unit has just the stuff from begin play
We have a winner ππππ

Doesn't persist through saves, but that can be solved, I really need to go now
(and now that this is done my brain will let me)
Oh hey cool, sampling works correctly
I think you can have a bool variable in the mixin, that is set to
SaveGame
, and that you use to call Make B-Unit
in BeginPlay if it's setGonna try that when I'm back home
So the problem was the base game skeleton asset stub being modified?
Speed read this thread while in the airport and that sounds like it was it?
Or was it the Linux editor branch of SML being behind latest SML?
The linux-editor branch of the SML project was out of date, some headers were outdated, so the C++ compilation didn't work correctly
The skeleton had nothing to do with it, that's unrelated
As far as I can tell the value isn't saving, I'm currently assuming I'm doing something wrong
No, the problem was headers being out of date, see https://github.com/satisfactorymodding/SatisfactoryModLoader/pull/389
Do I need to do anything other than creating the boolean, and ticking "SaveGame"?
I would have thought that SaveGame would work
AActually, I may not be setting the value right?
I don't know, I can't see
Lemme get it back to how it was before I disassembled for testing, then get you some screenshots
Mixin Functions (Make B-Unit and Make NormalLoco have been tested and do work when correctly when building with the buildgun in game, and have been cropped for brevity)
IsB-Unit is needed for EventTick to update particle effects and the engine glow.





And Configure vehicle in the hologram:

InitAsB-Unit has SaveGame ticked, IsB-Unit doesn't


(Just went and removed the
-
from the variable names, just to see if that helps)Is the idea of
IsBUnit
to avoid double initialisation?Yeah
Well, IsBUnit exisisted first, but yes
Hmmm, if the variable's value isn't saving, I'd say let's move the recipe check inside the mixin
Gonna give this a go, cause it does sample correctly when saved, so the recipe gets saved

Yes, I realise that does make the custom hologram thing a bit pointless
No, cause I still need it to build it
Huh
Wait no, I don't do I
Do I?
If moving everything into the mixin, the default
Holo_Locomotive
would workoh my god
This does work
It worked perfectly on load
Does it sample properly too?
yeah
oooooooo
It just works now
This was the magic key
And I think you're right, I think I don't need the hologram
What does the custom hologram even do at this point? I think nothing meaningful
Gonna disconnect the code

As far as I can tell this should still work identically to when this was all connected
I agree
Can I use the custom hologram to overwrite the way the hologram is drawn? Right now it still shows as a normal locomotive
It does
Probably yes, but I'm not sure how holograms decide what to draw
Well technically this is ready for an alpha release
Still needs some work, but mainly cosmetic
Functionality is done
Oh yeah, I set it back to the default hologram for now, still works
Cause it was a CDO it touched the vanilla loco too, which I try to do as little as possible for compaiblity reasons (in case anyone ever makes a different loco model)
You're still touching the vanilla locomotive, but if your "make normal loco" function does nothing, then it's as transparent as it can be
The only thing it does is hide the three components the mixin creates
Oh yeah, that's a thing, I tried removing those with destroy component, which didn't work
I've resorted to just setting the visibility to off


Make B-Unit hides the spotlight, Make NormalLoco hides the mixin components
I would try to spawn the components at runtime to avoid having extra components for the normal locos, but that's okay
Oh, right, the B-unit has no spotlight because it's a middle section
Considering I have to move it into position with the BP anyway, that might be the better option
Not now though
Ok, just tested what happens when you uninstall the mod:
- B-Unit locomotives turn into Vanilla locomotives, but can no longer be sampled
- Reinstalling the mod does NOT turn those locomotives back to B-Units, they have to be manually rebuilt, sampling remains broken
Still means that as it is right now uninstalling wouldn't break any factory funtionality though
Sampling is broken because
mBuiltWithRecipe
becomes null
So it doesn't know what recipe to use to spawn the locomotiveYeah, that makes sense, assumed as much
That's what I expected though
The only way to fix it for real that I know of would be to use a core redirect
This mod has core redirects to replace belts/lifts with the vanilla counterparts: https://ficsit.app/mod/BeltMk6
You could have a note to do the same but to redirect the locomotive recipe instead
You'd need one line per recipe you want to redirect
Luckily it's only one recipe, so I only need one line
Oh my god I just realised I completely forgot to thank you for all your help, I'm so sorry
Thank you for all the help with this, I highly appreciate it!
You're very welcome! I'm happy to help
Core redirects for this case would only work when the mod is absent but the redirect is still present. How are you distributing the redirect? Presumably listing on your mod page?
I have no idea, hadn't got that far yet, hadn't even looked into core redirects yet
Quite frankly the fact that the locootives aren't just deleted is a win in my book.
The only thing that breaks is sampling, other than that they function as expected (other than likely not returning materials when disassembled, cause no recipe, haven't actually checked that yet, I had no build cost on when testing)
The idea would be that if anyone wants to fix sampling after uninstalling the mod, they can use this core redirect. Redirect would be distributed in the same way as Belt Mk7*
Done
I just remembered, that you sent this, cause I kinda blanked on it initially, and then forgot to go back.
This was actually really helpful for me to understand the C++ code you wrote (and by extension any similar C++ code I may read in the future)
I'm glad you found it useful!
We should update the Open Source Examples page with info on the new features the mod is using. Can't do that now as I'm traveling
I've been upgrading my old mods to Mixins where appropriate
Previously train interiors was adding an actor using SCS hooks, which was running a runtime mesh replacement on the locomotive.
Now I'm using a CDO and a mixin.
The "train 2" system is interesting that it can revert back to vanilla train, but I think the skins system is probably how the game "wants" you to implement it. I wonder if it would be possible to make it compatible? Not sure it's worth the effort
I'm not sure I understand what you mean
Do you think the skins system would support reverting back to default?
No, I don't think it would. I think that's the advantage of the current approach
The game already has a skins system for swapping between functionally identical buildings that are different only in appearance (in a way that can't be handled just by customizer settings), like the ficsmas skins. They can be hot swapped with each other in place iirc. Your approach doea not currently use that system
If you were to code it with that approach from the start, I don't think you could have the "on mod uninstall, it reverts to the vanilla locomotive" feature
Yeah, I find that integral to the mod, I want this to be safe to uninstall.
This way I don't break any factories by not updating my mod for half a year again .-.
That's not very Modder's Curse of you /s
Looks like I could also add an option to the mod, which allows you to convert all B-Units to normal locomotives when you load your save, to make uninstalling easier.

Sure