GAMEBREAKING - instantieting materials inside npc_behavior_class ALWAYS throws COOKING ERROR

Summary

UEFN throws cooking error when you update an edit session after instantiating material from within npc_behavior_class EVERY SINGLE TIME. Managed to get 100% repro rate.
Both UEFN and Fortnite files verified, PC restarted, happens on old projects and newly created ones.
TLDR:
Add “DynamicMaterial : M_DynamicMaterialTest_material = M_DynamicMaterialTest_material{}” tp your favoruite class derived from npc_behavior_class and get a cooking error

Please select what you are reporting on:

Unreal Editor for Fortnite

What Type of Bug are you experiencing?

Verse

Steps to Reproduce

  1. Create a new blank creative island project.
  2. Add new Verse fike deriving from npc_behavior_class and name it “new_npc_behavior”.
  3. Create a new material with at least one parameter (probably beaks with no parameters too) named “M_TestDynamicMaterial”
  4. inside created “new_npc_behavior” under “new_npc_behavior := class(npc_behavior):” add “DynamicMaterial : M_TestDynamicMaterial_material = M_TestDynamicMaterial_material{}”
  5. Create new NPC Character definition and make it use verse script. Also set NPCBehaviorScript to “new_npc_behavior”
  6. Add NPC_spawner_device to a map and set its NPC character definition to the newly created one.
  7. Push changes and enjoy cooking errors preventing you from correctly launching a session every single time

Expected Result

Instantiating meterial from withing npc_behavior derived class does not cause cooking error

Observed Result

I get cooking error every time I launch a session

Platform(s)

ALL?

Upload an image

Additional Notes

Instatiating material works from creative_device in the same project. TEST_DEVICE:
using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }
using { /Verse.org/Random }

TEST_DEVICE := class(creative_device):
@editable ExistingProp : ?creative_prop = false
@editable SpawnableAsset : ?creative_prop_asset = false

DynamicMaterial<private> : M_TestDynamicMaterial_material = M_TestDynamicMaterial_material{}

RefreshInterval<private> : float = 0.2

OnBegin<override>()<suspends> : void =
    Sleep(1.0)
    if(TheProp := ExistingProp?):
        TheProp.SetMaterial(DynamicMaterial, ?Index:=0)
        Print("Existing Prop: dynamic material set")
    loop:
        Sleep(RefreshInterval)
        NewAlpha := GetRandomFloat(0.0, 1.0)
        set DynamicMaterial.Alpha = NewAlpha
        Print("Dynamic material Alpha set to: {NewAlpha}")

Hello,

UEFN is still technically in its infancy so there are many dependencies stripped from the standard UE editor and because of that, it will usually take more experimentation and work arounds to fix the subsequent issues. More of the issues are related to memory due to budget limitations and the source control not being completely reliant on unreal’s servers. Typically if an asset is too large/heavy in memory or becomes corrupted after you reopen the project, the log will tell you the asset ID so the line error in your screenshot is a similar situation.

Potential solutions, even if temporary:

  1. Try to use a different Class for Material Instantiation since material instantiation works in creative_device but not in npc_behavior_class, consider moving the material instantiation logic to a creative_device class. Then, reference or interact with this device from your npc_behavior_class.

  2. Instead of directly instantiating the material in npc_behavior_class, try creating a helper function or a separate utility class to handle material instantiation. This can isolate the problem making it easier to compare the errors from using the npc_behavior_class vs the creative_device.

  3. Check the npc_behavior_class documentation as the npc_behavior_class may not support dynamic material instantiation as another result of the “dumbed down” feature hierarchy.

It would also help to know your specs and if you are using custom materials or sharing instances across more than 1 UEFN device or asset, like if you were to create Child actors to inherit all functionality from an existing blueprint.

Try this in Verse to manually link/call on the material:
verse
ProxyDynamicMaterial := ProxyMaterialInstanceFromDevice.DynamicMaterial

Use Material Parameter Collections to allow to control material properties without directly instantiating materials.

  1. Create an MPC in the editor and add necessary parameters.
    2. Use Verse to update the MPC values at runtime.
    3. Link the material instance to the MPC in the material editor.

If not, then assign the dynamic material instance to the NPC in the editor instead of in the Verse script as this can avoid instantiation at runtime altogether.

Modify the class to instantiate the material later. For example, on spawn or first use, instead of during class definition.

          verse
 OnBegin<override>()<suspends>: void =
     DynamicMaterial := M_TestDynamicMaterial_material{}

Remove all parameters or layers and test with a basic material. This can help identify whether the complexity of the material contributes to the error. As you may know, Unreal doesn’t like large textures or caches.

If all else fails:
- Close UEFN.
- Navigate to Engine/DerivedDataCache
- Delete the cache files and relaunch the editor

Instead of assigning the material directly in the NPC behavior script, assign this functionality to a creative_device and trigger it via event handling.

Let me know if you need more help

@Croppa I tried re-creating it and while initially it gave cooking errors, I fiddled around a little bit, making them as @editable 's then changing them back etc, and it now cooks just fine, The print messages seem to work fine but I couldn’t find any way to actually link a prop to the NPC Behavior. It just kept staying empty.

These are the project files for anyone interested.
Project.zip (4.0 MB)

The code I had was the following:

using { /Fortnite.com/AI }
using { /Verse.org/Simulation }
using { /Fortnite.com/Devices }
using { /Verse.org/Assets }
# Getting started: https://www.epicgames.com/fortnite/en-US/creative/docs/uefn/Verse/onboarding-guide-to-programming-with-verse-in-unreal-editor-for-fortnite

# A Verse-authored NPC Behavior that can be used within an NPC Character Definition or an NPC Spawner device's NPC Behavior Script Override.
new_npc_behavior_basic := class(npc_behavior):
    DynamicMaterial1: RENAMED_Inst = RENAMED_Inst{}
    @editable CreativeProp : creative_prop = creative_prop{}
    @editable MyInt : int = 5
    # This function runs when the NPC is spawned in the world and ready to follow a behavior.
    OnBegin<override>()<suspends>:void=
        # TODO: Replace this with your code
        Print("Hello, NPC!")
        CreativeProp.SetMaterial(DynamicMaterial1)

    # This function runs when the NPC is despawned or eliminated from the world.
    OnEnd<override>():void=
        # TODO: Replace this with your code
        Print("Goodbye, NPC!")

Thank you for your input - I really appreciate it.
@MichaelGrinberg1 I’m using Lenovo 5 Pro with i7-11800H, 32GB of RAM, RTX 3060, running windows 10 with latest system and driver updates.
I do not use any other inheritance then from npc_behavior_class and creative_device as I recreated problem on a blank project in a simplest form possible. To be clear the only thing that triggers cooking error is that one line of code with instantiation of a material directly from npc behavior class. For this I used simple material with only one scalar parameter but I think it’s not about material itself.
I’ll test all the solutions you gave me as soon as I have a moment - thank you!

@Mineblo Thanks a lot! I also managed to remove cooking error once I think, but then I had to refactor part of it in my original project and it went back to hell :upside_down_face:
I’ll look into project you provided and try to replicate it in my project. I’ll let you know if it worked!

Thank you guys!

1 Like

I played a little with your feedback. Cooking errors seemed to have vanished even without me taking any action. Magically dissapeared.
Even though cooking error was gone SetMaterial() method did not work with Material instatieted from the class level. Moving material instantietion to the method level solved the problem.
Sollution works both for npc_behavior_class and for base classes.
Thanks for your help!

1 Like