Data-Oriented Visual Scripting -- The Structure of a Language

Data-Oriented Visual Script – DESIGN (as of drop 10)

So, after drop 6’s stackable purely “data-oriented” awesomeness to the somewhat more recent drop 8’s insanity, I nearly gave up on Visual Scripting and wrote my own solution. However, I have decided to put a little more faith in Unity and see what I can do to use the latest drop (drop 10) to salvage the UX in terms of using it (at least somewhat) for true “Data-Oriented design” – which was quite hard (but not as hard as drop 8).

So in my neverending attempt to evolve Unity’s UX, I came up with the following image to mockup what I think could be a workable design:

So the structure of a “language” – as I mentioned above – should be legible in general.

As you can probably tell, the concepts of a “Subject”, “Verb”, and “Main Idea” are still present from the UE4 example.

The difference is, unlike UE4, Unity is much friendlier with a “stackable” / “vertical” approach --thanks to its “data portals”.
That being said, there are two issues with this:
First, I am hoping there is no performance hit due to heavy use of portals.
Second, I must still (unfortunately) make heavy use of a “portals” concept (like in UE4). This is a problem since portals can link to and from anywhere – yet are still clearly dependent on other scripts/data imports.

Are ‘portals’ bad for workflow?

In short – yes.

But hear me out, please.

Portals, as they are used above, are useful for readability. However, they also suggest I cannot have (or keep track of) centralized “systems” that my scripts can remain independent of, meaning I would need to make a separate “foreach” “system” for every single script I want to apply data changes to more than one entity of mostly the same type (which is almost always) – with the caveat that I have to introduce additional logic to sort out the entities I don’t want the script to apply to (including when and where that application doesn’t need to apply) when, in ECS’s data-oriented design, all I would have to do is query for the component tags I do want (and remove tags from entities when I don’t want them considered in the data transform application).
This context-dependent “additional logic” reduces the overall importance of the ECS approach while also dismissing ECS’s strengths – i.e. applying specific changes to all interested parties at once by letting interested objects “subscribe/unsubscribe” to a system by “tagging” (or “untagging”) it with a component (or a certain series of components). For example, ideally, a central “damage” system should be able to query “all bad guys with the [aerial] and [spiky-hat] component tags” to damage Mario (the entity tagged as [player1]) when he’s in the air and is currently colliding with them from above (after trying to jump on this style of enemy).

The problem with portals is that you never know what data you’re getting – or where it’s coming from (in the case of a global “portal” system).
In the case of a local portal system (i.e. local to the current visual script), you lose the ability to delegate tasks to more (centralized) systems (such as the “damage” system in that Mario example) to handle extremely specialized cases (without additional logic) by simply adding/removing “tag” components. This “loss” of delegation happens because you are always dealing with data locally and in a (too explicit) manner.

Portals enable micromanagement, but often (in practice) just create spaghetti-networks that quickly become too unwieldy. Instead, of saying “portals are bad” – I’d rather say “portals should be left to local (per Visual Script) data transformation, while “tag components” should be used to delegate to global systems (which have their own local ‘portal’ components.)” instead. Portals are bad for global dataflowespecially when there are no other ways to efficiently delegate the data (i.e. to a more ‘global’ system – which is easy and possible to do with the ‘series of tagged components’ approach described above in the Mario example).

Readability and UX in Unity’s Visual Scripts

As you might have guessed – like UE4’s blueprints – even with “portals” and “tags” as their components, readability in Unity’s vanilla VS solution is still an issue.

For decent UX, we need some equivalent of a subject/verb/main-idea in the scripting workspace. To show the contrast in readability of simple layout versus layout plus the additional visual aids, see the two orange lines above to visually separate the subject/verb/main-idea, allowing one to quickly ascertain the main idea of each “block” of vertical scripting “stacked” on top of one another.

The brain processes “chunks” instantly – and being able to glance down the “subject” column to find the one you are looking for, helps immensely to find your place in your script. Then you can hop into the “verb” column to see what’s explicitly going on in that part of your script (and then, in the final column, what exact data that outputs).

Handy, right?

