Perfect Plugins integration into vvvv workflow

Hello everybody,
i finally decided to open this discussion to share some thoughts about all the nice plugins that fortunally many of you are contributing. …really thanks for that :)

I’m not a code writer but i’m quite experienced in vvvv patching; i spent some time in building node branches with our belovvvved tool, trying to figuring out the best logical organization of all the parts of software i was developing.
the nice thing of vvvv simple nodes is basically they are simple but highly modular.
eg. take the “+” value node:
it does a simple operation but the great thing about it is the input/output pin connection, so that you can insert in any data flow of your patch.
i think the greatest thing of vvvv is the branching system, i mean the possibility to organize data flow in branches of operators (nodes) and get a result.
to maximize the efficency of this approach, the best way to write a node is:
-it must be simplest as possible: it does just the specific operation that caracterize it. if it does different things i thik is better to split these different functions in different nodes, so you can decide what to use/ in wich order…all the freedom we have in vvvv…
-it must be open to input/output as much as possible: it will be highly configurable and will be build thinking at maximum integration possibilities inside vvvv environment (i’ll make examples later).

sometime you’ll find the first one more handy/easy/confortable, but logically it offers much less possibilities of the second approach.

using modular simple nodes you can configure and customize your branch flow in soooo different ways, just byepassing one node, adding another one, connecting in different ways…

this example shows a chain of simple operation but imagine if they are complex functions… the advantage of having them separate would be great, allowing you to use them individually in different scenarios.

let’s make another example:

https://vvvv.org/sites/default/files/imagecache/large/images/indipendent%20or%20dipendent%20plugins.png

there is a huge difference between the two plugins.
-the first one is “indipendent”: it’s autonomous and just provide the final position of the particles with a floacking behaviour.
-the second plugin is dependent: it depends from the position data arriving from the framedelay position cycle and it just gives the velocity that boids should have accordly to the floacking behaviour.

writing the plugin with the dipendent approach allow you to combine it with other behaviours and create a complex final particle system.

instead having a super huge complex plugin (like: "floacking-predator-obstacles-food-… plugin), imagine another approach:
-the floacking plugin it’s simplest as possible: it just provides Cohesion-Align-Desire behaviour.
-then it could be another plugin called “predator”: it provides the velocity of boids escaping the predator. the inputs could be “XYZ boids”, “XYZ predator”, “minimum distance from predator”, “wethever…”
-another plugin could be “obstacles”, that provides velocity of boids avoiding obstacles you set in the plugin.
-and soo on with other features…
you can imagine the patch like this:

https://vvvv.org/sites/default/files/imagecache/large/images/Complex%20Modular%20Behaviour.png

in this way you can use these plugins in a modula way, using for example just the “predator” plugin in another particle system.

i think this is the way to go for best user experience in building patches.

in the end the main things to consider when writing a plugin are:
-what should this plugin do?
-what is the best way to write it and integrate it in the vvvv style flow?
-can i separate different “steps” in this complex function and make them separate plugins in order to increase their versatility?

…these are few of the things that come in my mind…

i already spoke with some of you.
foe example, in our first italian Patcher kucha event i spoke with fibo about his super nice chaos toys.
they have amazing potential but in the current plugin implementation they are limited to few uses and can’t be easily integrated in any vvvv patch.
as i said to fibo, these chaos toys would be amazing builded as super semplified nodes, like the perlin node: you give them a value and they returned the chaos value given by the specific chaos behaviour.
in this way they could be used in any possible way, just as “filters” to give randomness and organical behaviour to many many patches…

as i said i’m not a code programmer, but hope that what i’m trying to say will make kind of sense for you coders…
what do you think about this topic?

hope was not toooooo boring… :)
ciao!

Natan

I totally agree, and second you on this :)

Lets keep vvvv the most modular as possible!!
Splitting advanced plugins into simple ones to keep the modular aspect of vvvv should definitely be the way to go!!

This would allows to reuse them in any scenarios, and create original systems.

good point here;)

not boring at all and of course good point here!

what about
independent vs. absolute
dependent vs. relative???

Agree!
… no text …

I’m sharing same thoughts with dottore, but i don’t like loops in VVVV. I think all behaviors must be connected into each other from top to bottom, like transformations. Each behavior must just output values for objects and depends on incoming values. I think modularity in plugins is very complex task - behaviours of-course must be modular, but state machines for example not. As for me, i did no like chaos in VVVV patches, so i prefer dynamic plugins for complex calculations and logic.

