How to return a ref to a struct?

This may have gotten lost from our tests, and I didn’t reiterate this so my bad but, I was originally set out trying to make an array of structs that was private. I want the array to be managed my the class but the structs themselves free to be changed. My class would have been that wrapper for the array but since I want BP support it needs to change a little due to BP nodes not allowing ref returns.

1 Like

Agent Ransack by Mythicsoft is a good tool to scan code. Much better than Explorer.exe or Visual Studio. Beats Github too.

Done searching before you can walk to the coffee machine.

Lots of blueprint nodes you can find by searching “Kismet”. At times it looks like at some time code was supposed to be separated as a “blueprint layer” from c++, by adding function libraries and such, but in the end most of such code got blended into a soup.

In my experience projects get less and less set in stone while they grow if you start with the programming, and not start with writing the core idea on a piece of paper and stick with that from the start. Often in gamedev you’d make a quick demo to present the idea of a game mechanic, but in modern times with game / engine code often being more complex than sending a rocket to the moon, it’s just going to hurt everyone by making such things in blueprints. If the demo succeeds you have to trash all the blueprints and literally create a new project to write c++ for the unportable systems.

So what I do, is write an idea down, (if you need to, do market research etc, plan ahead as much as possible for whatever it is you need.), then I write small plugins that stick to their own core functions. These little plugins can be put online for sale standalone, or combined into a large system, the (project) idea you wrote down at the start. You’ll barely have to trash anything if you can always reuse the individual parts. Blueprints are usually 0% reusable to begin with.

I’m currently publishing some.

Not entirely though. If you create instance A from class X, then create instance B from class X, instance A can access the private data of instance B. Only class X can not access anything private from class Y.

In the end, access specifiers are more of a design tool for programmers to limit how classes can interact with eachother (not instances), and with that, reduce chance of unintended implementations.

It’s also more of a limitation to your own code and not a security feature. It’s possible to bypass entirely in a running program.

2 Likes

I’m very much an aspiring indie dev so I appreciate all the insight.

My project is one that is starting on paper, game doc still a work in progress but the core game-play is there. I’ve just been developing what I know is needed so far to get the core mechanics down so I can experiment with some other design ideas to find what is fun and feels good in game. You’ve convinced me though to just dive in and cut to the chase with C++, since I’ll probably end up there anyway.

I actually did plan on releasing some of my code on the marketplace, to sort of help people like me trying to make their projects and I’ve identified some parts that can be turned into reusable packs that would have helped me with this project and for making similar game ideas. This is actually why I want to support BP so much, to help beginners, but maybe this is too limiting. I see your opinion may be bias but do you think C++ would be better than BP packs on Fab?

Also You say BP is “usually 0% reusable”, why do you think so? BP can make classes and objects that focus on their own functionality, same as a reusable class in c++, just limited to the confines of BP (like not being able to fully utilizes refs as we have found).

i wouldnt agree that its 0% but BP has a lot of dependencies.

ie you can use the c++ Actor in any project, but MyBPActor is likely tied to all the other systems in your game (items/attributes/interactions) etc so its hard to reuse in a different project unless its built to be super modular (interfaces/base classes)

I can’t tell how many blueprint users / beginners there are (are there public market statistics anywhere?). In the end anyone will use blueprints to some point (widget design, animation blueprint). Beginners who just use blueprints to learn programming miss the concepts, syntax of C++ entirely, and aren’t instructed on design patterns etc. In the end blueprints pushing beginners to stick with more blueprints is going to prevent them from moving on to C++. On the other hand, some non programmers like widget designers will stick with blueprints to script their visual animations for widgets. If you target programmers as customers, and don’t want to target beginners forever, go with C++. Possibly you’ll also spend less time on support for absolute beginners when you start selling.

What might appear reusable will be disappointing because of the issues you run into, requiring you to recreate the blueprints over and over, defeating the point.

So often when you change an enum in BP or C++, all your blueprint nodes will die with an error or change to byte type. This is a LOT of fun when you have an animation system the size of ALS running on 50 different enums and your entire animation blueprint dies. BTW, because it’s blueprint, that single blueprint is also 25MB and binary to commit to version control. PAIN.

When you want to port a struct to C++, it’s been proven that Core Redirectors do not work, again destroying all work from datatables to nodes. You can’t even change the struct reference a datatable was built on.

When you start moving assets around (regardless of redirectors) soft pointers will break (project settings, blueprints, some assets.) like occasionally references break in animation system (say sound effects while walking, or anim notifies). Most people WILL move things around (this includes renaming assets and using their own folder structure).

Most of the errors and broken pointers you will not notice as there are no logs for them or they don’t pop up unless you inspect the individual asset. Blueprints also corrupt easily and don’t properly clean themselves of old data (old properties etc. literally stick in there.). Try telling a C++ dev that BP is most of the product and they’ll screech in terror. :slight_smile:

Once a blueprint node needs to be updated to match c++ code (say a method name changes or a function parameter), you need to reconnect all the pins (dragging A to B with the mouse like you’re working in MS Paint) or recreate all the nodes manually. You can’t do a simple text “find and replace” action.

I’ve been on the edge of “why the h*ll” am I even doing this too often until I went for C++.

Modularity should be the plugin level (make a plugin for items, another for attributes, another for interactions), then on the project level create a new MyBPActor attaching those components and implementing communication between them. The plugins will remain decoupled at the plugin level, the project puzzles them together customizing to the specific project needs.

I’ve specifically not mentioned interfaces, because if you introduce interfaces on the plugin level you would have to couple the plugins (the interface needs to be known to both), which is the opposite of what you want. FAB doesn’t allow listings with user plugin dependencies so there is also no way to build such coupling or extensions or bridges.

I’m making this just to get all the answers together for anyone in the future coming across this.

Here is the simple answer:

If your objective is to change struct objects in an array within BP, just use Get (by Ref) node. You can wrap it in a Macro to add extra logic. This is also assuming you have reason to stick with structs rather than using classes.

Longer answer:
It looks like you might be able to actually make nodes in BP that truly support refs using CustomThunk and UK2Nodes. These are both something I am unfamiliar with and did not confirm so pursue this solution at your own risk.

I suggest this as an answer due to my understanding that this is how you would create your own custom nodes for BP instead of letting Unreal generate it. Also the extensive use of CustomThunk in the UKismetArrayLibrary, which is where I think the Get by Ref node, and this article

Side Note:
I found that UPARAM(Ref) can be put in front of the return type of a function, making the pin in BP appear like a ref (diamond shaped)

This seems to be unintended and does not actually do anything functional.

2 Likes

I’d still definitely report this as an engine bug, linking this forum thread with it. Forum no longer supports a bug report section for non fortnite issues (yes…) but there’s another way.

1 Like