If Unity made explicit (resizable) regions / columns of a certain pixel size and just automated the “lines” (in my case, the orange ones) to “fit” or trace downward (around my nodes) that were dropped within the correct column / region for their respective part of the sentence, I can suddenly have a visual priority to processing things. This visual priority (which isn’t present in code editors), works amazingly well for “grouping” things, where the visual brain can instantly process them (without wasting brain-cells to “compute” the node group you’re looking for). This is a HUGE win for artists/designers.

Artists Process Things Differently

I might be particularly annoyed by this because, as I mastered pixel animation, I had to deal with clusters of colors moving around, and my job was to make sure these super low-res groups of colors were instantly readable at super-low frame-counts (while being super-low-res). I think that is part of the appeal of classic pixel art though – your brain doesn’t have to work so hard to process it (at least the stuff made for legit hardware limitations).
Which is why “simpler is better” for anyone not trying to “savor” all the individual details of a UI at any given moment. Most of the time, you only care about whether the result is instantly gratifying (or not) – which is exactly the same thing you care about whether you are a user – OR whether you are someone who consumes (or creates) pixel art.

I came across a nice illustration of this principle – but in a different form:

This guy (and the kid) didn’t say it – but I will (since it’s my own personal UX slogan):
When you’re dealing with UX – “Remember the human.”

Visual Hierarchy – UX and SCIENCE!!!

The most pressing improvements to the Visual Script UX is that it really needs to return to its “Data-Oriented” design roots (i.e. systems for processing all entities at once – via queries and tags, as described in the Mario “damage” system example). This is because data itself needs a hierarchical presentation as well as hierarchical processing.
However, even when doing so, the below example for how to process values/methods/entities in a data-oriented design should still (visually and logically) apply.

The example below shows two “paragraphs” back-to-back, each “stacked” node group being its own “paragraph” comprised of node “sentences” (i.e. rows of subject/verb/main-ideas) for each sentence block “stacked” on top of the others.

This is a VERY rough mockup showing the concepts of a decent ‘visual hierarchy’.

Although the orange is garish, when it’s used alongside the yellow (slightly brighter) and darker (gray and black) tones, it forms a clear “Visual Hierarchy”. You can think of a “Visual Hierarchy” as “layers” of a grayscale heightmap (values from 0-1), which helps the brain to instantly “group” and process information (based on relative contrast). The higher the black/white contrast, the more “visual separation” of the ‘layers’. Remember, most people cannot hold (and then process) more than 3-4 (separate) pieces of information in the brain at a time. This is why a “Visual Hierarchy” needs to exist.
But because of this very same reason, there also cannot be tons and tons of visual separation (i.e. groups of groups) because the visual brain operates in that 0-1 space I was talking about (again, much like a heightmap, with limited room for extraneous data).
So with contrast (be it from color, luminosity, shape, or negative-space separation), the “visual grouping” produced should not exceed the number of bits and pieces of data (i.e. 3-4) that the average brain can hold and process at any one time. Otherwise the dreaded “boredom” factor sets in, ruining the elusive “Flow” (and not just “visual flow” either!), making your brain “give up” because it is now “working too hard” to try to process the provided information – leading to “visual fatigue” and can probably be considered a form of “boredom” (in the same way that someone spitting out tons and tons of extremely dry facts can very quickly become ‘boring’ to most people).
That being said, over time (and with familiarity) this visual load will seem to “lessen” in a way (since your eyes will eventually get used to placement/location of things), but this “lessened” load will be because you’re relying more on “visual memory” now than “visual processing” to “see” the things on that terrible screen / UI in front of you.
Think of it as processing every single letter into a word, one at a time, versus recalling the finished result of an already processed word - in one go. This is what I mean when I say the brain is “grouping” stuff. – It is trying to simplify it.
Into something meaningful.

This “visual memory” is the ONLY WAY anyone can ever truly use something like Maya (without going nuts) – It is also why so many people are so terrified of Houdini – i.e. “ALL THE STUFF!!! – What does it MEAN???”

This is where a nice “Visual Hierarchy” can save the day.

“Visual Hierarchies” exist in nature (objects, ground, sky, horizon) – it needs to exist in UX too.