I’ll say spreading is very important also , for exemple while the box2D plugin is really great , i love it… , and got a good modularity as you want it i guess ,the way it works with spread can be really improve , and patching with box2D node make very messy patch quickly , the new create body persist is already a good improvement. This is just to say that modularity is important as well but spreading also.

@alg i think loop are something you can’t avoid in programming , just look at a simple drag and drop , you need a loop to do it , and if the loop is not in the patch it will be in a node for sure , look also at feedback effect with shader… be able to access the loop give you a great control .

@Kalle :) don’t know really what’s the best terminology, we can think about it. let’s see what other users think about…

@alg
you don’t like loops in vvvv means you don’t like framedelay cycles? i think they are quite a nice feature of vvvv; i always use them and really love them…
anyway i can see your point, i know they have some limits, specially on variable count spreads …thinking at animation nodes vs variable spreads…

you told you prefer dynamic plugins for complex calculations and logic.
i agree with you about this, not for the mess patches but just because it’s easier to do some things in code than in patch.
but we have to admit that this approach necessary reduce our freedom in patch creation:
few “complex nodes”=>
-less nodes in patch > “clean patches” (i’d say empty patches)
-less possible combination > less possibilities

let me spend a word about order in patches:
occasionally i worked in patches with 1/2k nodes and i always felt confortable and never had troubles in finding/changing/…
_i really think the order of the patch just reflects how much we understand of what we’re doing. if you feel mess in the patch, it means you can’t SEE (in a_The Matrix style) all the logic flows and the relation between the “organs” of system.
i’m not talking about you :) this always happens to me: when i’m stuck i reorder the patch trying to get another more complete view of the whole system.

so, mess in the patches it’s not a vvvv problem, it’s a user problem.

if we don’t accept this we necessary are losing the best of vvvv, the true possibility of visualize logical data flows and work visually with that.

but in this post i’m really interested in finding the best way to think and create plugins intended to be contributed, means that they are really thought as “new vvvv nodes”, and they must be as flexible as possible to be integrated in any vvvv scenario. otherwhise i can’t see the point of contribute them (if i made a super complex plugin that work just for my specific project it will not be soo useful for other users…)

to me the point of writing plugins for vvvv should be:
try to get the best from both code and visual languages combining them in a unique programming experience.
this brings in many compromizes on both sides and it’s exactly here that we have to understand well what are the greatest features of both languages.

coming back to the example of flocking behaviour i did.
you told it would be better to connect different plugins in a single chain, one by one like we do with transform nodes.
i’m not sure this would be the best logical representation of this system:
let’s think at what these plugins do:
-cohesion-align-desire: "where am I? too distance from neighbours? too close to neighbours? am I going the same way as neighbours? …
input: my current position
output: the vector i should follow in my flocking behaviour.
-Predator: where am I? too close to a predator? run away!!!
input: current position
output: vector for safety escape from predator
-obstacles: am I near an obstacle? if yes,avoid the obstacle!!
input: current position
output: vector to follow in order to avoid obstacles

all these nodes have the same input source, so why connect them in chain creating a hierarchy?
my final movement vector should be just a combination of all these aspect of my simulation (mathematically should be just a vector sum); they are all important without any priority, they are “brothers”.
so in this case, the LOGIC suggesst to me that a “Parallel Approach” would reflect (and visualize) better the usage of these plugins.

it’s not always the same. i’ll make a different example:

here we have a possible floking-predator-obstacle system with a space optimization (look at this post to better know what i’m talking about: forum/flocking-behavior-simulation-plugin )
the “NeighbourFinder” plugin task is to find for each boid its closest neighbours in order to check the distance just with them (avoiding useless iterations).
there could be different “NeighbourFinder” plugins, based on different techniques (eg. grid space subdivision, quadtree subdivision, delaunay subdivision…)
and the great thing is that these plugins could be useful also in different scenarios (everywhere you need to optimize interaction between agents). this is the great thing of modularity…

in this case LOGIC tell us that there’s a specific hierarchy:
the behaviour plugins (Cohesion-Align-Design,predator,obstacles) are on the same level, but they all depends on the NeighbourFinder plugin that is on top. in fact it provides information needed for behaviour evaluation.

