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.
| Part | Purpose and examples |
|---|---|
| Runtime blocks | Declare Engine-managed work: tasks, timelines, loops, calculations, events, task groups, and callbacks. |
| Runtime sections | Own a task execution section: start:, task:, state idle:, or a timeline at T-10s: bucket. Loop and sequence bodies are implicit sections. |
| Handlers | Contain code for a bucket’s execute:, hold:, resume:, stop:, or abort:, or an event’s trigger:, on_firing:, or on_event:. |
| Fields | Configure values: timeline clock_start:, bucket hold_at:, state-machine states:, calculation depends_on:, task-group run:, and event title: or channels:. |
| Blocks | Group, choose, repeat, or define code: if, for, while, function, once, and when. |
| Statements | Perform an action or declaration: assignment, command, free, transition, return, break, or global. |
| Functions | Call reusable work, such as clamp(...), wait_until(...), or a helper you define. Standard helpers are also listed under Lua Base. |
| Modules | Group shared functions and values in imported files or standard namespaces such as math and string. See Modules and Native Functions. |
| Variables | Name authored values, collections, and function arguments. See Values and Scope. |
| Context variables | Supply Engine values where available, such as elapsed_seconds, current_state, or a calculation’s value. |
| Directives | Import code, load YAML parameters, or expand template(...) declarations. |
| Syntax and keywords | Form 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 written | Channel Calculations |
| Report a condition or react to a limit | Events |
| Repeat work at a requested frequency | Tasks |
| Organize behavior into named stages | Tasks |
| Run ordered steps and waits | Tasks |
| Schedule actions around T0 | Timelines |
| Expose an action to a schematic or another caller | Callbacks |
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.