What does a Graph get-variable node mean?

I was confused as to why my missiles seemed to be firing out of the wrong tubes (including the last one not animating at all) and the conclusion I could draw was that the “flow” of values in blueprint Graphs is not particularly clear. Specifically, two lines coming out of the same source may have different values!

Consider this example:

I would expect the value that comes out of the “Num Missiles” getter on the left to be the same for all the different nodes that use them. However, any use if this value after the “Set” node has been executed will read a different value than the uses to the “left” of this setter. This was highly unintuitive to me, I assumed that setters are monadic, so that only getter nodes that have a time dependency for “after the setter” would see the new value.

Separately, I also assumed that nodes are lazy evaluated, such that the first node that “pulls” a value out of a node forces evaluation of that node, and that output then retains that evaluated value (no re-evaluation happens of a particular output for a particular invocation.)

For the behavior I’m seeing to happen, BOTH of those assumptions have to be false (at least for variable getter nodes.) I consider that to be a bug – I’ve used a variety of other graph-like functional-like systems in the past, and they would typically work like that, and the UE graph behavior is highly surprising.

If it’s not a bug (“works as implemented,”) then I feel that the evaluation rules for nodes must be specified and documented somewhere a little more formally for it to be possible to develop blueprint graphs with any level of correctness. For example, if I pull a value out of a complex mathematical expression more than once, will the expression be evaluated once or twice? (This may have minor performance implications.)

"
Separately, I also assumed that nodes are lazy evaluated, such that the first node that “pulls” a value out of a node forces evaluation of that node, and that output then retains that evaluated value (no re-evaluation happens of a particular output for a particular invocation.)"

What you are seeing is the concept of C++ Pointers in action :slight_smile:

The variable that you are drawing from multiple times is a pointer, it is not a bunch of hard data / copied data. It is just a pointer to a memory address.

If you change the data at that address, or point the pointer to something new, then the pointer now points to new data, and so when you draw from it later, it now points to new data and returns that new data

no extra copies of data are being saved off as you mentioned in quotes

You are working directly with a memory address, when you modify the memory at that address or point the pointer to a new memory locaiton, of course calls to it later will reflect your changes.

Design your work flow with this in mind and you will find this is actually a great benefit and improves the speed and efficiency of Blueprints

#Arrays

Try making an Array of your actor type and using a for each loop to make this more intuitive process for yourself.

Then each entry in the array will always point to the same actor/data, once you initialize the array.

Rama

While it may be true that a “variable read node” is “only a pointer,” that still doesn’t define when the value will actually be read.

Also, that is a terrible match to the idea of a functional graph programming language – these languages have been done before many times, there is lots of research to them, and lazy-monadic is a much better match for that model than haphazard-mutable.

So, thanks for the comment, but I’d still like to see what guarantees, if any, are actually made for when various values will be fetched/computed. Clearly, for example, the output of the “-” operator will not be read only through a pointer access.

Just to be clear, there are still open questions here. This question isn’t actually answered, although I appreciate Rama’s answer.

For example, if I pull a value out of a complex mathematical expression more than once, will the expression be evaluated once or twice?