DDC entries that Niagara script compilation creates are not deterministic - causing thousands of diffs eg when cooking with VerifyDDC flag. The diffs (at least most of them) are in `LastHlslTranslationGPU` property, example of the HLSL code diffs is attached. The difference is in the generated function names. The majority of the diffs come from NiagaraScript UObjects having default name (equal to class name), and because the order in which niagara assets are loaded while cooking is random, the disambiguating number assigned to them is random too. There’s also some random GUID in the name generated for `CustomHLSL` function.
At least one of the reasons why CustomHLSL has non-deterministic GUID is this: `TNiagaraHlslTranslator<GraphBridge>::HandleCustomHlslNode` creates `UniqueIdentifier` by building a hash and including GetTypeHash(PinVariable) into it. The implementation of `GetTypeHash` for `FNiagaraVariableBase` includes `GetTypeHash(Var.GetName())` into the output. Var.GetName() is an FName, and `GetTypeHash` for FName simply hashes the internal table *index* rather than string itself, which is of course not deterministic across runs…
Yah, the default version of the Niagara Hlsl translator in 5.6 does suffer from these kinds of issues. 5.7 will have the default compilation changed over to a new version that is entirely deterministic (and faster and generates better code). I believe that in 5.6 there was a Niagara project setting to select this new compilation mode (AsyncTasks) if you’d like to try. I think that there were still some bugs in it for 5.6...but nothing horrific if I recall correctly. Outside of that, another strategy can be to simply not push the HLSL into the DDC (this can be helpful to also reduce DDC storage), but there are some draw backs to that (not easily being able to see the generated code in the Niagara editor, at least not initially, you’d have to do a force recompile to get it to show up, as it couldn’t be pulled from the DDC).