Since the data is the most important element you are working with, DATA needs to be central to the UX as well as the workflow.
This means that whenever DATA changes or is modified, it needs to be visually-clear and well-represented in the “Visual Hierarchy” that you are working with (and changing) DATA.
Visual-flow of data changes and representation needs to be heavily considered in the hierarchy – It cannot be too distracting either. (Again – those oranges/yellows would make your eyeballs bleed if they were being used seriously – I only use them as a point of illustration to show visual hierarchy clearly. The gray I used for “highlighting” the DATA input/output nodes would probably be a bit nicer to work with.)

Script Flow – in a Visual Hierarchy

The flow of the above script emphasizes data with the fact that only the stored input/output is featured prominently (and therefore “highlighted” with that thick gray outline, which could possibly be a custom-color tag, letting the author right-click it and select a “tag” to feature that particular local data node prominently in this script, which is very useful in complex scripts doing fancy stuff with only one main set of localized data).
The processes (and processing) of the dataflow are considered secondary.
These should also be considered globalized dataflow.

“Dataflow” should be localized to Visual Scripts (as it is now), with a globalized “link” through a “tag component” styled system. This would ensure that external methods/functions would not be depended on generally.
Methods such as OnUpdate and OnStart, or “methods/functions” like the GetInputManagerAxis or LogMessage nodes that “transform” data should do the transformation independently of the Visual Script that is currently executing now. Since these “transform” the data, they should be featured (visually) by location (i.e. being located in the center of the script in which is doing the transformation), where they actually transform the “imported” data from the portals (located in the “subject” columns). Then, when the data requires further processing, it is “exported” to a portal via placement in the “main-idea” column.

It might even be neat to drag a function node to this column to automatically generate its “output” node (and then reposition the function/method node back in the “verb” column.

Then, when data must be “handed-off” to another system, the “verb” column would have a node to “attach” a new “tag” component (or series of tag components – which are ECS component types which do not yet currently exist), letting the globalized SYSTEM handle it based on the tags you’ve chosen to apply to it. The globalized SYSTEM, however, is just another Visual Script that deals in “tagged” components to alter data in a specific way, rather than resorting to explicit ifs, ands, ors, or elses – which quickly get unwieldy!!
These can, technically, exist in any Visual Script, as all Visual Scripts should really be considered the “Systems” in ECS, while “Gameobjects” should be considered the DATA “Components”. However “tagged” components are just a kind of low-level query data that should not have DATA associated with them. They are, after all, just a query string that allows you to sort and easily change the behavior of gameobjects instantly. Sadly, “tagged” components (with this use-case) do not currently exist – only “data” components do.

Subtlety is possible in Visual Hierarchies

The “Pages” concept (on the far bottom-right) actually allows your individual scripts to not become spaghetti-nighmares, when you’re only dealing with a small number of data transforms and allows you to have a nice “visual flow” (without losing your place) while letting you quickly label your “pages” of data so you can find where you are. Just click on the + to add a new script page and toggle between them. Right-click to delete a page. You can also name the title of the page there (i.e. importing). You can have page 1 be the “import” page, and page 2 be the actual “script” page that references the imported data if you like. But I honestly think this defeats the purpose of writing “sentences” that have an intuitive ‘flow’ to them (and you’re getting back in that ‘programmer’ mindset of anything goes as long as it ‘works’ – even if you’re promoting bad programming practices).
At times though, if you simply want a visual separation on the same page (akin to paragraphs on a standard “page” in a book, that don’t diverge too heavily on subject-matter), you could insert visual “spacing” of the “main-idea” of that particular “paragraph” with a “separator” line.

Enter the Yellow line (and its physical spacing).

This line is meant to be more prominent than the orange ones, and lends itself to letting you know, visually, where your overall main idea (the current ‘paragraph’ or subject of focus) ends.
This line is combined with physical spacing of the nodes (preferably automatically) on the vertical axis, allowing an extra-nice visual separation (leading to additional contrast) in a script’s visual hierarchy (and adding a rhythm to the flow – which is absent in most actual “code”).

When you feel like your script has gone on too far vertically, simply make a new “page” and continue “writing” your script where you left off on the previous “page” – as if you were writing some actual thoughts in a book.

Imagine that – programming and thinking. Working hand in hand.

Eerie, isn’t it?

Hopefully Unity sees this and implements some of these ideas!

– I cannot fathom scripting without them!!

2 Likes