Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Blueprint nodes generation at runtime #33

Open
nxrighthere opened this issue Sep 6, 2020 · 16 comments
Open

Blueprint nodes generation at runtime #33

nxrighthere opened this issue Sep 6, 2020 · 16 comments
Labels
enhancement New feature or request

Comments

@nxrighthere
Copy link
Owner

A robust and flexible system should be implemented to generate blueprint nodes and data types weaved with managed code that exposes functionality to the engine.

@nxrighthere nxrighthere added enhancement New feature or request in-progress labels Sep 6, 2020
@nxrighthere
Copy link
Owner Author

The first prototype implemented. Current challenges:

@nxrighthere
Copy link
Owner Author

Seems like it's possible to generate blueprint nodes dynamically at runtime. The current challenge at this point is the invocation of user functions with variable-length parameters. In terms of performance, the invocation of functions with predefined fixed-length parameters are 195% faster than the closest equivalent for variable-length parameters:

BenchmarkDotNet=v0.12.1, OS=Windows 10.0.19041.508
AMD Ryzen 5 1400, 1 CPU, 8 logical and 4 physical cores
.NET Core SDK=5.0.100-rc.1.20452.10
  [Host] : .NET Core 5.0.0 (CoreCLR 5.0.20.45114, CoreFX 5.0.20.45114), X64 RyuJIT
Method Mean Error StdDev
'Fixed-length parameters, Function()' 2.878 ns 0.0149 ns 0.0140 ns
'Fixed-length parameters, Delegate.Invoke()' 3.850 ns 0.0264 ns 0.0234 ns
'Fixed-length parameters, Dynamic->Delegate.Invoke()' 18.292 ns 0.3381 ns 0.2997 ns
'Variable-length parameters, Dynamic->Method.Invoke()' 224.541 ns 1.3883 ns 1.2986 ns
'Variable-length parameters, Dynamic->Delegate.DynamicInvoke()' 372.478 ns 1.4545 ns 1.3605 ns

All delegates for user functions should be stored as dynamic types in a single cached collection for fast access from native code once all entry points are cached at startup.

This approach has a significant impact on performance, unlike the code generation where all functions with parameters can be predefined at compilation time.

A performant solution might be a custom blittable representation of function parameters using a single predefined function for the invocation from blueprints, but that means intermediate conversion to appropriate data types in the user function itself. This approach is counterproductive.

@nxrighthere
Copy link
Owner Author

nxrighthere commented Sep 25, 2020

Related to dotnet/csharplang#3718

@nxrighthere nxrighthere changed the title Code generation for blueprint nodes and data types Blueprint nodes and data types generation at runtime Oct 2, 2020
@nxrighthere
Copy link
Owner Author

Blocked by dotnet/runtime#42275

@dagillespie
Copy link

Looking forward to this feature. Is it in the main branch or is it pending the initial stable release?

@nxrighthere
Copy link
Owner Author

This feature is on hold at the moment, but I think I can ship it partially in the following weeks with certain limitations. The main problem is that .NET 5 lacks functionality to implement this feature the right way.

@dagillespie
Copy link

Happy to wait if .NET 5 is the blocker here (does 6 help?) but equally very happy to kick the tyres of your implementation.

@nxrighthere
Copy link
Owner Author

Happy to wait if .NET 5 is the blocker here (does 6 help?)

Unfortunately, as long as this issue remains unresolved, it wouldn't help.

@nxrighthere nxrighthere changed the title Blueprint nodes and data types generation at runtime Blueprint nodes generation at runtime Aug 16, 2021
@darkguy2008
Copy link

Happy to wait if .NET 5 is the blocker here (does 6 help?)

Unfortunately, as long as this issue remains unresolved, it wouldn't help.

As of July 12, 2021, it seems they moved the feature to the Future roadmap, which basically means "anytime between tomorrow and the next big bang, if we're still alive" although I agree with the feature, MS is MS... I think it would be a good time to think on alternatives. I'll check what I can come up with.

@hez2010
Copy link

hez2010 commented Oct 5, 2021

Since the API has been approved, I think a PR from community will definitely push the process of implementing dotnet/runtime#42275

@danielmeza
Copy link

What about use Source Generator instead runtime to improve performance?

@nxrighthere
Copy link
Owner Author

@danielmeza Blueprint function libraries compiled from C++ can't be hot reloaded. You have to restart the editor to reflect changes of nodes.

@danielmeza
Copy link

danielmeza commented Jan 4, 2022

@nxrighthere so, every code made with a Source Generator, will need an editor restart to see it on the editor?

I´m talking about this Seems like it's possible to generate blueprint nodes dynamically at runtime. we can use Source Generators to generate those nodes not at runtime but on precompile time so the performance can be improved there.

@dagillespie
Copy link

@danielmeza Blueprint function libraries compiled from C++ can't be hot reloaded. You have to restart the editor to reflect changes of nodes.

C++ can be hot reloaded into UE4 without an editor restart however it does a temporary patch of the DLLs meaning at times an editor restart is needed. Saying that USharp was able to implement hot reloading of blueprint nodes from C#.

@nxrighthere
Copy link
Owner Author

C++ can be hot reloaded into UE4 without an editor restart however it does a temporary patch of the DLLs meaning at times an editor restart is needed.

I'm talking about the cases where static blueprint callable functions are used. Once they are loaded into memory, the engine locks the entire module from hot reloading.

Saying that USharp was able to implement hot reloading of blueprint nodes from C#.

It's based on a very different approach, such as a mix of runtime pointer manipulations and code generation.

@darkguy2008
Copy link

Happy to wait if .NET 5 is the blocker here (does 6 help?)

Unfortunately, as long as this issue remains unresolved, it wouldn't help.

It seems that issue is gaining some traction now (yay!) so hopefully once it's done it will help to fix this important one. They're having an ongoing discussion now and are asking for feedback. The more we can help, the better! :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

5 participants