in the end, chain and parallel approaches have different logic meanings; we have to find out each time what’s the correct structure.

@sanch:
you’re right when saying that spreading it’s very important. it’s one of the main vvvv features…
i understand also that sometimes it’s not so easy to combine spreading approach with other coded systems (like the box2d core), and probably is not the best approach in code optimization.
as i said before, we have to get to the best compromize in order to obtain the best from both the languages. :)

sorry to everyone for my neverending posts… :D
just hope it will be useful in some way

buonanotte

@ dottore
nothing to be sorry for, I find it a very interesting read, and I’m sure others do too.

Definitely 100% agree on the use of feedback. I found this a bit confusing at first (still often do actually) but it seems simply much more deep in potential.

Just for conversation’s sake let’s take your last example and have it as a module rather then a patch. Perhaps you would then still have the top level function, and the component functions inside can still be rewired/exposed/cut and pasted/whatever.

I’ve heard that performance wise it’s good to avoid too many levels of subpatches- I don’t know how big an effect this has and what other factors are involved though.

@dottore
always very interesting posts…

@dottore Clean structure not mean “less nodes” - this is just the way of organization. Yes, mess in patches is exactly users problem. I can agree with your way of behaviors organizing. We need node - BehaviorsStack, that can join all our behaviors. As for modularity, Behavior nodes must output only Behaviors, but BehaviorsStack will output XYZ in VVVV coord space, so it can be integrated to any VVVV project easily.

@dottore @sanch About loops, i’m trying to use some OOP in VVVV dataflow, so if node is object it can’t refer to himself in most cases. I think we can somehow avoid it in boids library.

I just opened an Official VVVV Particle Library thread.
Let’s continue there our discussions about particles plugins
forum/vvvv-particles-library

@ modularity vs. ease of use

in my view you all made VERY good points here, and, like everyoneishappy points out, we could easily achieve both (modularity & ease of use) when the easy-to-use highlevel node is a module that uses the modular lowlevel nodes.

that way as a user you typically first use the highlevel node until you need to operate on the internals otherwise. the highlevel module then also provides a great show case for how to work with the lowlevel nodes.

so i would vote with dottore for a low level modular approach where nodes can combined in many ways (and where state is omitted) in combination with an additional module for high level use…
typically however it is much more work to build a system of compatible lowlevel nodes than one brilliant node, that just rocks…

@ namings (independant, relative…)

in dottores example the Position is a state.
the highlevel (independant) approach hides the state.
the lowlevel (dependant) approach let’s the user work with the state.

so i would propose to use terms like

state

  • = persistent values
  • how to produce own states: a feedback with a framedelay node
  • nodes can have hidden states inside (e.g. damper, toggle, framedelay itself)
  • modules can have hidden states inside (e.g. by using a framedelay inside)

stateless/purely functional

  • = nodes’ outputs only depend on their inputs - not on their history.
  • e.g. typospread, +
  • a module is stateless if it only uses stateless nodes
  • a plugin is stateless when no fields are required to store data for future frames

stateful

  • = nodes that handle state inside.
  • nodes that are not stateless are stateful
  • combine stateless nodes with framedelay nodes to make a nice easy-to-use module.

@ another example

i attached a small example that i extracted from that other zip over here:vvvv-as-a-language

open Buffer (Spreads) as an example for

  • how to put all logic in a stateless node (Buffer (Spreads Manual))
  • and how to build a stateful node by wrapping the stateless node and combining it with a state (by using a feedback)

edit: sorry. take care: spread grows endlessly…

more theory also here: node08.workshop.framebasedanimations


so in general i would like to encourage coders or patchers of modular nodes to keep one fact in mind: states are troublesome in vvvv. more on that here: vvvv-as-a-language

if possible try to build a module or plugin as a purely functional node where the state needs to be fed back into the node. don’t let the node remember things when avoidable. you then always can do the feedback in a module.

you even can do more fancy stuff with the state. as in dottores example you could build up a hierarchy, where you use a predator, add the velocity to the old position, then use this position to check for obstacles and again add up that velocity, and feed back that position. this way you could be sure that the obstacles have a higher priority and the velocities don’t just mix up independantly. you might want that.

