Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

- Thanks! - Re: "function with parameters" you mean so the configuration is exposed on the node itself? It's definitely something I want to consider as an UX improvement. At first, I was very puristic about having all configurations acceptable as dynamic inputs, to ensure Flyde is robust and flexible, but that led to things like the HTTP node having 5 different pins which made it even worse. Now it's a hybrid model - as an author of a node you can choose how to expose it, and many nodes in the Stdlib expose configuration in both ways - Interesting use-case! Flyde's last incarnation was an attempt to offer this to other SaaS products (before realizing it must start OS) to allow their users to do "Visual scripting" (like https://luna-park.app/, a project I've stumbled upon) You can check the source code of the playground and try embedding Flyde, should work!


Hey, author of https://luna-park.app here! (I was wondering where the spike in visits came from ^^'... Thanks a lot for mentioning me!).

Luna Park was indeed a npm package that you could integrate to allow users to build their own logic using visual scripting. In the end, I pivoted, and Luna Park is now a visual scripting wrapper around the Vue.js framework, allowing people to build modern webapps without code. (I also made https://roller-coaster.app to create endpoints using the visual scripting system of Luna Park)

In any case, that's super cool to see people building awesome tools like yours in the visual programming space :) ! I love how Flyde show you what node is running, and the way it executes logic is really interesting!


Haha glad you found this comment! Love your dedication to the amusement park theme, it's rare to see web products take such a "game design" approach.


Yeah, that's part of what I'm talking about, for sure. Being able to, say, click a little expand icon to see other pins that aren't usually necessary, is great for discoverability. I'm not a big fan of library maintainers deciding that I can only use certain inputs for an underlying function that I know has more functionality. Node authors should, of course, be able to guide, but I don't appreciate them having the ability to control.

More than that, though, it's about the difference between 'data references' and 'execution flow'. It's something that Unreal makes very, VERY obvious. Color coding data types, emphasizing execution flow lines, etc. I can't recommend using it as a guide, enough. Whatever problem I've come up with as 'complicated' for visual scripting, they've got an elegant solution for.

Even stuff like being able to 'break' nodes into other nodes, or pins into other pins. So a "Point" node might be useful for sending into a function expecting a Point data type, but you might also want to send just that Point's x or y value to something else. In that scenario, you might 'break' the exit pins into a Point reference, an x reference, and a y reference. It would be cumbersome and unruly to always have that available. But the UX to make it available is straightforward and satisfying.

And then, all of that aside, I just prefer the visual look of pins integrated into the nodes. The extra lines you get from drawing between the pin and the node is messy and since you can't move them independently, they don't really add anything. Just a lot of extra buffer to prevent a 'crowded' feeling. But at least that's not something unique to Unreal. I don't think I've ever seen a visual scripting system that used pins as separate elements. So maybe it's just saturation bias. But I do like what I like!

Anyway, I'll definitely mess around with it and see if it can help with its embedded version. To be completely honest, I think there's too much friction, overall. I would need something to render as plain javascript, rather than a JSON structure or minified JS (or typescript), so there's a translation there. And then to get it graphically how I want it would be complicated due to all the domain-knowledge required for integrating with your app's underlying library (looks like next js? Not sure, but it's not something I want to work with). Not to be too pessimistic or anything. Most libraries work toward providing a complete solution, not towards providing a composable, compsitable, modular set of utilities, which is what I need. I don't hold any contempt for providing what you've provided because it's a hell of a thing and perfect for a lot of use cases, I'm sure! I'm just very pragmatic about my own use-cases, and my development quirks (like not using libraries that obfuscate functionality [next, react, svelte, etc]).


Insightful – commenting to keep a reference as I spent the last four years engineering around this very aspect.

I'm trying to wrap my head around the difference between execution models. On one hand we have real-time node systems like Unreal Blueprint, Modo or DaVinci Resolve, which depend heavily on state nodes, i.e. nodes whose sole purpose is to hold and serve information (a mesh, a transformation, an RGB matrix). These nodes act as complementary inputs to nodes in the main execution flow.

On the other hand we have Node Red and the likes, whose nodes rely on a single input. At first glance this approch might make sense from a UX perspective – simply connect your components and deploy. However with time I've come to see this as a major limitation to the extent that you're often better off writing code. After building a number of flows you start to notice certain patterns... Since nodes are uncapable of fetching data from other nodes ("state nodes" above), it's up to you as a developer to serve the node with the exact data structure it needs. The GUI gives you no hint as to the structure itself, so you're left reading the node's documentation: {payload, action, topic, subject} – different for every node.

At the core, this approach is the FBP version of polish notation in the sense that you first have to fetch all the operands before sending them to the operation. So what you're left with is a flow where every core node is surrounded by data shuffling nodes: "put this into 'action', put that into 'body', take 'payload' and store it away because the next node will overwrite it". As an effect of this "serial execution model", flows often stretch wide from the left to the right where two thirds of nodes are pure data transformations.

Somewhere around here the USP of FBP gets literally lost in the flow – the USP being to offload working memory. During building/debugging/revisiting flows, I often know right away what piece is broken. Nevertheless I spend a lot of time double-clicking on function, change, and switch nodes just to find that piece of code. The irony of it all is that I wanted to use FBP to _visualise_ logic. Instead the same paradigm hides it away.

So what you've accomplished is transforming code that goes from up to down into boxes that go left to right.

The thinking behind it all is that Node Red shouldn't make assumptions about the incoming data, however someone has to make those assumptions, and that someone is you, the developer.

It would be trivial to create a node that takes an arbitrary input (a sample message), analyses the message structure and exposes the appropriate output pins, however as long as Node Red persists with single input ports and the "message-based execution" it entails, it will take tolls on working memory and lag behind the Unreal model which I too consider state of the art.


Yeah, this is a really tricky space to delve into because the people who are most familiar with it are working on mathematical models and have very strong opinions about the "kind" of graph you're making, or what you're actually doing with the underlying data. Which is all definitely important for a node library maker to know, but the whole purpose of the library is that an implementing dev shouldn't have to know any of that stuff. So you really have to dig through a lot of irrelevant stuff about graph theory and whatnot to get to any relevant programming knowledge on the topic.

What's galling to me is that nodes map 1-1 to function calls. I can't even think of a scenario where a program that can be written as functions and objects couldn't be represented as a node graph. I can certainly shudder at the horrific types of graphs most programs would make, but they can all be mapped out. And, on the flip side, every single program I've written in visual scripting could easily be written as functions and objects. So, with that in mind, it's frustrating to go looking for information about node graphs and getting a bunch of muck about why they're 'not good', and why they don't handle certain things well, and why they aren't suited for x or y, when - in my head - I'm literally just asking for a well-formed API, and I'm getting a bunch of pushback about how APIs aren't really a good way to program. -_-

But because it's so hard to get good comparative information on visual scripting, I've also wrestled with what makes for good abstractions vs what is too broad. And that's what I think the Node Red stuff is: just too broad. Abstracting away everything breaks the value of the abstraction. So it's always about finding a balance, which is why I appreciate Epic's maintenance of Blueprints. A good API abstracts concepts you don't need to understand behind concepts you already understand. "GetDistance()" is a great abstraction because I don't care about the vector math underneath. But "Login()" is a terrible abstraction because a library shouldn't have the intimate details of my login process (meaning that it should be abstracted into more modular parts that I can more easily inject my business logic/keys into). So a node, or a library of nodes, or a node library system - they're all only as good as their abstractions. And Node Red is just way too abstracted to be "good". And, of course, the irony there is that if it were only a little more flexible, it could even be abstracted, itself, into something more use-able! If you could write a node that DID accept two inputs, you could abstract away all of the setting and swapping and trading. But since even that node could only ever be kick started by a single node, you would have to come up with some kind of hacky scheme to make any kind of utility actually function. So it's the one type of abstraction that they don't allow (their node model) which I find to be fundamental to successful visual scripting languages.

Honestly, though, I think there are some fundamental designs that visual scripting languages just need to implement, but I have a very hard time describing those designs with rigor. I would naively say that they need nodes, edges, a variable deck, a node discovery utility, and a good variable property manager. But that's just because that's what I'm used to. I think once someone really serious sits down to formalize these things, we'll have a much richer environment. I just hope they do it soon!




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: