Script Commands
What Is a Script Command?
A script command is a C# statement executed by the HiNC scripting engine. Scripts directly reference members and methods of SessionShell, which serves as the global scope — no explicit object reference is needed.
// These are all SessionShell members used directly as globals
EnablePhysics = true;
MachiningResolution_mm = 0.125;
PlayNcFile("NC/file1.nc");
Message("Done");
Script Syntax Basics
Scripts use native C# syntax:
| Feature | Syntax |
|---|---|
| Statement terminator | ; |
| End-of-line comment | // comment |
| String interpolation | $"Value is {variable}" |
| Positive infinity | double.PositiveInfinity |
| Negative infinity | double.NegativeInfinity |
| Bitwise OR (for flags) | Fx|Fy|Fz |
All standard C# language features (variables, loops, conditionals, LINQ, etc.) are available.
Execution Model
Session Lifecycle
- Scripts execute in order on the Task page
- A PacePlayer(API) controls playback — script commands like PlayNcFile(API) block until the NC program completes
- Player control commands (Pace()(API), Pause()(API), Reset()(API)) interact with the PacePlayer(API). The mission script runs on the player thread, so its own
Reset()is refused withReset--Refusedand resets nothing, since the reset would end the session and clear the runtime under the script's own run — reset the runtime between two programs with ResetRuntime(API) instead - ResetRuntime(API) clears the runtime state — the recorded steps, the meshed workpiece and the messages. Handlers on the session events survive it; they go when the session ends, at the player's Reset. Called inside the program being played — from the program's own embedded script, or by a script inside its own loop over RunNcFile(API) — it is refused with
ResetRuntime--Refused, resets nothing, and the program plays on; PowerReset(API) is refused there the same way (PowerReset--Refused). Call either between two programs
A Script command that does not compile is reported on Shell as ScriptCommand-Compile--Failed,
with every diagnostic, and runs nothing; one that throws — a cancellation of its own included — as
ScriptCommand-Run--Fault, with the script's own message, once, whether the error comes before or
after an await such as await Map(…). Neither ends the mission: it goes on with its next command.
An exception from an action the script returns — the play that
RunNcFile(API) hands back in return RunNcFile(…),
for one — is the play's, not the script's: the mission stops there, with Player-Run--Fault.
A Stop while the script runs is not a fault: the script ends without a report at its next call that looks at the
Stop — a play, an act, an NC optimization or a mapping it awaits — and the rows below it do not run
(see Starting and Stepping).
Event-Driven Execution
Events like SessionStepBuilt(API) fire during simulation and allow per-step logic:
SessionStepBuilt += (preStep, curStep) => {
if (curStep != null)
Message($"Step: ToolId={curStep.ToolId}");
};
PlayNcFile("NC/file1.nc");
A handler added this way belongs to the session: ResetRuntime leaves it in place, and it goes when the session ends, at the player's Reset.
Script Commands in NC Code
Script commands can be embedded in an NC program's own comments, so a setting changes at the point in the program where it applies. Two syntaxes have to agree for that to happen. The controller's comment syntax takes the comment out of the block first, and the comment character is the controller's own:
| Controller | What opens a comment |
|---|---|
| Fanuc, Mazak, Syntec | ( ) — parentheses, and nothing else |
| Siemens | ;, to the end of the line |
| Heidenhain | //, ; or ( ) |
The script syntax then takes the script out of the comment's text, by two markers: @@ for a script
that runs before the block's motion, @@^ for one that runs after it. The two markers are
settings of that syntax rather than fixed characters: they come from the controller definition a
project names, and a project that carries its own parser configuration keeps its own. On Siemens,
where ; opens the comment:
T01 M06 ;@@MachiningResolution_mm=0.03125;
S1270 M03
G43 Z10. H01
On a Fanuc-family controller the same script goes inside the parentheses:
T01 M06 (@@MachiningResolution_mm=0.03125;)
S1270 M03
G43 Z10. H01
Three rules decide whether the script a block carries is the script that runs:
- One script per marker, and each script goes last. A marker takes everything from itself to the
end of the comment, so text written after a script but still inside that comment is read as
part of it — a second
@@in one comment is swallowed into the first script. @@before@@^, in a comment that carries both. The after-the-block script is taken out of the comment first, so a comment that writes@@^first has its@@swallowed into it.- One parenthesised comment per line. Such a comment runs from the first
(to the last)on the line, so a second comment is read as part of the first. On Heidenhain the parenthesised comment is taken out before the;one, so a call written after;loses its arguments to it —;@@LineSelection("a", …);runs asLineSelection;, which does not compile. There, write a script that calls anything inside( )or after//.
An embedded script compiles against the same references and imports as a Script command, and like
a Script command it needs no licence feature of its own. A script that does not compile is reported
on its step as Script-Compile--Error and one that throws as Script-Run--Exception; neither stops
the play. A Stop pressed while an embedded script runs is seen at the next program or act the script
plays and ends the script there, without a report; a script whose block the Stop caught in progress
does not run. An embedded script cannot reset the run it plays in: @@ResetRuntime(); and
@@PowerReset(); are refused with ResetRuntime--Refused and PowerReset--Refused, reset nothing,
and the program plays on. Put such a reset between two programs, in a Script command or a script line
between their plays.
Note
Packages 3.2.7 to 3.2.31 ran embedded scripts only under the NcComposition licence feature.
Without it the first one reported Script--NotLicensed once and every further one — in that play
and in the plays after it — was skipped silently. A program whose embedded scripts stopped taking
effect after a move to one of those packages runs them again on a later one; nothing in the
program has to change.
Warning
;@ was the marker of the previous runner, and ;# was its after-the-block marker. On the runner
that plays NC today they are ordinary comment text and the command does not run. For ;@ the build
warns CsScript-Marker--Legacy once per NC file, naming the file and the first line where ;@
stands before a call or an assignment; a ;# command goes unreported. Written bare on a
Fanuc-family controller, where ; opens no comment at all, the text is not even a comment — the
build also warns UnparsedText--Remaining.
File Path Templates
Commands that output files support the [NcName] token, which is replaced with each NC file name:
PlayNcFile("NC/file1.nc");
PlayNcFile("NC/file2.nc");
WriteShotFiles("Output/[NcName].shot.csv", 1);
// Produces: Output/file1.nc.shot.csv, Output/file2.nc.shot.csv
All file paths are relative to the project directory unless an absolute path is given.
Important Warnings
The following operations can corrupt simulation state or produce incorrect results:
- Do not save the project during simulation. System-internal configuration (e.g., training-specific resolution overrides) may overwrite your settings.
- Do not reset the player during milling coefficient training. Close the project instead of pressing the reset button to avoid unexpected errors.
- Do not modify resolution, tool, or controller settings during training. Changing these mid-training invalidates the results.
- Do not play, reset or end the session inside a SessionStepBuilt(API) handler. A handler runs as each step is finished, while the play is still producing the next ones. Called from one, PlayAct(API), PlayToolingTeleport(API), PlayClTeleport(API), ResetRuntime(API), EndSession(API) and the player's Reset(API) throw: the exception is reported on that step as
Step--Exception, and the step is left without a result.PlayNcFileand the other program plays are refused as a second play (Play--Busyunder a mission;Play--BusyAnotherThreadwhen the play runs on another thread, such as a host's or a web request's). Closing the project is not refused, but stops the play and waits for it to end, while the play may be waiting for that handler: the two can wait on each other. Do such work after the play: a script line afterPlayNcFileruns once every step's handler has returned. - Do not play an act from another thread while a run is live. PlayAct(API), PlayToolingTeleport(API) or PlayClTeleport(API) called from a host's thread or a web request, and
LocalProjectService's Act(API) called by a host, play nothing while the player is running or paused — a mission, or a job such as the step-physics recompute — and reportPlay--BusyAct; a mission script's own call, on the player thread, and an NC-embedded script's are let through. While another thread plays NC on the session, an act from any other thread plays nothing and reportsPlay--BusyActAnotherThread. Make the call in the mission script, or after the run. - Do not combine
UpdateNcOptOptionin SessionStepBuilt(API) with NC-embedded optimization commands. Parallel computation may cause undefined behavior. - Do not write
NaNinto a per-stepNcOptOption. ANaNfeed-per-tooth boundary is refused when the step is solved: that step keeps its simulated feed rate and is reported as an error naming the option values, and the rest of the run is optimized normally. See When a Step Cannot Be Solved.
Global Variables
Global provides a key-value dictionary for sharing data across scripts:
Global["material"] = "Steel";
var material = Global["material"];
Full API Reference
For the complete list of available commands, properties, and events, see:
- SessionShell — full API documentation
- SessionShell — the command families, and which workflow uses each
See Also
- SessionShell — the command families this syntax reaches
- Step — machining step data model
- Workflow: Basic Machining Simulation — using scripts in a simulation workflow
- Cutter-Location (CL) Playback — replaying a CL toolpath from a script
- ShellProgress — the message stream a running script writes to
- NC Optimization — what a per-step optimization option does, and how a step that fails to solve is reported