FCS Essentials

FCS is a declarative language used to describe geometry, parameters, materials, loads, and generated outputs in HiStruct workflows. Most files use the .fcs extension.

Core Concepts

Practical tip: think of an FCS file as a live model graph. When one value changes, dependent expressions update automatically.

Variables

Top-level declarations use :=.

# Lazy binding (re-evaluates when dependencies change)
x := 10
name := "hello"
area := width * height   # computed — changes when width or height change

# Inside parameter blocks and object literals, use =
myObj := MyClass{ param1 = 10, param2 = "test" }

:= vs =

This distinction is one of the most important FCS habits to learn.

Correct usage

width := 10
height := 8
area := width * height

panel := RectPanel{
    Width = width
    Height = height
    Label = "A1"
}

Why it matters

At the top level, := creates a model binding. Inside object-style configuration blocks, = assigns parameter values immediately within that object literal or clause.

Common mistake

# Good
beamLength := 12

# Good
member := Beam{ Length = beamLength }

# Bad: using = at top level can behave differently than intended
beamLength = 12

Gotcha: if a value belongs to a parameters { ... } block, object literal, or inline config block, use = there even if the surrounding file mostly uses :=.

Types

FCS commonly uses the following value categories.

Numbers

Numbers are typically doubles.

n1 := 10
n2 := 3.14
n3 := -5.0

Strings

greeting := "hello"
path := "D:\\Models\\sample.fcs"

Booleans

isEnabled := True
isValid := False

Lists

values := [1, 2, 3]
points := ["A", "B", "C"]

Objects

pt := { x = 1, y = 2 }
style := { color = "Red", thickness = 2 }

Null / undefined

Some expressions may evaluate to null or undefined depending on context, optional parameters, or conditional construction.

optionalNote := Null

Practical tip: when a value may be missing, guard downstream expressions with a conditional instead of assuming the value always exists.

Operators

Arithmetic

a := 10 + 2
b := 10 - 2
c := 10 * 2
d := 10 / 2
m := 10 % 3
p := 2 ** 3

Comparison

isEqual := a == b
isNotEqual := a != b
isSmall := a < b
isLarge := a > b
isSmallOrEqual := a <= b
isLargeOrEqual := a >= b

Logical

ok := isEnabled && isValid
fallback := hasMesh || hasGeometry
notReady := !isReady

Ternary

label := width > 5 ? "large" : "small"

Practical tip: ternaries are useful for optional geometry, alternate materials, and conditional output values without needing verbose control flow.

Functions and Lambdas

Lambdas are compact and are often used with lists.

square := x => x * x
add := (a, b) => a + b

More examples:

isTall := h => h > 3.0
scalePoint := (p, f) => { x = p.x * f, y = p.y * f }

Use lambdas when you want a reusable expression or when list operators expect a function argument.

List Operations (LINQ-style)

FCS supports collection-style operations that feel similar to LINQ.

items := [1, 2, 3, 4, 5]
sum := items.Sum
filtered := items.Where(x => x > 2)
mapped := items.Select(x => x * 2)
reduced := items.Aggregate(0, (s, x) => s + x)
count := items.Count
first := items.First

Typical patterns

widths := [2.5, 3.0, 4.5]
maxWidth := widths.Max

names := ["A", "B", "C"]
joined := names.Aggregate("", (s, x) => s == "" ? x : s + ", " + x)

validHeights := heights.Where(h => h > 0)

Practical tip: prefer Where, Select, and Aggregate over manually duplicating expressions. They keep parameterized models compact and easier to change.

Math and Units

FCS includes standard math functions and unit helpers.

s := Sin(angle)
r := Sqrt(x**2 + y**2)
angle := 45 * Unit.deg    # degrees → radians
PI                         # built-in constant

Common math examples

hyp := Sqrt(dx**2 + dy**2)
angleRad := 90 * Unit.deg
cosVal := Cos(angleRad)

Units tip

If an API expects radians, multiply degree values by Unit.deg instead of manually converting.

roofPitch := 30 * Unit.deg
rotated := GCS.Rx(roofPitch)

String Operations

Strings can be concatenated and transformed through methods.

msg := "Value: " + x.ToString()
url.Replace("?", "%3F")

More examples

memberId := "B-" + index.ToString()
title := "Zone " + zoneName
safeUrl := rawUrl.Replace(" ", "%20")

Practical tip: use string building for labels, file names, report text, and diagnostic output values.

Coordinate Systems

Coordinate systems are central to geometry placement and transformation.

GCS                          # Global Coordinate System
GCS.Tx(d), GCS.Ty(d), GCS.Tz(d)  # Translation
GCS.Rx(a), GCS.Ry(a), GCS.Rz(a)  # Rotation (radians)

Examples

moveUp := GCS.Tz(3.0)
moveRight := GCS.Tx(5.0)
spin := GCS.Rz(45 * Unit.deg)

These transforms are often combined with local coordinate systems, gblocks, and distributed elements.

Key Insight: Lazy Evaluation

Lazy evaluation is the biggest conceptual difference from most scripting languages.

x := 10
y := x * 2    # y is the EXPRESSION "x * 2", not the number 20
x := 5        # NOW y evaluates to 10 (not still 20!)

Mental model

Why this is useful

Lazy evaluation makes parameterized models powerful:

Example: parametric rectangle

width := 10
height := 8
area := width * height
perimeter := 2 * (width + height)

width := 12
# area now evaluates to 96
# perimeter now evaluates to 40

Practical tip: define primary driving parameters first, then derive everything else from them. This is the cleanest way to build reusable FCS models.

Best Practices

Quick Reference

# Variables
x := 10
obj := MyType{ A = 1 }

# Types
n := 3.14
s := "hello"
b := True
l := [1, 2, 3]
o := { x = 1, y = 2 }

# Lambdas
square := x => x * x

# Lists
vals := [1, 2, 3]
vals.Select(x => x * 2)
vals.Where(x => x > 1)
vals.Sum

# Math
angle := 45 * Unit.deg
Sin(angle)
Sqrt(9)

# Coordinates
GCS.Tx(1)
GCS.Rz(90 * Unit.deg)

Final Takeaway

If you remember only one thing from this page, remember this:

Top-level FCS is lazy. Write models so derived values depend on source parameters, and always be deliberate about := versus =.