Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Statements

Every line in an .fsl file starts with a keyword or tier name. This chapter explains what each statement does, why you would reach for it, and where it appears in the example at the end.

set – project-wide settings

Use set to update metadata (set name, set ri) or machine configuration (set gear, set girdle). The change applies immediately and carries forward to later lines.

CommandValue syntaxWhat it controlsNotes
set name "Brilliant Oval"Quoted stringUpdates the project title used in the viewer, analyzer panels, and printable exports.Keep the quotes when you need spaces; later set name calls overwrite the previous label.
set ri 1.760Plain number or optimizable literal (for example [1.76, 1.70, 1.80])Defines the refractive index the renderer, analyzer, and optimizer use for light calculations.Makes RI available to the optimizer if you supply the square-bracket form.
set color #ffd166Hex literal (#fff, #ffaa33), named color (red, cyan, ...).Sets the simulated material color in screenshots and raytraces.
set absorption 0.6Number from 0.0–1.0Controls how strongly the gem colour tints the interactive WebGL preview.Defaults to 0.6; lower numbers reduce tinting while 1.0 fully uses the gem colour.
set gear 96 cwPositive integer followed by optional cw or ccwSets the index gear tooth count and dop rotation direction for every later facet.Gear must be an integer; include cw/ccw only when you need to flip the rotation.
set girdle 4.5Number representing a percentage of the stone’s average widthAdjusts how thick the girdle is when interpreting +/- girdle offsets.Typical values are 2–5; larger numbers make the girdle offsets push farther.
set cube 3.0Number interpreted as the cube’s edge lengthRebuilds the starting blank as a cube of the given size before additional cuts.This discards previously cut geometry, so place it near the top of a file.

let – save a value for later

let table = mp(G1) stores a point or number so you can reuse it further down. Inside macros, the binding disappears when the macro finishes; elsewhere it lives to the end of the file. Edge helpers are the only exception: they emit two points, so let edge_ref = edge(...) is invalid—always destructure the pair.

Need both endpoints of an existing facet edge? Add a second identifier on the left and feed an edge(...) helper. The interpreter assigns the ordered pair of edge points to those identifiers. Replace whichever side you do not care about with _ to discard it. In a fresh file you can try:

set name "Edge destructuring"
set gear 96

P1 down 0 @ 41.8 : 0.18 x8

let break_a, break_b = edge(P1:0, P1:12)
let keep, _ = edge(P1:12, P1:24)

Those bindings behave like any other point variable—you can aim facets at them, drop debug markers, or pass them into macros.

show – drop a marker (or edge) in the viewer

show mp(P1) drops a marker using the default highlight colour (#ffd166). Add up or down (right after show) if you want to force the side, and optionally supply a colour: either one of the named options (cyan, orange, etc.) or a hex literal such as #ffe422 or #fff. The web studio keeps a small picker next to the editor so you can drop in hex values without memorising them.

Need to highlight a segment instead of a single point? Feed show edge(Tier:Index, Tier:Index) and the viewer/printable exports draw the coloured line. Just like the let statement, show does not accept edge variables directly—call edge(...) inline or reuse the destructured point pair.

Macros – reuse a favourite sequence

define macro wraps statements so you can replay them with a single command. Every parameter is named ($Macro(tier = "C1")), and defaults live either in the header or inline using ${param = ...}. They are an advanced feature, often used for complex gem outlines.

Facet commands – the main event

When a line starts with a tier name (P1, Star, etc.) you are cutting a facet. Read it like a simple recipe:

Tier [up|down] index @ angle : target xN ["note"] frosted

Go left to right:

  • Tier – the label that will appear in the printable diagram.
  • up / down – crown or pavilion. Leave it off when the tier already implies the side (for example, a C tier lives on the crown, a P tier is pavilion).
  • index @ angle – which tooth on the gear and which angle to lock in. Legacy notes that show < still parse the same way.
  • : target – how far to swing the quill. This can be a depth (: 0.18), a meet point (: mp(G1)), or the special word size for auto-depth on 90° girdle cuts.
  • xN – how many times to echo the facet around the dop. Use xxN when you want mirror-image pairs (for example, left/right star facets).
  • "note" / frosted – optional add-ons: custom printable text or hatch marks.

Here is the classic pavilion break written that way:

P1 down 0 @ 41.8 : 0.18 x8
  • P1 — name in the legend.
  • down — pavilion side.
  • 0 @ 41.8 — tooth 0, 41.8° on the dial.
  • : 0.18 — stop when the quill drops 0.18 units.
  • x8 — repeat eight times (every 45°).

Once you remember the pattern, you only need to choose which target style fits:

  1. Angle + depthP1 down 0 @ 41.8 : 0.18 x8. Great for pavilion mains, breaks, or any cut where you know the depth. Use : size only with 90° girdle passes that should land exactly on the girdle thickness.
  2. Angle + pointC1 up 0 @ 32 : mp(G1) + girdle x16. Aim the facet at a meet point or helper. Add + girdle / - girdle if the point should sit slightly outside or inside the default girdle radius.
  3. Point pairG3 0 : mp(G1) : mp(C2) x16. Define the plane using two points instead of an angle. Ideal for tidying a girdle or bridging between meet points when the trig would be a pain.

Tier naming, sides, and base index rules

Every tier label must be a single string with no whitespace inside it, and it has to start with an alphanumeric character. Reserved keywords (set, let, show, etc.) are off limits as tier names. The optional up/down flag tells the interpreter which side of the stone to use, but most of the time the engine can infer it:

  • Names that start with P default to the pavilion.
  • Names that start with C default to the crown.
  • If you omit the side and the previous cut specified one, that side carries forward.

That’s why a table named T typically doesn’t need up—it inherits the current crown context. You can always override the inference by writing the side explicitly.

The base_index argument is zero-based and must stay below gear / symmetry. Until you dig into the Symmetry section later in this guide, use this mental model:

  • With a 96 index gear and 4-fold symmetry, the valid base index range is 0 .. (96 / 4 - 1)0 .. 23.

Some quick examples:

P1 1 …     // Pavilion cut using base index 1
G2 1 …     // Girdle tier; inherits the pavilion side from P1
C1 3 …     // Crown cut using base index 3
X8 down …  // Non-standard tier name forced onto the pavilion

Everything together

Paste the snippet below into a fresh file to see each statement in context. Feel free to tweak the numbers and watch how the studio responds.

set name "Statement Tour"
set gear 96
set ri 1.760

P1 down 0 @ 41.8 : 0.18 x8
P2 down 6 @ 39.4 : mp(P1) x8

let break_angle = 23.2

show mp(P1) #0011ff

G1 0 @ 90 : size x16
G2 0 @ 90 : mp(G1) x16

let table = mp(G1)
show table #ff004c

define macro CrownRing(tier, angle = 32.0, target = table)
  ${tier} up 0 @ ${angle} : ${target} + girdle x16
end macro

$CrownRing(tier = "C1", angle = break_angle)
$CrownRing(tier = "C2", angle = 27.5)

Once you are comfortable with the building blocks, jump to Expressions to see how to shape angles, numbers, and points inside those statements.

Curious how we handle your designs or what to expect from the simulator? Read the Privacy, ownership, and disclaimer note for the plain-language policy.