FCS Essentials

FCS is a declarative language for HiStruct/FemCAD models. This page is intentionally conservative: examples here should be valid FCS patterns, not pseudocode inspired by other languages.

If a snippet has not been checked with FLI or copied from a tested gist, do not promote it as working syntax.

The Most Important Boundary

FCS has both expressions and model-building statements. Do not blur them.

gblock is a statement-like model declaration. It is not an expression you can return from a lambda, assign into a list, or generate inside .Select(...).

Do not write gblock inside .Select(...), a lambda body, or a top-level assignment as if it returns a value. Use explicit named gblock declarations, or use a verified distribution pattern when you need repeated placement.

How FCS Evaluates

FCS is a pure functional language. A file is a set of definitions, like a spreadsheet written as source code.

Every .fcs file is also a class. A sibling file quadsol.fcs can be used as quadsol{a = 1, b = -3, c = 2}.resultArray without a declaration, or declared explicitly with gclass {gcQuad} filename "quadsol.fcs". Class{ ... } is an updater: it returns a copy of the instance with the listed fields replaced. Updaters compose: Q = quadsol{c = -10} then Q{a = 1, b = 2}.

:= vs =

Both operators are valid at the top level and inside updaters (Class{ ... }, parameters { ... }). Neither is "the top-level one" or "the parameter one". The difference is whether a value is an input that callers may override, and when it is evaluated.

The rule of thumb from the engine author: = says "nobody overrides this, you may inline and optimise it"; := says "this may be an input, keep a slot for it".

Top-level fields of a class file

a := 1        # input: lazy, cached, overridable by callers / PVC
b = 2         # internal value
s = a + b

Overriding each field from another file with Class{a = 10}.s and Class{b = 20}.s:

Engine (.fcsconfig.json) Class{a = 10}.s Class{b = 20}.s
e3.emulation (no config file) 12 21
e4.trans 12 21
e4.pure 12 error: Unable to update readonly field 'b' ... define it with ':='

Declare every value that a caller, a parent gblock or user input (PVC) may change with :=. Use = for derived or internal values. Code written this way works under every engine.

Inside updaters and parameters { ... }

x = gc{ a = someValue }.t     # '=' entry
y = gc{ a := someValue }.t    # ':=' entry

For constants and pass-through values (parameters {w = w}) both forms give the same result. Prefer := when the value is expensive or might fail.

Verified with fli.exe on 2026-10-12. See also Legacy engine warning and .fcsconfig.json.

Geometry Declarations

Basic geometry is declared with geometry keywords, not with invented helper calls:

vertex {p} xyz 1 2 3

That is the source of the Golden Example: Vertex. Evaluating p.X should return:

1

When coordinate arguments contain expressions, keep the expression syntax from verified examples. See Geometry Primitives and the tested geometry gists before extrapolating.

Reuse With gclass And gblock

A common reuse pattern is:

gclass {gcTable} filename "Table.fcs"
gclass {gcChair} filename "Chair.fcs"

gblock {gbTable} gclass {gcTable} lcs (GCS) parameters {tableWidth=tableWidth, tableLength=tableLength, tableHeight=tableHeight}
gblock {gbSnowWhite} gclass {gcChair} lcs (GCS.Ty(swY).Rz(PI)) parameters {seatHeight=swSeatH, seatWidth=swSeatW, seatDepth=swSeatD, backHeight=swBackH}

This is copied from the checked Snow White Dining example. Notice that each block has a stable name. The page does not pretend that gblock can be produced from .Select.

Lists And Lambdas

Use .Select(...) for values, numbers, records, or data needed by later declarations:

numbers := [1, 2, 3, 4, 5]
doubled := numbers.Select(x => x * 2)

Do not use .Select(...) to emit vertex, curve, area, volume, gclass, or gblock declarations unless that exact construct is backed by a working FLI test.

Repetition

For repeated model elements, prefer one of these documented routes:

Do not invent collection-comprehension syntax for model statements.

Read Next

  1. Start Here In 5 Minutes
  2. Geometry Primitives
  3. GBlock Placement gist
  4. Distribution Linear Array gist
  5. All Gotchas