<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0">
<channel>
<title>Coder Legion - Recent posts tagged visual-programming</title>
<link>https://coderlegion.com/tag/visual-programming</link>
<description>Powered by Question2Answer</description>
<item>
<title>Flow of Autonomous Brain and its Engine</title>
<link>https://coderlegion.com/19138/flow-of-autonomous-brain-and-its-engine</link>
<description>&lt;p&gt;On the last post, I mentioned usuage of multiple github models, but made some more modifications, and now 2 new providers are also added to the boardroom. &lt;/p&gt;
&lt;p&gt;STAGE 1  ARCHITECT CONFERENCE&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;     Architect A (Mixtral/Groq) + Architect B (Llama/Groq) propose plans in parallel
     Judge (GPT-4o) synthesises or proposes a more unpredictable plan
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;STAGE 2  IMPLEMENT&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;     Engineer (GPT-4o) writes each file with full sibling context
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;STAGE 3  QUALITY LOOP (up to 8 rounds)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;     Reviewer A (Mixtral/Groq) + Reviewer B (Gemini) in parallel
     Fixer applies merged feedback + Playwright interaction test
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;STAGE 4  QA REVIEW&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;     Playwright clicks every button, tests every slider
     QA Tester (GPT-4o) issues verdict: shippable / partially_usable / non_functional
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;STAGE 5  PUBLISH&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;     New public GitHub repo created via API
     GitHub Pages enabled -&amp;gt; live URL in under 60 minutes from cold start
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;STAGE 6  SELF-IMPROVE&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;     CTO (Gemini) reads last 30 failure logs, proposes a surgical source patch
     Validates Python syntax, commits - next build runs improved code
