Custom functions are not instantiated and are part of the same graph, indeed like events, hence more advanced since they can also return a value and support latent nodes to run inside them like a wait for example. They don’t hold local variables on their own thought.
However, Macros are more similar to what you are after. Macros are basicaly flowscript graphs that can be re-used any number of times. They can have multiple inputs and outputs (both flow and value ports), and also hold their own local variables per instance. Do note however that a node referencing a Macro will only instantiate the Macro once, and not each time the Macro is called.