On this page

Where NuML runs

Manual contents | Tutorial | Model logic | Dashboard configuration | Platforms

The same NuML language serves three workflows: typed live into a DynSS app's editor, loaded from a preset, or embedded in a project definition so that an app is authored entirely as configuration. This chapter describes each home and the engine contract they share.

1. Three homes for NuML code

Home Who writes it Where it lives
The DynSS Model Definition editor the user (or the AI portal), interactively the app's code input; saved into presets
Presets saved sessions, shipped examples the app's preset JSON (for example dynss2.json), under each preset's code property
Project.model the app author the project definition file (for example lorenzPrj.js)

2. The DynSS apps: editor, presets, and the AI portal

In a DynSS app (dynss2 and relatives), clicking Model Definition opens a NuML text area. Applying it compiles the model logic, reconfigures the dashboard per the #= directives, and arms the Run, Sensitivity, and Stochastic platforms. Compile problems surface in a Numl Error(s) dialog.

Each app ships a set of presets — complete NuML programs with saved slider state and documentation, selectable from the preset menu and briefly cataloged in the app's RAM documentation summary. Presets are the best starting points for new models; the manual contents indexes the most instructive ones.

The AI portal, reached from the model editor, chats with a choice of LLMs that have been given a NuML system instruction (for the dynss2 app, NuML_dynss.md). A prompt describing a model in natural language returns NuML code plus documentation; the code drops into the editor, populates the dashboard, and can be saved as a preset. Each LLM session keeps an independent chat history; switching presets resets the histories so stale context does not leak between models.

3. NuML in Project.model

An app author can embed the model logic directly in the Project definition. The shipped lorenz app declares its inputs and displays as ordinary Project inputs/displays, then supplies the equations as an array of NuML lines:

model: [
  "deriv(x) @= sigma * (y - x);",
  "deriv(y) @= x * (rho - z) - y;",
  "deriv(z) @= x * y - beta * z;",
  "initial(x) @= 10.0;",
  "initial(y) @= 1.0;",
  "initial(z) @= 1.0;",
  "update(x,y,z) @= mainGraph;",
  "update(x,z) @= phaseGraph;",
  "update(x,y,z) @= xyzGraph;"
]

Three things differ from the DynSS workflow:

import {SDMain} from "@nwk/api/sdmain.js"
import {uberfy} from "@nwk/api/uberbuilder.js"

class Lorenz extends SDMain {
  constructor() {super();}

  init() {
    super.init();
    this.uber = uberfy(this.model, this);
  }

  setup() {
    super.setup();
    this.uber.update();
  }

  update() {
    super.update();
    this.uber.update();
  }

  get model() {return this.getParam("model");}
  get sigma() {return this.getParam("sigma");}
  // … one getter per Project input …
}

The runtime joins the model array into one source string, parses it, and delivers it to the engine as the model parameter; uberfy compiles it exactly as in a DynSS app. Only the input getters vary between such apps — and when an app is created in Studio or Designer with the NuML pattern, even those are generated automatically from the Project's inputs (selector.js). An author using Studio or Designer therefore configures only the Project.

4. The engine contract

However it arrives, NuML reaches the simulation engine as a parameter value, and two conventions make that work:

The #= directives never reach the engine; the hosting page consumes them to reconfigure widgets, clock, and platforms before each run (directive.js).

5. Sharing models as presets

Saving a model in a DynSS app serializes the NuML program together with the dashboard state (slider positions, ranges, and legends) into the app's preset JSON format. Preset files can be downloaded, shared, and loaded by other users of the same app — the shipped dynss2.json, dynsshs.json, dynsslvpp.json, and dynsspb1.json are exactly such files. Models produced through the AI portal additionally record the LLM identity and the prompt in their documentation, keeping generated models reproducible and attributable.