User:Papaltine/ProtoGraph: Difference between revisions

From Resonite Wiki
mNo edit summary
Add object example with counter
 
(10 intermediate revisions by the same user not shown)
Line 2: Line 2:


== Overview ==
== Overview ==
* '''Paradigms''': Declarative, Modular
* '''Paradigm''': [[wikipedia:Dataflow_programming|Dataflow]]
* '''Family''': ML: Caml: OCaml: F#
* '''Family''': ML: Caml: OCaml: F#
* '''Designed by''': [[User:Papaltine|Papaltine]], [[User:Kittysquirrel|Kittysquirrel]]
* '''Designers''': [[User:Papaltine|Papaltine]], [[User:Kittysquirrel|Kittysquirrel]]
* '''Developer''': [[User:Papaltine|Papaltine]]
* '''Developer''': [[User:Papaltine|Papaltine]]
* '''Stable Release''': N/A (Currently in Alpha)
* '''Stable Release''': N/A (Currently in Beta)
* '''License''': AGPLv3
* '''License''': AGPLv3
* '''Target Platform''': Resonite (via ProtoFlux)
* '''Target Platform''': Resonite (via ProtoFlux)
Line 13: Line 13:
* '''Repository''': [https://git.samsmucny.com/ssmucny/Flux-SDK Flux SDK]
* '''Repository''': [https://git.samsmucny.com/ssmucny/Flux-SDK Flux SDK]
* '''Compiled Format''': <code>.brson</code> (Resonite Record)
* '''Compiled Format''': <code>.brson</code> (Resonite Record)
* '''Influenced by''': F#, Elm, Python, Haskell, Odin
* '''Influenced by''': F#, Elm, Python, Haskell, VHDL, Odin, Go
* '''Showcase World''': https://go.resonite.com/world/U-1O4IcGhlKSm/R-2045c574-dda6-4a7e-9955-56d2ca002d78


== Who Should Use ProtoGraph? ==
== Who Should Use ProtoGraph? ==
Line 21: Line 22:


== Benefits ==
== Benefits ==
* '''Readable''': Clean syntax that mirrors ProtoFlux visually
* '''Readable''': Clean syntax that mirrors ProtoFlux
* '''Modular''': Encourages reusable code through modules and packages
* '''Modular''': Encourages reusable and easy to refactor code
* '''Safe''': Compiler checks help catch errors early
* '''Reliable''': Compiler checks help catch errors early
* '''Accessible''': Friendly to those familiar with ProtoFlux as a first programming language
* '''Accessible''': Friendly to those familiar with ProtoFlux as a first programming language


Line 33: Line 34:
# Compile it:
# Compile it:
<syntaxhighlight lang="bash">
<syntaxhighlight lang="bash">
flux-sdk build MyModule.pg
dotnet flux-sdk.dll build MyModule.pg
</syntaxhighlight>
</syntaxhighlight>
# Import the <code>.brson</code> file into Resonite
# Import the <code>.brson</code> file into Resonite
# Inspect the generated ProtoFlux under the corresponding slot
# Inspect the generated ProtoFlux under the corresponding slot


== Example: Cross Product Module ==
== Examples ==
<syntaxhighlight lang="fsharp">
== Cross Product Module ==
This is a simple pure module that transforms input data into outputs.<syntaxhighlight lang="fsharp" line="1">
module CrossProduct
module CrossProduct
in A: float3
in B: float3
out this: float3
where {
// Inputs
Ax, Ay, Az = Unpack_Float3(A);
Bx, By, Bz = Unpack_Float3(B);
// Computations
Cx = (Ay * Bz) - (Az * By);
Cy = (Az * Bx) - (Ax * Bz);
Cz = (Ax * By) - (Ay * Bx);
// Final result
Pack_Float3(Cx, Cy, Cz);
}
</syntaxhighlight>
== Counter Object ==
This shows how you can write an object that maintains internal state and exposes methods to be called.<syntaxhighlight lang="fsharp" line="1">
module Counter
out this: int // The current value of the counter
// Public methods
out Increment: Impulse
out Decrement: Impulse
out Reset: Impulse


where {
where {
    /// First vector input
// Variables are not shared with other nodes, they are private
    let A = Pack_Float3;
sync CounterVar: int;
    /// Second vector input
 
    let B = Pack_Float3;
// out impulses are methods on the object that send it messages
// to do different actions
Reset = CounterVar <- 0;


    let Ax, Ay, Az = Unpack_Float3(A);
Increment = CounterVar <- ValueInc(CounterVar);
    let Bx, By, Bz = Unpack_Float3(B);


    let Cx = (Ay * Bz) - (Az * By);
Decrement = CounterVar <- ValueDec(CounterVar);
    let Cy = (Az * Bx) - (Ax * Bz);
    let Cz = (Ax * By) - (Ay * Bx);


    // Final result
// We can also expose normal data. This is like a getter.
    Pack_Float3(Cx, Cy, Cz);
CounterVar;
}
}
</syntaxhighlight>
</syntaxhighlight>
Line 64: Line 96:
* [https://git.samsmucny.com/ssmucny/Flux-SDK Git Repository]
* [https://git.samsmucny.com/ssmucny/Flux-SDK Git Repository]
* [[ProtoFlux]]
* [[ProtoFlux]]
* [https://www.youtube.com/watch?v=aPh4Z3SioB8 <nowiki>Dataflow Programming [Video]</nowiki>]

Latest revision as of 14:59, 16 July 2025

ProtoGraph is a declarative programming language designed to work with ProtoFlux in the Resonite ecosystem. It allows creators to write logic in a clean, readable text format that compiles directly into ProtoFlux nodes—making it easier to build, test, and maintain complex systems.

Overview

Who Should Use ProtoGraph?

  • Creators who want to move beyond visual scripting
  • Developers building modular, reusable systems
  • Teams collaborating on large-scale Resonite projects

Benefits

  • Readable: Clean syntax that mirrors ProtoFlux
  • Modular: Encourages reusable and easy to refactor code
  • Reliable: Compiler checks help catch errors early
  • Accessible: Friendly to those familiar with ProtoFlux as a first programming language

Building and Using in Resonite

Getting Started

  1. Write your .pg file
  2. Compile it:
dotnet flux-sdk.dll build MyModule.pg
  1. Import the .brson file into Resonite
  2. Inspect the generated ProtoFlux under the corresponding slot

Examples

Cross Product Module

This is a simple pure module that transforms input data into outputs.

module CrossProduct

in A: float3
in B: float3

out this: float3

where {
// Inputs
Ax, Ay, Az = Unpack_Float3(A);
Bx, By, Bz = Unpack_Float3(B);

// Computations
Cx = (Ay * Bz) - (Az * By);
Cy = (Az * Bx) - (Ax * Bz);
Cz = (Ax * By) - (Ay * Bx);

// Final result
Pack_Float3(Cx, Cy, Cz);
}

Counter Object

This shows how you can write an object that maintains internal state and exposes methods to be called.

module Counter

out this: int // The current value of the counter

// Public methods
out Increment: Impulse
out Decrement: Impulse
out Reset: Impulse

where {
// Variables are not shared with other nodes, they are private
sync CounterVar: int;

// out impulses are methods on the object that send it messages
// to do different actions
Reset = CounterVar <- 0;

Increment = CounterVar <- ValueInc(CounterVar);

Decrement = CounterVar <- ValueDec(CounterVar);

// We can also expose normal data. This is like a getter.
CounterVar;
}

See Also