DCode

Covers Engine 2.0.0

Overview

Write readable automation with channels, scoped state, reusable logic, and YAML templates.

DCode is DARTWIC’s language for automation. A script can turn measurements into engineering values, control outputs, raise warnings, or run a test procedure. Save .dcode files in your project’s scripts folder and activate them from the Interface.

Architecture of DCode

A script combines declarations that tell the Engine what work exists with code that performs that work. The names below follow the type labels in the editor’s documentation popup. Links open the relevant reference lists.

PartPurpose and examples
Runtime blocksDeclare Engine-managed work: tasks, timelines, loops, calculations, events, task groups, and callbacks.
Runtime sectionsOwn a task execution section: start:, task:, state idle:, or a timeline at T-10s: bucket. Loop and sequence bodies are implicit sections.
HandlersContain code for a bucket’s execute:, hold:, resume:, stop:, or abort:, or an event’s trigger:, on_firing:, or on_event:.
FieldsConfigure values: timeline clock_start:, bucket hold_at:, state-machine states:, calculation depends_on:, task-group run:, and event title: or channels:.
BlocksGroup, choose, repeat, or define code: if, for, while, function, once, and when.
StatementsPerform an action or declaration: assignment, command, free, transition, return, break, or global.
FunctionsCall reusable work, such as clamp(...), wait_until(...), or a helper you define. Standard helpers are also listed under Lua Base.
ModulesGroup shared functions and values in imported files or standard namespaces such as math and string. See Modules and Native Functions.
VariablesName authored values, collections, and function arguments. See Values and Scope.
Context variablesSupply Engine values where available, such as elapsed_seconds, current_state, or a calculation’s value.
DirectivesImport code, load YAML parameters, or expand template(...) declarations.
Syntax and keywordsForm expressions, literals, channel pipes, comments, and indentation. Keywords such as and, not, and return also have a role in these constructs.

A keyword can introduce a block or statement. Classification describes the construct, while placement decides its owner. Task lifecycle entries such as start: and timeline-level hold: are runtime sections; the same lifecycle names nested inside an at bucket are handlers belonging to that bucket. In the example below, task_periodic declares a runtime block, start: is a runtime section, if is a conditional block, and command writes an output under automation control.

Runtime Blocks

DCode exposes its runtime actions in Runtime Blocks. These are statements in the script that create artifacts that the engine manages, such as a task or a channel calculation. Read more at Runtime Blocks and Activation

Below are some pages to take a first look at depending on what you want to do:

You want to…Read
Derive a value when an input is writtenChannel Calculations
Report a condition or react to a limitEvents
Repeat work at a requested frequencyTasks
Organize behavior into named stagesTasks
Run ordered steps and waitsTasks
Schedule actions around T0Timelines
Expose an action to a schematic or another callerCallbacks

Activation installs the file’s runtime definitions. Closing its editor does not stop them; reactivation replaces them and resets script state.

Runtime blocks are marked by icons in the gutter, and their activation state is displayed in the menu bar, showing if they are loaded into memory or not. The icons will change color based on their state. Green indicates running, Grey indicates loaded but not running, and Yellow indicates stale/ not loaded.

When edits are made, the script will have to be re executed to rewrite what the engine has loaded in memory.

In the photo above, the YAML that drives the templated loops has been changed, which requires the script to be ran again.

Variables, Scope, Functions, and Other

Use Values and Scope for variables, collections, and shared state. Templates and Configuration creates several controllers from one definition and a YAML list; Modules and Native Functions covers helper files and plugin calls.

Start with the default Lua backend. Native C++ Execution explains compiled execution when you need it. Use the language reference to look up exact syntax and arguments.

Common Syntax and Functions describes blocks, functions, and syntax that is common to a DCodescript.

Automation Example

This controller requests filling below 20, stops above 40, and remembers its decision between those limits. That gap avoids repeated switching near a threshold.

In a test project, create docs_demo_pressure_a and docs_demo_pressure_b at 30. The output is a demo channel with no hardware connection:

limits = {low: 20, high: 40}

task_periodic docs_demo_fill:
    start:
        filling = 0

    task elapsed_seconds:
        global limits

        readings = [
            |docs_demo_pressure_a|,
            |docs_demo_pressure_b|
        ]
        pressure = math.max(readings[0], readings[1])

        if pressure < limits.low:
            filling = 1
        elif pressure > limits.high:
            filling = 0

        command |docs_demo_fill_request| = filling

    end:
        command |docs_demo_fill_request| = 0
        free |docs_demo_fill_request|

Activate the file and start docs_demo_fill. Set both inputs to 10: the request becomes 1. Return them to 30: it stays 1. Raise either to 45: it becomes 0. Stopping writes 0 and releases the task’s claim. Operator manual control still takes precedence; Channels and Control explains write authority.