&lt;/code&gt;&lt;/pre&gt;
</description>
<category>Articles</category>
<guid isPermaLink="true">https://coderlegion.com/19138/flow-of-autonomous-brain-and-its-engine</guid>
<pubDate>Thu, 28 May 2026 07:23:50 +0000</pubDate>
</item>
<item>
<title>DevLog 20260225: Divooka Visual Programming - Direct Value Setting of Compound Inputs</title>
<link>https://coderlegion.com/12185/devlog-20260225-divooka-visual-programming-direct-value-setting-of-compound-inputs</link>
<description>&lt;p&gt;Finally, it arrived! Well, not exactly here yet, but getting closer.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9uefmdr5tir0qjdcfyax.png&quot; alt=&quot;Screenshot of Visual Programming in Divooka - Value Assignment of Compound Inputs&quot;&gt;&lt;/p&gt;
&lt;h3 id=&quot;overview&quot;&gt;Overview&lt;/h3&gt;
&lt;p&gt;Divooka intends to make visual programming simple and accessible - the accessible part is achieved both through wide availability and the general-purpose nature of the programming system, but the &lt;em&gt;simple&lt;/em&gt; part is what we spend lots of effort thinking hard trying to improve.&lt;/p&gt;
&lt;p&gt;In the past, dealing with complex configuration takes the form of either &lt;em&gt;&quot;explosion&quot;&lt;/em&gt; of arguments or dedicated &lt;code&gt;Make XXX&lt;/code&gt; construction functions:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mf6epcnl90nzwn4v3sni.png&quot; alt=&quot;An Example of A Node with Lots of Inputs&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://dev-to-uploads.s3.amazonaws.com/uploads/articles/haamwdqh83lph8wphcw4.png&quot; alt=&quot;An Example of A Node Taking a Struct, Which Needs to be Created from a Node with Lots of Inputs&quot;&gt;&lt;/p&gt;
&lt;p&gt;The problem arises due to direct exposure of all input arguments in visual programming. Both approach makes the canvas look busy, with the former a common approach in existing systems - using a struct sounds good on paper but still requires a complex looking construction node. This is a common problem in visual programming systems, below shows how it's done in Blender and ComfyUI.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://dev-to-uploads.s3.amazonaws.com/uploads/articles/p74kj1nn0v5clwya2bp4.png&quot; alt=&quot;A Node with Many Inputs in ComfyUI&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5jkcps43hasucbgc4fjr.png&quot; alt=&quot;A Node with Many Inputs in Blender&quot;&gt;&lt;/p&gt;
&lt;p&gt;You do get used to it after a while, but a busy looking canvas remains a busy-looking canvas. In Blender, you can sort of &quot;collapse&quot; a node:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://dev-to-uploads.s3.amazonaws.com/uploads/articles/51ssein4u54ak1b4x2dp.png&quot; alt=&quot;Collapse Nodes in Blender&quot;&gt;&lt;/p&gt;
&lt;p&gt;As Blender is constantly improving, we can also now collapse property groups as shown in the earlier screenshot.&lt;/p&gt;
&lt;p&gt;As a syntax purist and (unfortunately) very conscious about my working space, my eyes can't tolerate messiness. I kind of like how Houdini approaches this.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6rcfmxoty5i6dt915ue9.png&quot; alt=&quot;Nodes in Houdini Are Very Simple and Clean&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://dev-to-uploads.s3.amazonaws.com/uploads/articles/25jwxr7qrhzxak2u6ylm.png&quot; alt=&quot;Houdini Makes Use of Property Panels&quot;&gt;&lt;/p&gt;
&lt;p&gt;Essentially they offload all the complexity to the properties panel - this has the huge benefit of making everything look very clean. But the downside is Houdini rely heavily on scripting expressions (like Excel).&lt;/p&gt;
&lt;p&gt;TerraGen and World Machine mixes the approach:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8j6701vpaacarx9406jj.png&quot; alt=&quot;A Node Graph in World Machine&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://dev-to-uploads.s3.amazonaws.com/uploads/articles/fabvq61w0sqm3oiybyxf.png&quot; alt=&quot;A Node Graph in TerraGen&quot;&gt;&lt;/p&gt;
&lt;p&gt;In both cases, connections represent flow of terrain data only and additional configurations are offloaded to property panels. In TerraGen especially, this allows those properties to be animated. The downside, once again, is &lt;strong&gt;whatever is offloaded to property panels are no longer programmable using nodes&lt;/strong&gt;.&lt;/p&gt;
&lt;h3 id=&quot;our-approach&quot;&gt;Our Approach&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9uefmdr5tir0qjdcfyax.png&quot; alt=&quot;Compound Input Editing Popup in Divooka&quot;&gt;&lt;/p&gt;
&lt;p&gt;Our proposed solution for Divooka looks like this: fundamentally all properties remain as node inputs, but compound values (especially value types) should just allow &quot;editing in place&quot; through a property panel. If more complex programming is needed, one can easily fall back to &lt;code&gt;Make XXX&lt;/code&gt; nodes again.&lt;/p&gt;
&lt;h3 id=&quot;future-work&quot;&gt;Future Work&lt;/h3&gt;
&lt;p&gt;There is still remaining work on type check, hierarchical compound types, arrays, and serialization, and also node rendering.&lt;/p&gt;
&lt;h3 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h3&gt;
&lt;p&gt;As usual with all the exciting language features of Divooka we intend to introduce, there are lots of details to take care of here.&lt;/p&gt;
</description>
<category>Articles</category>
<guid isPermaLink="true">https://coderlegion.com/12185/devlog-20260225-divooka-visual-programming-direct-value-setting-of-compound-inputs</guid>
<pubDate>Wed, 25 Feb 2026 17:55:52 +0000</pubDate>
</item>
<item>
<title>DevLog 20260224 Divooka - Node-Level Automatic Dispatch (Runtime Execution Behavior)</title>
<link>https://coderlegion.com/12155/devlog-20260224-divooka-node-level-automatic-dispatch-runtime-execution-behavior</link>
<description>&lt;p&gt;&lt;img src=&quot;https://dev-to-uploads.s3.amazonaws.com/uploads/articles/k0nmv1dzv1kuerx8vvr5.png&quot; alt=&quot;Scalar Operation&quot;&gt;&lt;/p&gt;
&lt;h3 id=&quot;overview-1&quot;&gt;Overview&lt;/h3&gt;
&lt;p&gt;Anything useful done with a program eventually involves file I/O and some form of repetition.&lt;/p&gt;
&lt;p&gt;In Divooka, the dataflow context already makes it very easy to &quot;just get a single thing done.&quot; That part feels good. But handling loops? That's where things start to get awkward.&lt;/p&gt;
&lt;p&gt;One challenge lies on the GUI side — especially around lambdas and subgraphs. We do have foundational support (as shown &lt;a rel=&quot;nofollow&quot; href=&quot;https://dev.to/methodox/devlog-20250510-dealing-with-lambda-3ff9&quot;&gt;here&lt;/a&gt; and &lt;a rel=&quot;nofollow&quot; href=&quot;https://dev.to/methodox/progress-share-graph-local-lambda-calculus-4dj2&quot;&gt;here&lt;/a&gt;), but let's be honest: it's not &lt;em&gt;smooth&lt;/em&gt; yet.&lt;/p&gt;
&lt;p&gt;So the question becomes: how do we make repetition feel natural without introducing heavy conceptual overhead?&lt;/p&gt;
&lt;h3 id=&quot;the-plan&quot;&gt;The Plan&lt;/h3&gt;
&lt;p&gt;There are several well-established ways to achieve looping behavior in a functional or visual programming context:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Subgraph context&lt;/strong&gt; - Used in tools like Blender, vvvv, and Houdini. A specialized node group or frame defines loop entry and exit boundaries.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Lambda callbacks&lt;/strong&gt; - Evaluation is handled via callback-style execution.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Expressive recursion&lt;/strong&gt; - As seen in text-based functional languages, requiring explicit termination conditions to avoid stack overflow.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;All of these approaches are powerful and necessary in certain contexts. But they also introduce additional constructs into the language model. For advanced workflows, that's fine. For simple operations, it can feel unnecessarily complex.&lt;/p&gt;
&lt;p&gt;I wanted something lighter.&lt;/p&gt;
&lt;h3 id=&quot;array-coercion&quot;&gt;Array Coercion&lt;/h3&gt;
&lt;p&gt;Divooka already supports &lt;strong&gt;Array Coercion&lt;/strong&gt; — a scalar value can be passed into an input expecting a collection.&lt;/p&gt;
&lt;p&gt;This avoids the need to manually &quot;wrap&quot; a scalar into an array just to satisfy a function signature - I still remember the pain of handling arrays in Unreal Blueprint.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://dev-to-uploads.s3.amazonaws.com/uploads/articles/y2m2p8hs7ellxbfzgj5m.png&quot; alt=&quot;Treat Scalar as Array&quot;&gt;&lt;/p&gt;
&lt;p&gt;Scalar-to-array coercion keeps graphs clean and avoids clustering.&lt;/p&gt;
&lt;p&gt;To take this to the next level, I've been giving it much thought on how the reverse might work: if we can coerce scalars into arrays — what if we also let nodes automatically dispatch when arrays are passed in?&lt;/p&gt;
&lt;h3 id=&quot;automatic-dispatch-node-level-&quot;&gt;Automatic Dispatch (Node-Level)&lt;/h3&gt;
&lt;p&gt;The core design question was:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Should an array input implicitly turn the &lt;em&gt;entire downstream chain&lt;/em&gt; into a loop?&lt;/li&gt;
&lt;li&gt;Or should the dispatch behavior stay localized to the node itself?&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Eventually it seemed localizing things to the node made far more sense. &lt;/p&gt;
&lt;p&gt;For example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;string String.Replace(string, string, string)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If any input is provided as an array instead of a scalar, the node automatically promotes itself to:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;string[] String.Replace(string[], string[], string[])
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The node executes element-wise.&lt;/p&gt;
&lt;p&gt;Now, I can rename a folder of files with roughly three nodes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Enumerate files&lt;/li&gt;
&lt;li&gt;Regex replace&lt;/li&gt;
&lt;li&gt;Rename file&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;No explicit loop node. No subgraph. No lambdas.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7bvz2dbw56ctqp2kju5n.png&quot; alt=&quot;Dispatch Setup&quot;&gt;&lt;/p&gt;
&lt;p&gt;In this example, &lt;code&gt;Duplicate as Array&lt;/code&gt; returns a strongly typed &lt;code&gt;string[]&lt;/code&gt;, enabled by &lt;a rel=&quot;nofollow&quot; href=&quot;https://dev.to/methodox/devlog-20250710-generics-in-divooka-49e6&quot;&gt;generics support&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;One important rule: All array inputs must align in size with the source array. The dispatch is index-based and deterministic.&lt;/p&gt;
&lt;h3 id=&quot;full-example&quot;&gt;Full Example&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tsypgdt3xrj6g4phkvij.png&quot; alt=&quot;Full Example&quot;&gt;&lt;/p&gt;
&lt;p&gt;What used to require explicit iteration logic now becomes implicit behavior at the node boundary. The graph remains readable. The mental model stays simple.&lt;/p&gt;
&lt;h3 id=&quot;conclusion-1&quot;&gt;Conclusion&lt;/h3&gt;
&lt;p&gt;This is still early work. Integration with the rest of Divooka's features is ongoing, and edge cases are being worked through.&lt;/p&gt;
&lt;p&gt;So far so good.&lt;/p&gt;
</description>
<category>Articles</category>
<guid isPermaLink="true">https://coderlegion.com/12155/devlog-20260224-divooka-node-level-automatic-dispatch-runtime-execution-behavior</guid>
<pubDate>Tue, 24 Feb 2026 22:22:17 +0000</pubDate>
</item>
<item>
<title>DevLog 20250507 Bringing Smart Suggestions and Smarter Search to Divooka’s Visual Coding</title>
<link>https://coderlegion.com/3063/devlog-20250507-bringing-smart-suggestions-and-smarter-search-to-divookas-visual-coding</link>
<description>&lt;h3 id=&quot;learning-from-unreal-engine-blueprints&quot;&gt;Learning from Unreal Engine Blueprints&lt;/h3&gt;
&lt;p&gt;I’ve always admired Unreal Engine’s Blueprints - particularly its subtle yet powerful &lt;strong&gt;connection suggestion feature&lt;/strong&gt;. When you drag a wire out from a pin, the system intuitively suggests compatible nodes based on the pin’s data type.&lt;/p&gt;
&lt;p&gt;This kind of context-awareness accelerates creation and keeps workflow fluid by making things &lt;em&gt;just work&lt;/em&gt; - no guesswork needed.&lt;/p&gt;
&lt;h3 id=&quot;the-challenge-missing-type-labels-in-c-instance-methods&quot;&gt;The Challenge: Missing Type Labels in C# Instance Methods&lt;/h3&gt;
&lt;p&gt;Divooka, built atop C#, posed a snag: &lt;strong&gt;instance methods don’t include the object’s type in their signature&lt;/strong&gt;. So if a method like &lt;code&gt;Rotate()&lt;/code&gt; belongs to a &lt;code&gt;Transform&lt;/code&gt; object, the type isn’t explicitly declared in the method signature - making automatic suggestion tricky.&lt;/p&gt;
&lt;p&gt;To match Unreal’s intuitiveness, I needed a way to tell Divooka - not just &quot;Rotate()&quot;, but &lt;em&gt;Rotate() on Transform&lt;/em&gt;.&lt;/p&gt;
&lt;h3 id=&quot;explicit-type-filter-in-search-syntax&quot;&gt;Explicit Type Filter in Search Syntax&lt;/h3&gt;
&lt;p&gt;The first step is to allow users to filter the toolbox explicitly in their search query.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://dev-to-uploads.s3.amazonaws.com/uploads/articles/r0n5z8by0eapb5k7iy4t.png&quot; alt=&quot;Instance Function without Type Parameter&quot;&gt;&lt;/p&gt;
&lt;p&gt;For example: &lt;code&gt;[Pixel Image] Save&lt;/code&gt; would filter for methods in the &lt;code&gt;Pixel Image&lt;/code&gt; toolbox (category). The symmetry of this syntax remains intuitive even in localized languages like Chinese - because only the type would be translated, not the syntax design itself.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://dev-to-uploads.s3.amazonaws.com/uploads/articles/g1girqglhmc2hx0itcuo.png&quot; alt=&quot;Type Parameter Syntax&quot;&gt;&lt;/p&gt;
&lt;h3 id=&quot;building-the-pipeline-filtering-and-highlighting&quot;&gt;Building the Pipeline: Filtering and Highlighting&lt;/h3&gt;
&lt;p&gt;Next, I leveled up the search experience by crafting a multi-stage pipeline:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Category names&lt;/strong&gt; (like &lt;code&gt;[AI Service]&lt;/code&gt;, &lt;code&gt;[Pixel Image]&lt;/code&gt;) now at the front, so users can scope their search by purpose.&lt;/li&gt;
&lt;li&gt;Then we optionally parse &lt;code&gt;&amp;lt;TypeName&amp;gt;&lt;/code&gt; syntax, which is used to filter input parameters.&lt;/li&gt;
&lt;li&gt;Finally, full-text search for other keywords.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;So a query might look like:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[Pixel Image] &amp;lt;String&amp;gt; Save
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In which case we will search only for functions containing the word &quot;Save&quot; and expects a &lt;code&gt;String&lt;/code&gt; parameter. Visually, I emphasized that first category tag with syntax highlighting to help the eye quickly scan.&lt;/p&gt;
&lt;h3 id=&quot;the-result-it-just-works-mostly-&quot;&gt;The Result: It Just Works (Mostly)&lt;/h3&gt;
&lt;p&gt;Here’s how it currently looks:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kw31ux4qf0ajmc7oneq9.gif&quot; alt=&quot;Working Result&quot;&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Type &lt;code&gt;[Pixel Image] Save&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;The search autocomplete suggests all instance methods named &lt;code&gt;Save...()&lt;/code&gt; defined in &lt;code&gt;Pixel Image&lt;/code&gt; toolbox (mostly operating on the &lt;code&gt;PixelImage&lt;/code&gt; object type) (e.g., &lt;code&gt;PixelImage.Save&lt;/code&gt;, &lt;code&gt;PixelImage.Load&lt;/code&gt;, etc.).&lt;/li&gt;
&lt;li&gt;Everything lights up in palette instantly - &lt;em&gt;users can find what they need fast&lt;/em&gt;.&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&quot;what-s-missing-auto-connecting-suggestions&quot;&gt;What’s Missing: Auto-Connecting Suggestions&lt;/h3&gt;
&lt;p&gt;This solves the &lt;strong&gt;searching&lt;/strong&gt; half of the problem beautifully - but it doesn’t yet auto-connect. In Unreal, dragging from a &lt;code&gt;Vector&lt;/code&gt; pin might instantly suggest &lt;code&gt;Normalize()&lt;/code&gt; - and connect it for you if you click that suggestion.&lt;/p&gt;
&lt;p&gt;Right now, Divooka still requires a manual drag-and-click - our intention was only searching and filtering, not full drag-and-drop automation.&lt;/p&gt;
&lt;h3 id=&quot;next-steps-toward-full-contextual-suggestions&quot;&gt;Next Steps: Toward Full Contextual Suggestions&lt;/h3&gt;
&lt;p&gt;I’m plotting the future:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Pin-aware suggestion&lt;/strong&gt;: When dragging a wire from a pin, immediately filter down to matching methods—and optionally even pre-wire the node when hitting “Enter” or double-clicking.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Type inference&lt;/strong&gt;: Avoid requiring &lt;code&gt;&amp;lt;Type&amp;gt;&lt;/code&gt; if the context is obvious - since the system already knows the pin’s type.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Better localization&lt;/strong&gt;: Make sure category tags and type filters localize cleanly, without mangling grammar in languages like Chinese, Japanese, etc.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Enhanced UX hints&lt;/strong&gt;: Perhaps grey-out non-matching nodes live, or provide quick tooltips (e.g. “only shows methods on Transform”, like Unreal Blueprint's node search interface).&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;summary&quot;&gt;Summary&lt;/h3&gt;
&lt;p&gt;Previously, instance-based methods don’t expose their object type; this hampers auto-suggestion. We solved this by introducing explicit &lt;code&gt;&amp;lt;Type&amp;gt;&lt;/code&gt; filters and category tags in our search syntax. The result is now the users can quickly locate relevant methods with filtered search - instant clarity. Up next, we want to add full context-aware, auto-connecting suggestion - move from “search” to “smart connection.”&lt;/p&gt;
&lt;h3 id=&quot;conclusion-2&quot;&gt;Conclusion&lt;/h3&gt;
&lt;p&gt;Unreal Blueprints’ delightful node suggestions inspired us to refine Divooka’s search. By introducing syntax like &lt;code&gt;[Category] &amp;lt;Type&amp;gt; Keywords...&lt;/code&gt;, Divooka now lets you filter instance-based methods explicitly - greatly improving discoverability. Coming up: auto-connection and smarter, context-aware wiring.&lt;/p&gt;
&lt;p&gt;Let me know if you are interesting in learning more specific implementation details - like the regex matching, indexing logic, or localization strategy!&lt;/p&gt;
&lt;p&gt;Happy visual coding!&lt;/p&gt;
</description>
<category>Other</category>
<guid isPermaLink="true">https://coderlegion.com/3063/devlog-20250507-bringing-smart-suggestions-and-smarter-search-to-divookas-visual-coding</guid>
<pubDate>Sun, 07 Sep 2025 23:39:02 +0000</pubDate>
</item>
<item>
<title>DevLog 20250816: Divooka Language Specification (Preliminary Look)</title>
<link>https://coderlegion.com/4757/devlog-20250816-divooka-language-specification-preliminary-look</link>
<description>&lt;h3 id=&quot;overview-2&quot;&gt;Overview&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Divooka&lt;/strong&gt; is a cutting-edge visual programming platform developed by Methodox Technologies, Inc. It enables users to build and deploy complex applications through a drag-and-drop, node-based interface that integrates seamlessly with C# and Python libraries.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Key Features&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;General-Purpose &amp;amp; Flexible&lt;/strong&gt;: Suitable for a wide range of use cases - from business tools to innovative software products - supporting both automation and application development.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Node-Based Visual Interface&lt;/strong&gt;: Workflows are constructed visually by connecting nodes that represent data operations, logic, APIs, and more.&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Multiple Editions&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Divooka Explore&lt;/strong&gt;: A beginner-friendly, Windows-only edition designed for learning, data analytics, dashboards, programming, and everyday utilities.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Divooka Compute&lt;/strong&gt;: A professional package built on the same engine, aimed at power users. Currently available as a Windows preview build, with Linux and macOS support planned for the full release.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Cross-Platform Vision&lt;/strong&gt;: While early versions support Windows, full Linux and macOS support is planned.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Strong Architectural Foundations&lt;/strong&gt;: Based on Data-Driven Design principles, Divooka emphasizes modular, external control of behavior through data files - streamlining workflows without modifying code.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Developer-Centric Philosophy&lt;/strong&gt;: Divooka is not a new programming language per se. Instead, it focuses on decoupling functionality from specific environments to maximize flexibility and usability.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Active Development &amp;amp; Community&lt;/strong&gt;: Ongoing updates, documentation (wiki), tutorials, a Discord community, and blog posts ensure an active ecosystem.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Divooka is built around &lt;strong&gt;node graphs as executable documents&lt;/strong&gt;. Instead of writing sequential code, developers construct graphs of nodes, where each node represents a unit of computation or data. This graph-based approach supports both &lt;strong&gt;dataflow-oriented&lt;/strong&gt; and &lt;strong&gt;procedural-oriented&lt;/strong&gt; paradigms. A Divooka script file (a &quot;Divooka Document&quot;) acts as a container for node graphs.&lt;/p&gt;
&lt;p&gt;At its simplest:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;A Divooka document contains multiple graphs.&lt;/li&gt;
&lt;li&gt;Each graph contains multiple nodes.&lt;/li&gt;
&lt;li&gt;Nodes have a type, an optional ID, and attributes.&lt;/li&gt;
&lt;li&gt;Node attributes can connect to other nodes’ attributes.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;In a &lt;a rel=&quot;nofollow&quot; href=&quot;https://wiki.methodox.io/en/Divooka/Language/DataflowContext&quot;&gt;Dataflow Context&lt;/a&gt;, node connections are acyclic; in a &lt;a rel=&quot;nofollow&quot; href=&quot;https://wiki.methodox.io/en/Divooka/Language/ProceduralContext&quot;&gt;Procedural Context&lt;/a&gt;, connections may be cyclic and more flexible.&lt;/p&gt;
&lt;h3 id=&quot;interpretation&quot;&gt;Interpretation&lt;/h3&gt;
&lt;p&gt;To illustrate the simplicity of the language, we can write a minimal interpreter in &lt;strong&gt;Python&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://coderlegion.com/?qa=blob&amp;amp;qa_blobid=12773764991494639793&quot; alt=&quot;Diagram&quot;&gt;&lt;/p&gt;
&lt;p&gt;This interpreter handles an acyclic graph of nodes with &lt;code&gt;Type&lt;/code&gt;, &lt;code&gt;ID&lt;/code&gt;, attributes (all strings), and connections between attributes. Connections are represented directly as attribute values: if an attribute value starts with &lt;code&gt;@&lt;/code&gt;, it refers to another node’s attribute (e.g., &lt;code&gt;@Node1.Value&lt;/code&gt;).&lt;/p&gt;
&lt;p&gt;For example:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;DefineNumber&lt;/code&gt; outputs a number in its &lt;code&gt;Value&lt;/code&gt; attribute.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;AddNumbers&lt;/code&gt; takes two numbers as inputs and produces a &lt;code&gt;Result&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Print&lt;/code&gt; consumes the &lt;code&gt;Result&lt;/code&gt; and prints it.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The interpreter maps node types to operators, executes them, and produces results.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;# minimal_graph_interpreter.py
# A tiny, in-memory, non-cyclic node graph + interpreter.
# Nodes have: Type, ID, attrs (all strings). Connections are '@NodeID.Attr'.

from typing import Dict, Any, List, Callable, Optional, Tuple

Node = Dict[str, Any]  # {&quot;ID&quot;: str, &quot;Type&quot;: str, &quot;attrs&quot;: {str:str}, &quot;state&quot;: {str:Any}}

def is_ref(value: Any) -&amp;gt; bool:
    return isinstance(value, str) and value.startswith(&quot;@&quot;) and &quot;.&quot; in value[1:]

def parse_ref(ref: str) -&amp;gt; Tuple[str, str]:
    # &quot;@NodeID.Attr&quot; -&amp;gt; (&quot;NodeID&quot;, &quot;Attr&quot;)
    target = ref[1:]
    node_id, attr = target.split(&quot;.&quot;, 1)
    return node_id, attr

def to_number(s: Any) -&amp;gt; Optional[float]:
    if isinstance(s, (int, float)):
        return float(s)
    if not isinstance(s, str):
        return None
    try:
        return float(int(s))
    except ValueError:
        try:
            return float(s)
        except ValueError:
            return None

class Interpreter:
    def __init__(self, nodes: List[Node]):
        # normalize nodes and build index
        self.nodes: List[Node] = []
        self.by_id: Dict[str, Node] = {}
        for n in nodes:
            node = {&quot;ID&quot;: n[&quot;ID&quot;], &quot;Type&quot;: n[&quot;Type&quot;], &quot;attrs&quot;: dict(n.get(&quot;attrs&quot;, {})), &quot;state&quot;: {}}
            self.nodes.append(node)
            self.by_id[node[&quot;ID&quot;]] = node

        # map Type -&amp;gt; evaluator
        self.ops: Dict[str, Callable[[Node], bool]] = {
            &quot;DefineNumber&quot;: self.op_define_number,
            &quot;AddNumbers&quot;: self.op_add_numbers,
            &quot;Print&quot;: self.op_print,
        }

    # ---- helpers ----
    def get_attr_value(self, node_id: str, attr: str) -&amp;gt; Any:
        &quot;&quot;&quot;Return the most 'evaluated' value for an attribute (state overrides attrs).&quot;&quot;&quot;
        node = self.by_id.get(node_id)
        if not node:
            return None
        if attr in node[&quot;state&quot;]:
            return node[&quot;state&quot;][attr]
        return node[&quot;attrs&quot;].get(attr)

    def resolve(self, raw: Any) -&amp;gt; Any:
        &quot;&quot;&quot;Dereference '@Node.Attr' chains once (graph is acyclic so one hop is enough).&quot;&quot;&quot;
        if is_ref(raw):
            nid, a = parse_ref(raw)
            return self.get_attr_value(nid, a)
        return raw

    def all_resolved(self, values: List[Any]) -&amp;gt; bool:
        return all(not is_ref(v) and v is not None for v in values)

    # ---- operators ----
    def op_define_number(self, node: Node) -&amp;gt; bool:
        # Input: attrs[&quot;Value&quot;] (string number). Output: state[&quot;Value&quot;] (numeric)
        if &quot;Value&quot; in node[&quot;state&quot;]:
            return False  # already done
        raw = node[&quot;attrs&quot;].get(&quot;Value&quot;)
        val = self.resolve(raw)
        num = to_number(val)
        if num is None:
            return False  # can't parse yet
        node[&quot;state&quot;][&quot;Value&quot;] = num
        return True

    def op_add_numbers(self, node: Node) -&amp;gt; bool:
        # Inputs: attrs[&quot;Value1&quot;], attrs[&quot;Value2&quot;] (can be @ refs). Output: state[&quot;Result&quot;]
        if &quot;Result&quot; in node[&quot;state&quot;]:
            return False
        v1 = to_number(self.resolve(node[&quot;attrs&quot;].get(&quot;Value1&quot;)))
        v2 = to_number(self.resolve(node[&quot;attrs&quot;].get(&quot;Value2&quot;)))
        if v1 is None or v2 is None:
            return False
        node[&quot;state&quot;][&quot;Result&quot;] = v1 + v2
        return True

    def op_print(self, node: Node) -&amp;gt; bool:
        # Input: attrs[&quot;Result&quot;] (@ ref). Side effect: print once. Also store state[&quot;Printed&quot;]=True
        if node[&quot;state&quot;].get(&quot;Printed&quot;):
            return False
        r = self.resolve(node[&quot;attrs&quot;].get(&quot;Result&quot;))
        # Allow printing numbers or strings once the reference resolves
        if r is None or is_ref(r):
            return False
        print(r)
        node[&quot;state&quot;][&quot;Printed&quot;] = True
        return True

    # ---- execution ----
    def step(self) -&amp;gt; bool:
        &quot;&quot;&quot;Try to make progress by evaluating any node whose inputs are ready.&quot;&quot;&quot;
        progressed = False
        for node in self.nodes:
            op = self.ops.get(node[&quot;Type&quot;])
            if not op:
                # Unknown node type: ignore
                continue
            progressed = op(node) or progressed
        return progressed

    def run(self, max_iters: int = 100):
        &quot;&quot;&quot;Iteratively evaluate until no changes (DAG assumed, so this stabilizes quickly).&quot;&quot;&quot;
        for _ in range(max_iters):
            if not self.step():
                return
        raise RuntimeError(&quot;Exceeded max iterations (graph might be cyclic or ill-formed).&quot;)


if __name__ == &quot;__main__&quot;:
    # --- Example in-memory graph ---
    graph = [
        {&quot;ID&quot;: &quot;Node1&quot;, &quot;Type&quot;: &quot;DefineNumber&quot;, &quot;attrs&quot;: {&quot;Value&quot;: &quot;3&quot;}},
        {&quot;ID&quot;: &quot;Node2&quot;, &quot;Type&quot;: &quot;DefineNumber&quot;, &quot;attrs&quot;: {&quot;Value&quot;: &quot;5&quot;}},
        {
            &quot;ID&quot;: &quot;Adder&quot;,
            &quot;Type&quot;: &quot;AddNumbers&quot;,
            &quot;attrs&quot;: {&quot;Value1&quot;: &quot;@Node1.Value&quot;, &quot;Value2&quot;: &quot;@Node2.Value&quot;},
        },
        {&quot;ID&quot;: &quot;Printer&quot;, &quot;Type&quot;: &quot;Print&quot;, &quot;attrs&quot;: {&quot;Result&quot;: &quot;@Adder.Result&quot;}},
    ]

    interp = Interpreter(graph)
    interp.run()   # Should print: 8.0
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Running the example graph prints:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;8.0
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;summary-1&quot;&gt;Summary&lt;/h3&gt;
&lt;p&gt;The Divooka language demonstrates how a &lt;strong&gt;minimalist graph-based specification&lt;/strong&gt; can serve as a foundation for both &lt;strong&gt;computation and orchestration&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Key takeaways:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Node-Centric Abstraction&lt;/strong&gt;: Everything is reduced to nodes with types, IDs, and attributes - uniform, extensible, and easy to interpret.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Simple Reference Mechanism&lt;/strong&gt;: The &lt;code&gt;@NodeID.Attr&lt;/code&gt; convention provides a straightforward but powerful way to connect attributes.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Separation of Concerns&lt;/strong&gt;: Distinguishing between &lt;em&gt;dataflow&lt;/em&gt; (acyclic, deterministic) and &lt;em&gt;procedural&lt;/em&gt; (control flow, cyclic) contexts allows Divooka to cover both declarative and imperative styles.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Composable Operators&lt;/strong&gt;: Even with just three operators (&lt;code&gt;DefineNumber&lt;/code&gt;, &lt;code&gt;AddNumbers&lt;/code&gt;, &lt;code&gt;Print&lt;/code&gt;), meaningful behaviors emerge.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Compact Interpreter Footprint&lt;/strong&gt;: The entire interpreter is under 200 lines of Python, demonstrating the specification’s simplicity and rapid prototyping potential.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;One might ask why not use traditional graph connections. The answer is simplicity: defining connections as local attribute references reduces structure while keeping graphs clean. In dataflow, inputs typically come from a single source, while in procedural contexts, outputs are unique but inputs may be shared, so we can just reverse the syntax - making this lightweight approach intuitive and efficient.&lt;/p&gt;
&lt;h3 id=&quot;reference&quot;&gt;Reference&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Wiki (WIP): &lt;a rel=&quot;nofollow&quot; href=&quot;https://wiki.methodox.io/en/Standardization/DiLS&quot;&gt;Divooka Language Specification&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
<category>Divooka</category>
<guid isPermaLink="true">https://coderlegion.com/4757/devlog-20250816-divooka-language-specification-preliminary-look</guid>
<pubDate>Sat, 16 Aug 2025 19:41:04 +0000</pubDate>
</item>
<item>
<title>DevLog 20250728: Multi-graph Navigation GUI</title>
<link>https://coderlegion.com/4322/devlog-20250728-multi-graph-navigation-gui</link>
<description>&lt;h3 id=&quot;overview-3&quot;&gt;Overview&lt;/h3&gt;
&lt;p&gt;From the beginning, we've expected Divooka documents to support multiple graphs for efficient daily use. I consider this essential for scripting purposes, as dealing with file system entry references should be the last thing on our minds when trying to get something done quickly.&lt;/p&gt;
&lt;p&gt;However, implementing this isn't straightforward. Several interesting and foundational features are required first: serialization, file format support, editor refactoring - and graph referencing, which we may discuss in a future entry.&lt;/p&gt;
&lt;p&gt;In traditional programming languages, especially object-oriented ones, similar functionality is often achieved by allowing multiple classes per file. In C#, for example, it's even possible to define partial classes across separate files, which can become confusing if not managed carefully.&lt;/p&gt;
&lt;h3 id=&quot;objective&quot;&gt;Objective&lt;/h3&gt;
&lt;p&gt;When working with multiple graphs in a single document, the experience should feel similar to working with separate documents that each contain a single graph. At the most basic level, the editor should allow quick and seamless switching between graphs. More advanced features will come later. For example, storing multiple graphs within a single document should eventually enable referencing those graphs or documents from other documents.&lt;/p&gt;
&lt;h3 id=&quot;implementation-progress&quot;&gt;Implementation Progress&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;https://dev-to-uploads.s3.amazonaws.com/uploads/articles/k3gcza59pu9l1lpes82s.png&quot; alt=&quot;Graphs Selection&quot;&gt;&lt;/p&gt;
&lt;p&gt;Today's goal was to support navigation and switching between different graphs in Neo.&lt;/p&gt;
&lt;p&gt;Preliminary work on refactoring the graph editor into a reusable component was already completed earlier. This refactor is also crucial for enabling the subgraph editing window.&lt;/p&gt;
&lt;p&gt;To maintain context when switching graphs, the current viewport remains unchanged. We've also implemented a mini-map to help users quickly identify their location within the graph.&lt;/p&gt;
&lt;h3 id=&quot;minimap-behavior&quot;&gt;Minimap Behavior&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;https://dev-to-uploads.s3.amazonaws.com/uploads/articles/unxovuu86yg2srk4tjd0.png&quot; alt=&quot;Minimap&quot;&gt;&lt;/p&gt;
&lt;p&gt;The math behind the minimap is a bit tricky, so it's worth documenting:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;When switching between graphs, the editor should either preserve the current viewport (location and zoom) or reset the view to the center of the new graph.&lt;/li&gt;
&lt;li&gt;A &quot;world boundary&quot; must be calculated that encompasses all nodes in the graph.&lt;/li&gt;
&lt;li&gt;A &quot;viewport boundary&quot; should also be calculated to represent the currently visible area of the canvas.&lt;/li&gt;
&lt;li&gt;The minimap scale (typically less than 1 to represent downscaling) should be the minimum of:  &lt;ul&gt;
&lt;li&gt;&lt;code&gt;minimap size / world size&lt;/code&gt;, or  &lt;/li&gt;
&lt;li&gt;&lt;code&gt;minimap size / viewport size&lt;/code&gt;, if the viewport is larger than the world (e.g., when zoomed out).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&quot;other-matters&quot;&gt;Other Matters&lt;/h3&gt;
&lt;p&gt;The Neo graph editor is taking noticeably longer to load lately. We may need to investigate and address performance issues soon.&lt;/p&gt;
</description>
<category>Divooka</category>
<guid isPermaLink="true">https://coderlegion.com/4322/devlog-20250728-multi-graph-navigation-gui</guid>
<pubDate>Tue, 29 Jul 2025 17:19:46 +0000</pubDate>
</item>
<item>
<title>DevLog 20250711: Flappy Bird in Divooka! (Sneak Peak)</title>
<link>https://coderlegion.com/3910/devlog-20250711-flappy-bird-in-divooka-sneak-peak</link>
<description>&lt;p&gt;&lt;img src=&quot;https://dev-to-uploads.s3.amazonaws.com/uploads/articles/o0azkmv7eu52o89j04yp.jpg&quot; alt=&quot;Flappy Bird Demo&quot;&gt;&lt;/p&gt;
&lt;h3 id=&quot;sneak-peek&quot;&gt;Sneak Peek&lt;/h3&gt;
&lt;p&gt;I'm very excited to share some updates, along with this early demo video of making and playing Flappy Bird in Divooka! Please take a look at our &lt;a rel=&quot;nofollow&quot; href=&quot;https://youtu.be/KPrjm8zWBuQ&quot;&gt;YouTube&lt;/a&gt; for the HD video!&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://dev-to-uploads.s3.amazonaws.com/uploads/articles/eg75q0dnksupzisf94kj.png&quot; alt=&quot;Graph Setup&quot;&gt;&lt;/p&gt;
&lt;p&gt;There's a lot of technology packed into and behind this little demo.&lt;br&gt;
Sure, there are hacks here and there - like all video games - and there's still tons to be done to make it production-ready and robust. But I think this is a good, solid proof-of-concept! We are at least at parity with what Unreal Engine Blueprint can achieve for interactive 2D games!&lt;/p&gt;
&lt;h3 id=&quot;overview-4&quot;&gt;Overview&lt;/h3&gt;
&lt;p&gt;Divooka by Methodox is our flagship visual programming language and programming platform.&lt;/p&gt;
&lt;p&gt;In the YouTube video, I shared a quick demo of the program setup, graph layout, and runtime behavior of Flappy Bird made in Divooka.&lt;/p&gt;
&lt;p&gt;This setup is entirely done in the Divooka procedural context as a proof of concept for competitive runtime performance, suitability for practical program development, general applicability of the Divooka language, and the availability of Glaze! - our real-time graphical application API.&lt;/p&gt;
&lt;p&gt;A detailed tutorial, along with all resource files, will be shared under the &lt;a rel=&quot;nofollow&quot; href=&quot;https://wiki.methodox.io/en/Frameworks/Glaze/Tutorials/FlappyBird&quot;&gt;Methodox Wiki&lt;/a&gt; when the time comes.&lt;/p&gt;
&lt;h3 id=&quot;dev-process&quot;&gt;Dev Process&lt;/h3&gt;
&lt;p&gt;The latest update on the &lt;a rel=&quot;nofollow&quot; href=&quot;https://dev.to/methodox/devlog-20250708-procedural-context-visual-debugger-in-divooka-4fb7&quot;&gt;procedural context visual debugger&lt;/a&gt; has been really helpful!&lt;/p&gt;
&lt;p&gt;For the purpose of this particular demo, I started in Divooka, then realized lots of missing pieces. So I drafted the API for Glaze! first, then did a benchmark in C# - so actually, there is a pure C# implementation before the Divooka implementation.&lt;/p&gt;
&lt;p&gt;The urgent need for &lt;a rel=&quot;nofollow&quot; href=&quot;https://dev.to/methodox/devlog-20250710-generics-in-divooka-49e6&quot;&gt;generics&lt;/a&gt; becomes evident when we don't have structs and other OOP constructs in Divooka - we need a way to contain tuples of values in collections.&lt;/p&gt;
&lt;h3 id=&quot;commentary&quot;&gt;Commentary&lt;/h3&gt;
&lt;p&gt;Unreal Engine can already do it - and we're just catching up. On the other hand, Unreal Engine actually packs a similar size - but with way more features! Reducing distribution size is something that will require tremendous effort from us.&lt;/p&gt;
&lt;h3 id=&quot;references&quot;&gt;References&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Learn more about procedural context: &lt;a rel=&quot;nofollow&quot; href=&quot;https://wiki.methodox.io/en/Divooka/Language/ProceduralContext&quot;&gt;Methodox Wiki&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;YouTube: &lt;a rel=&quot;nofollow&quot; href=&quot;https://youtu.be/KPrjm8zWBuQ&quot;&gt;Divooka Visual Programming&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Tutorial on making Flappy Bird in Divooka(WIP): &lt;a rel=&quot;nofollow&quot; href=&quot;https://wiki.methodox.io/en/Frameworks/Glaze/Tutorials/FlappyBird&quot;&gt;Methodox Wiki&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
<category>Divooka</category>
<guid isPermaLink="true">https://coderlegion.com/3910/devlog-20250711-flappy-bird-in-divooka-sneak-peak</guid>
<pubDate>Fri, 11 Jul 2025 19:38:55 +0000</pubDate>
</item>
<item>
<title>The Divooka Way - Part 1: Philosophically, How Exactly is Divooka Different and Useful</title>
<link>https://coderlegion.com/3862/the-divooka-way-part-1-philosophically-how-exactly-is-divooka-different-and-useful</link>
<description>&lt;ul&gt;
&lt;li&gt;Full title: The Divooka Way — Part 1: Philosophically, How Exactly is Divooka Different and Useful Compared to Plain Good Code API&lt;/li&gt;
&lt;li&gt;Tags: Visual Programming, Developer Tools, API Design, Software Architecture, Programming Paradigms, NVI, No-Code / Low-Code, Programming Philosophy, Tool Economy  &lt;/li&gt;
&lt;li&gt;Target Audience: Software Architects, Engine and Tool Developers, Programming Educators and Curriculum Designers, Low-Code/No-Code Platform Researchers, Senior Developers interested in alternative programming models, Developers interested in visual alternatives to traditional code*&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;abstract&quot;&gt;Abstract&lt;/h3&gt;
&lt;p&gt;Traditional programming uses text to represent program logic. Existing visual design platforms offer varying levels of programmability but generally focus on building specific kinds of applications. From a production-use perspective, Divooka represents a significant step forward in how users build and interact with software - by combining tool-building, data handling, and program logic under a single, coherent interface. This unified approach aims to deliver a substantial productivity boost.&lt;/p&gt;
&lt;h3 id=&quot;overview-5&quot;&gt;Overview&lt;/h3&gt;
&lt;p&gt;If we already have a really good library - just as we have high-quality commercial software - does it still matter what language or environment we use?&lt;/p&gt;
&lt;p&gt;In theory, it shouldn't. In practice, it absolutely does.&lt;/p&gt;
&lt;p&gt;Pretty much everything imaginable already exists for C++, often under GNU licenses. But that doesn't mean a Python, C#, or Java developer can easily access or use those resources. Even when libraries are available for a target language, usage may not be straightforward. Licensing, API design, and documentation all come into play.&lt;/p&gt;
&lt;p&gt;Still, let's imagine we have a well-written, freely accessible, multi-language-bound, well-documented, and easy-to-use library. Does it then matter &lt;em&gt;how&lt;/em&gt; we use it?&lt;/p&gt;
&lt;p&gt;That leads us to the core question:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;If we already have a really good API, why not just use it in C#, Python, C++, Lua, or Pure?&lt;/strong&gt;&lt;/p&gt;
&lt;h3 id=&quot;the-proof-of-concept&quot;&gt;The Proof of Concept&lt;/h3&gt;
&lt;p&gt;To explore this, we can approach the question from three distinct perspectives:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;The end user&lt;/li&gt;
&lt;li&gt;The program designer&lt;/li&gt;
&lt;li&gt;Everyday tool development and sharing&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;From the end user's perspective&lt;/strong&gt;, assuming the final deliverable is a polished CLI or GUI tool, it typically doesn't matter what language was used - as long as the interface is well-designed. Case closed.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;From the program designer's perspective&lt;/strong&gt;, building anything sophisticated involves significant &quot;dry&quot; work - debugging, iteration, architectural decisions. Productivity depends largely on the quality of the debugger and IDE, and again, it's not strictly tied to the programming language.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;But from the perspective of everyday tool use&lt;/strong&gt;, the question becomes more subtle. What do we mean by &quot;everyday tools&quot;? Broadly speaking, we mean:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Tools built quickly to solve practical problems within days&lt;/li&gt;
&lt;li&gt;Tools that are easy to share and use by others&lt;/li&gt;
&lt;li&gt;Tools that are easy to iterate, improve, refactor, and eventually package as full software&lt;/li&gt;
&lt;li&gt;Tools that are maintainable - so that months later, we can return and still understand what we were doing, without extensive documentation effort&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;To solve (1), you need extensive libraries.&lt;br&gt;
To solve (2), you need solid dependency and packaging mechanisms.&lt;br&gt;
To solve (3), you need simple syntax and easy refactoring.&lt;br&gt;
To solve (4), you need expressive, self-documenting code - or better yet, self-explanatory program design.&lt;/p&gt;
&lt;p&gt;It's in this third category - everyday tools - that &lt;strong&gt;Divooka stands out&lt;/strong&gt;. The features baked into Divooka's graph editor enable rapid development without sacrificing performance or scalability. The editor itself proves how smoothly things can run with minimal setup: just open a graph document, and it works.&lt;/p&gt;
&lt;h3 id=&quot;the-nvi&quot;&gt;The NVI&lt;/h3&gt;
&lt;p&gt;In Divooka, the primary mode of interaction is the &lt;strong&gt;Node Visual Interface (NVI)&lt;/strong&gt; - distinct from both CLI and GUI paradigms.&lt;/p&gt;
&lt;p&gt;Each node represents a functional unit, and the connections represent program or data flow. Unlike CLI, NVI offers &quot;autocomplete&quot; visually - everything is made explicit through connection and layout. Unlike a GUI, an NVI is composed entirely of nodes and avoids complex syntax structures.&lt;/p&gt;
&lt;p&gt;At the base is a &lt;strong&gt;node canvas&lt;/strong&gt;, and programs are built using what we call &lt;em&gt;node-driven design&lt;/em&gt; - a pattern that breaks software into node blocks, each representing a compositional or procedural component.&lt;/p&gt;
&lt;p&gt;The main &lt;strong&gt;disadvantage&lt;/strong&gt; of NVI compared to text-based programming is space inefficiency: nodes occupy screen real estate, reducing information density. But this is offset by improved &lt;strong&gt;readability&lt;/strong&gt;: the visual layout shows the exact dependencies between functional units - something much harder to grasp in linear text code.&lt;/p&gt;
&lt;p&gt;NVI becomes more powerful when it supports:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Subgraphs&lt;/strong&gt; – Logical groups of nodes encapsulated into single blocks. This is more compact than plain functions or classes and more intuitive than managing multiple files.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Extensible node visuals&lt;/strong&gt; – Nodes can be customized for specific data. For example, a &lt;em&gt;Table&lt;/em&gt; node can offer compact entry for 2D data, reducing friction.&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&quot;the-scripting-interface&quot;&gt;The Scripting Interface&lt;/h3&gt;
&lt;p&gt;At its core, the NVI exposes functionality in two ways:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Nodes represent standalone functional units in a Divooka document.&lt;/li&gt;
&lt;li&gt;A framework parses the interconnected nodes and derives behavior from the graph structure.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The key is &lt;strong&gt;interface availability&lt;/strong&gt; - file operations, media I/O, math routines, etc.&lt;/p&gt;
&lt;p&gt;The first use case is covered well by scripting languages like Python, Lua, or Jupyter.&lt;br&gt;
The second - interpreting a structured node graph into dynamic program behavior - is where traditional languages fall short, often requiring large, specialized frameworks (e.g., Streamlit for Python).&lt;/p&gt;
&lt;p&gt;With Divooka, the same graphical program often needs &lt;strong&gt;no changes at all&lt;/strong&gt;. A simple toggle in the host environment can completely redefine how the program behaves.&lt;/p&gt;
&lt;p&gt;Frameworks like &lt;strong&gt;Glaze&lt;/strong&gt;, &lt;strong&gt;Novella&lt;/strong&gt;, &lt;strong&gt;Ol'ista&lt;/strong&gt;, &lt;strong&gt;Slide Present&lt;/strong&gt;, and &lt;strong&gt;App Builder&lt;/strong&gt; (all part of Divooka Explore except &lt;strong&gt;App Builder&lt;/strong&gt;) rely heavily on metadata - information &lt;em&gt;not&lt;/em&gt; defined on the graph, but embedded in the document and interpreted by the host system.&lt;/p&gt;
&lt;p&gt;This separation - code in the graph, behavior defined by metadata - creates a powerful, &lt;strong&gt;data-driven&lt;/strong&gt; model that enables reuse, variation, and flexibility.&lt;/p&gt;
&lt;h3 id=&quot;on-the-matter-of-libraries&quot;&gt;On the Matter of Libraries&lt;/h3&gt;
&lt;p&gt;Not all useful features are readily available via libraries. And even when they are, compatibility issues, licenses, platform differences, and interoperability challenges often make reuse hard or impossible.&lt;/p&gt;
&lt;p&gt;At Methodox, we actively author and maintain a curated library set - &lt;strong&gt;toolboxes optimized for Divooka&lt;/strong&gt;. This represents a major investment, ensuring that as Divooka grows, users have an expanding, well-integrated set of native components tailored for node-driven environments.&lt;/p&gt;
&lt;h3 id=&quot;summary-2&quot;&gt;Summary&lt;/h3&gt;
&lt;p&gt;From a scripting standpoint, Divooka may appear unremarkable: libraries are still authored in native code, and Divooka simply provides an interface layer.&lt;/p&gt;
&lt;p&gt;But &lt;strong&gt;methodologically&lt;/strong&gt;, Divooka offers a profound shift in how we &lt;em&gt;build&lt;/em&gt; and &lt;em&gt;interact&lt;/em&gt; with programs. It's as different as using a natural-language model to co-write your software.&lt;/p&gt;
&lt;p&gt;Divooka is a high-level, GUI-native, NVI-first programming system. Our belief is that this new format can significantly enhance &lt;strong&gt;productivity&lt;/strong&gt;, &lt;strong&gt;readability&lt;/strong&gt;, and &lt;strong&gt;maintainability&lt;/strong&gt; by making programs &lt;strong&gt;smaller&lt;/strong&gt;, &lt;strong&gt;clearer&lt;/strong&gt;, &lt;strong&gt;less error-prone&lt;/strong&gt;, and &lt;strong&gt;more intuitive&lt;/strong&gt;.&lt;/p&gt;
</description>
<category>Divooka</category>
<guid isPermaLink="true">https://coderlegion.com/3862/the-divooka-way-part-1-philosophically-how-exactly-is-divooka-different-and-useful</guid>
<pubDate>Wed, 09 Jul 2025 20:28:58 +0000</pubDate>
</item>
<item>
<title>A General Service Configuration Scheme in Graphical Context</title>
<link>https://coderlegion.com/3150/a-general-service-configuration-scheme-in-graphical-context</link>
<description>&lt;h3 id=&quot;overview-6&quot;&gt;Overview&lt;/h3&gt;
&lt;p&gt;In this article, we take a look at one emerging pattern that provides a straightforward and compact way to configure services. Generally speaking, when a function expects many inputs, the most straightforward way is to directly expose those on the node. However, this quickly makes the node gigantic in size.&lt;/p&gt;
&lt;p&gt;(Node with many parameters)&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://coderlegion.com/?qa=blob&amp;amp;qa_blobid=10966338511247207470&quot; alt=&quot;Node with many parameters&quot;&gt;&lt;/p&gt;
&lt;p&gt;(Example in ComfyUI)&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://coderlegion.com/?qa=blob&amp;amp;qa_blobid=4213407889948385493&quot; alt=&quot;Example in ComfyUI&quot;&gt;&lt;/p&gt;
&lt;p&gt;When a node has too many parameters, it becomes bulky.&lt;/p&gt;
&lt;p&gt;(Example in Blender)&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://coderlegion.com/?qa=blob&amp;amp;qa_blobid=11621986877267314345&quot; alt=&quot;Example in Blender&quot;&gt;&lt;/p&gt;
&lt;p&gt;This quickly becomes infeasible when even more complex parameters are required for the functioning of nodes—for instance, if it's an online service with many potential configuration settings. A typical approach is thus to utilize a GUI element, which we shall call a &quot;node properties panel.&quot; Below is a sophisticated example from Houdini. PowerBI and Zapier do similar things.&lt;/p&gt;
&lt;p&gt;(Houdini node configuration panel)&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://coderlegion.com/?qa=blob&amp;amp;qa_blobid=15805477494334374509&quot; alt=&quot;Houdini node configuration panel&quot;&gt;&lt;/p&gt;
&lt;p&gt;This method falls short for two reasons:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;It's not explicit, and configuration parameters are not visible on the graph. Which makes it not possible to see dataflow nor to programmatically drive those values.&lt;/li&gt;
&lt;li&gt;It requires a dedicated GUI and can only be configured within that GUI.&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&quot;the-design-approach&quot;&gt;The Design Approach&lt;/h3&gt;
&lt;p&gt;Usually, some kind of scripting or expression language is used to address the first problem. For instance, in Houdini, users often write VEX snippets or Python expressions inside parameter fields to control behavior dynamically. In Zapier, configuration can include custom JavaScript code or formulas in input fields to manipulate data between steps. These workarounds bring back some level of flexibility, but at the cost of breaking the visual flow and requiring users to write code inside otherwise &quot;no-code&quot; or &quot;low-code&quot; environments.&lt;/p&gt;
&lt;p&gt;One design goal of Divooka is to be frontend-agnostic. The currently released frontend is officially known as &quot;Neo&quot;, which is a WPF-based technology. However, Divooka graphs are designed to be generic enough to be visualized on different frontends—ideally in a way that's very easy to implement. That’s why we prefer to expose everything explicitly, so no specialized logic is required on the frontend (e.g., to be aware of the nodes they are dealing with).&lt;/p&gt;
&lt;h3 id=&quot;configuration-in-divooka&quot;&gt;Configuration in Divooka&lt;/h3&gt;
&lt;p&gt;Visually, we have a &lt;code&gt;ConfigureX&lt;/code&gt; node and some nodes that take a configuration parameter as input. This dominant pattern is used in many places, including plotting configuration, OpenAI service configuration, and some other APIs like the image composition API.&lt;/p&gt;
&lt;p&gt;(Example of plot configuration)&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://coderlegion.com/?qa=blob&amp;amp;qa_blobid=17498224958783455849&quot; alt=&quot;Example of plot configuration&quot;&gt;&lt;/p&gt;
&lt;p&gt;(Example of OpenAI service configuration)&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://coderlegion.com/?qa=blob&amp;amp;qa_blobid=8094236953975528394&quot; alt=&quot;Example of OpenAI service configuration&quot;&gt;&lt;/p&gt;
&lt;p&gt;(Example of image composition API)&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://coderlegion.com/?qa=blob&amp;amp;qa_blobid=10649681161302771571&quot; alt=&quot;Example of image composition API&quot;&gt;&lt;/p&gt;
&lt;p&gt;We could provide a few different overrides for creating a configuration—so depending on how many details are needed, one can use a more lightweight or more heavy-duty configure node.&lt;/p&gt;
&lt;p&gt;(PostgreSQL with two different configurations)&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://coderlegion.com/?qa=blob&amp;amp;qa_blobid=6301383600821675371&quot; alt=&quot;PostgreSQL with two different configurations&quot;&gt;&lt;/p&gt;
&lt;p&gt;That concludes our introduction to the current setup, but the versatility of Divooka doesn't end here. Indeed, we could also introduce some kind of GUI panels for advanced configurations, and in fact, that’s desirable for certain things - at the price of losing the capability to programmatically drive the parameter values. This will be an expected standard feature in the full release of Divooka.&lt;/p&gt;
&lt;h3 id=&quot;references-1&quot;&gt;References&lt;/h3&gt;
&lt;p&gt;This article reference the following software:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Houdini – A professional 3D animation and visual effects software used in film, TV, and games, known for its node-based procedural workflow.&lt;/li&gt;
&lt;li&gt;Blender – A free and open-source 3D creation suite that supports modeling, animation, simulation, rendering, and more.&lt;/li&gt;
&lt;li&gt;ComfyUI – A graphical node-based interface for building image generation workflows using AI models like Stable Diffusion.&lt;/li&gt;
&lt;li&gt;PowerBI – A business analytics tool by Microsoft that lets users visualize data and share insights across an organization.&lt;/li&gt;
&lt;li&gt;PostgreSQL – A powerful, open-source relational database system with a strong emphasis on extensibility and standards compliance.&lt;/li&gt;
&lt;li&gt;Divooka – A general purpose programming language for building procedural programs and data flows through node graphs.&lt;/li&gt;
&lt;li&gt;Zapier – An online automation platform that connects different apps and services to automate workflows without coding.&lt;/li&gt;
&lt;/ul&gt;
</description>
<category>Best Practices</category>
<guid isPermaLink="true">https://coderlegion.com/3150/a-general-service-configuration-scheme-in-graphical-context</guid>
<pubDate>Sun, 25 May 2025 06:16:54 +0000</pubDate>
</item>
</channel>
</rss>