i am not so sure about the velocity/position discussion: if you would use a Position In and a Position Out you also could get the velocity by Position Out - Position In. but when in doubt i would just suggest that such anode should just output both position and velocity, so that the user can grab what is more handy. (hmmmm… for outputting an additional Acceleration Out you might need to additionally input the former velocity…)

so let’s sum it up:

  • explicit user state handling is very good but hard to patch. so when providing lowlevel nodes that only work within feedback systems you need to provide modules to make users happy.
  • modularity: yes! (the hard part: but you need to think of clean node interface for several nodes)
  • spreadability: yes! (the hard part: you might need to add binsize and vectorsize pins)

hope that makes sense?!

Buffer (Spreads).zip (3.0 kB)

Hi all,

maybe could be considered crazy and/or not in the vvvv philosophy but, since performance is important, and I experienced that “porting” a module to a dynamic plugin ( or to a shader ) improves perfomance, my question is:

=============================================================
could it be possibile ( maybe it is yet ) to “code” a patch ?

I mean something like this pseudo code,

node1 = new VVVV.Node(“Foo”);
node2 = new VVVV.Node(“Bar”);

in = node2.getPin(“Input”);
out = node1.getPin(“Output”);

link = new VVVV.Link(in,out);

So it would be possible to reuse vvvv nodes inside dynamic plugins and port modules or patches into nodes. Then there should be some exporter from node to patch, with some LayoutManager to “indent” the patch.

@fibo i think it’s not the way to go, because it really difficult to use. But this API can be used for making modules not editable - like “bake” mode in Grasshopper. So we can press “bake” on any module and it will become compiled plugin.

you can already code patches somehow. think of the setpatch node. you input some text that describes the patch you want to create. it is just xml not c#. but with that you can build up a patch.

if you now could do the same with c# you wouldn’t gain a performance improvement, since again it would be just a patch that you are creating.


however we could try to write plugins in a way that not only the node itself is of interest, but also some other public methods or classes.

that way other nodes could just use the public helper classes/functions that make up the main part of another node.

think of a subdivision like this:

  • (1) static public functions doing the purely functional stuff
  • (2) a public class that represents more or less a slice of a node, doing the core work and handling its state (optional)
  • (3) a public class that represents the node
    ** deals with (1) (and if states are needed (2))
    ** wraps up the core and adds pin and spread handling
    ** (1) and (2) could be embedded in (3)

you now could call functions (1) or create objects (2) from within another plugin.

a good example for (1) would be a perlin() function
a good example for (2) would be a toggle object that has a
bool state;
and a
bool evaluate(bool input);
both would not care about spreads, since you typically want the freedom to work with loops in c#…

note that this would only work for plugins to come, not with native vvvv nodes.

@gregsn:
ciao! i’m happy that you like what’s on this post… means we are not on the wrong track ;)

i quoted your post and replied in this thread:
forum/vvvv-particles-library

Interestingly using the ((A+B)A)+2-(B2) example first mentionned above i decided to make quick benches test with decently large spread (100k for A, 50k for B) and a few different techniques, results as follow:

  • Standard vvvv nodes: 20ms
  • Expr: 19ms (slower as doing pinischanged, would be faster otherwise)
  • Advanced Expr: 2.6ms
  • Simple Dynamic plugin: 4.2ms
  • Some threaded nodes: 2.2ms

Increasing A to 1 million (b still to 50k) i get:

  • Standard vvvv nodes: 200ms
  • Expr: 202ms
  • Advanced Expr: 27ms
  • Simple Dynamic plugin: 42ms
  • Some threaded nodes: 13ms

@gregsn very interesting, i need to write some test plugins, for better understanding of idea.
@vux nice test. As i see, we need to implement threads in our future plugins. Can you provide some examples of best techniques?

(
Very interesting post, not boring at all !
For people like me, who learn vvvv absolutely alone and can decently not post in the forum for each problem or question, it is vvvvery precious to see how other users (and specially experimented ones) currently patch !!
Thanks !
)

@alg: threading does help in some cases (eg: high spread count), but for smaller data size non threaded will be faster (by the time you create your threads you would have finished your operation), so having the option to enable threading (as toggle) is a must.

For simple operations using the old IValueFastIn + Pointer instead of ISpread will improve performance too (as you save lot of memory copies, and you can do simple trick to save mods operators).