Code-only / code-first / hot-reload questions

I’m diving into UE5 with a “mostly procedural except for sounds and fonts” hobbyist / side project idea of mine. Although new(ish) to UE5 (practiced through plenty of C+±involving-but-not-only UE5 courses on gdtv & udemy for weeks, plus gobbled up plenty of the docs, API docs and other learning materials), I’m OK-versed in game engines in-general (and previously Unity & Godot in-particular), rendering basics, shader coding, and indeed C/C++.

Well so I have this tiny starting point of my project right now with a fully-empty map/level. Fully black in edit mode of course, and to bring up something-to-see in PIE, I have this working basic sky setup just to kick things off:

void AMoGameMode::InitGame(const FString &mapName, const FString &opts, FString &errMsg) {
    Super::InitGame(mapName, opts, errMsg);

    auto moWorld = this->GetWorld();

    moWorld->SpawnActor(ASkyAtmosphere::StaticClass());

    ADirectionalLight* light_sun = (ADirectionalLight*)(moWorld->SpawnActor(ADirectionalLight::StaticClass()));
    light_sun->SetMobility(EComponentMobility::Movable);

    ASkyLight* light_sky = (ASkyLight*)(moWorld->SpawnActor(ASkyLight::StaticClass()));
    light_sky->GetLightComponent()->SetMobility(EComponentMobility::Movable);
    light_sky->GetLightComponent()->SetRealTimeCaptureEnabled(true);

    moWorld->SpawnActor(AExponentialHeightFog::StaticClass());
    moWorld->SpawnActor(AVolumetricCloud::StaticClass());
}

(As we know, the defaults for those are pretty enough to move on and deal with more crucial things for now =)

Well, a couple practical newb questions:

1. Anything off/inadvisable about the above, or footguns?

Other than “modularize rather than everything in there” of course, that’s clear.

But eg. should I do BeginPlay or GameStart or some such rather than right-on-gamemode-init? If so why? Not sure with fully-empty maps/levels. Works for now though. Curious about lurking footguns.

2. Just when does Hot Reload hot-reload and when not?

This seemed glitchy, as follows. Using 5.3.2 on Linux with VS Code here. I went line-by-line, doing a Build, getting a UE5 “Hot-Reloaded” notify, went into PIE. How it went:

  • First added SpawnActor(ASkyAtmosphere::StaticClass()); and SpawnActor(ADirectionalLight::StaticClass()). Sky & sun showed up in PIE right away.
  • Then light_sky but couldn’t tell, there’s no light receivers yet.
  • Then SpawnActor(AExponentialHeightFog::StaticClass()) — nothing in PIE (ie. still black-below-horizon) despite Hot Reload notify. Tried “Rebuild” instead of just “Build” on the code side, still nothing. Quit vsc, restarted UE5 editor, re-opened vsc, rebuilt, then it showed in PIE (blue not black below horizon).
  • Finally, SpawnActor(AVolumetricCloud::StaticClass()) — same ordeal! Quit, restart, rebuild, PIE, only then, clouds.

Why did the early 2 steps “work in a RAD way” and the final 2 steps did not? How can one predict this? It’s not like I added new .h or .cpp files in between those. When it works, it’s very promising for rapid iterating. But if it’s a gamble every time with 50/50 odds… ouch?!

(To pre-empt the common advice about “prototype in BPs first, then put it into C++”. Might even do that for some scenarios/situations, or any marketplace-asset adoptions-adaptations, but endless node-clicking/dragging/plugging/unplugging ain’t my thing, esp. for some exploratory/experimental mostly-procedural side project.)