#Rule Cost Model
#Purpose
This page defines the rough per-cell worst-case cost model used to compare rule shapes.
The units are comparative estimates for generated shader work, not timing guarantees. unit represents simple comparison, boolean operation, arithmetic operation, branch test, or assignment.
Costs are worst-case estimates for a cell that evaluates the expression or reaches the rule branch being described. They are not necessarily paid by every cell in the whole ruleset: first-match-wins rule ordering can skip later branches, and some outcome paths such as ranked tie/fallback handling or combine rows only run when their branch reaches that path.
For selector, clause, and outcome semantics, see Rule expressions. For the WGSL generation pipeline, see Rule engine internals.
#Shared Work
A -condition count over the Moore neighbors costs units.
Clause count selectors are precomputed once per unique selector and reused by every clause that needs the same count. Cost estimates for a standalone expression include the count unless otherwise stated; when a count is already available, only the expression-specific check is additional.
Direct assignments and simple current-cell checks cost unit.
#Cost Terms
| Term | Meaning |
|---|---|
selectedTribeCount |
Number of explicit tribe IDs in a tribes or different-in selector. |
countCost |
Cost of computing selector's neighbor count. A -tribe selector, same, or different costs when not reused. |
leftCountCost |
Count cost for the left side of a comparison. |
rightCountCost |
Count cost for the right side of a comparison. |
tribeCount |
Active tribe count, including dead. |
candidateCount |
Candidate tribe IDs considered by a ranked outcome. |
rankingOverhead |
. Per candidate: eligibility check, non-zero check, best-count comparison, and tie-count path. |
selectedTieOrFallback |
Cost of the tie or fallback outcome path that actually runs after ranking. |
nonDeadTribeCount |
Active tribe count excluding dead. |
rowInputCost |
Cost of evaluating lookup-row input selectors in a combine outcome. |
rowCount |
Number of lookup rows in a combine outcome. |
#Rule Branches
A deterministic rule branch costs: . The leading is the rule branch test.
A probabilistic rule with probability greater than and less than adds units for the deterministic hash/threshold guard.
Muted rules and rules with probability do not emit active rule branches. Outcome work is only paid on the branch that executes.
#Selector Costs
#tribes
As a count selector: . Each neighbor is compared against the selected tribe IDs.
As a ranked selector, the explicit list is the candidate list: .
For this selector form, .
Explicit selector signatures are sorted and deduplicated for stable reuse.
#same
As a count selector: .
As a ranked selector: .
The ranked implementation still iterates the full tribe list as candidate IDs and uses candidate == selfTribe as the eligibility check.
#different
As a count selector: .
As a ranked selector: .
The ranked implementation still iterates the full tribe list and uses candidate != selfTribe as the eligibility check.
#different-in
As a count selector: .
Each neighbor is compared against the selected tribe IDs and against the current cell tribe.
As a ranked selector: .
For this selector form, ; per-candidate eligibility also excludes candidate == selfTribe.
#tie
Inside ranked tie handling, tie reuses the current ranked state: .
When used in a combine row, each tied candidate referenced by the row can add units for a candidate neighbor count.
Outside a ranked tie branch, the compiler has no tie state and treats the selector like its source.
#Clause Costs
| Clause | Cost |
|---|---|
is |
|
count |
|
none |
|
exactly |
|
min |
|
max |
|
comparison |
|
not |
|
and |
|
or |
|
xor |
|
empty |
#Simplified Constant Clauses
Some clause shapes compile to constants and avoid unnecessary count work:
countwith[0, 8]costs ;min 0costs ;max 8costs ;iscovering every known tribe can cost astrue;isresolving to no known tribe can cost asfalse;emptycosts and always compiles tofalse.
#Reused Counts
When a selector count has already been precomputed, only the final test is additional:
A comparison likewise reuses either side independently when its count is already available.
#Outcome Costs
#fixed
A direct assignment to tribe index costs unit.
#same
A direct assignment from the current cell value costs unit.
#majority and minority
Ranked outcomes cost: , where: .
For a tribes selector, candidateCount is the explicit selector size, so .
For same and different, candidateCount is the full tribe list size. For tribes and different-in, candidateCount is the selected tribe count. Per-candidate eligibility checks determine which candidates can participate for the current cell.
Only the tie or fallback path that actually runs is counted in selectedTieOrFallback.
#combine
Combine outcomes cost: .
The terms are:
Rows that explicitly include dead add a cheap deadPresent condition.
Large tribe lists or combination tables can make generated shaders noticeably larger and slower.
This is the worst-case cost once the combine outcome runs. A row that matches early can avoid later row checks at runtime, but the formula counts all rows so lookup tables can be compared conservatively.
#Whole-Ruleset Considerations
#Rule Count and Order
More rules increase branch work and shader size.
Rule order matters because the engine uses first-match-wins evaluation. Earlier rules can prevent later branches from being evaluated.
A fixed-dead rule often adds work without changing the result because result already starts as dead. It is generally preferable to narrow a later positive rule unless the earlier branch deliberately exists to block it.
#Probabilistic Rules
Failed probabilistic rolls continue to later rules.
Overlapping probabilistic rules can therefore pay multiple clause and branch costs for the same cell before one applies or the chain ends.
#Bounded Topology
Bounded topology can add overhead near grid edges because off-grid neighbor reads must resolve to the virtual boundary tribe.
Interior bounded cells use a faster direct path, so this extra cost is concentrated on packed words that contain grid edges.
#Worked Examples
#Conway Birth
The standalone rule:
is dead
AND exactly 3 Alive neighbors
→ fixed Alive
costs units:
| Cost | Component |
|---|---|
Alive count |
|
is dead |
|
exactly 3 |
|
Boolean AND |
|
| Rule branch | |
| Fixed outcome | |
| Total |
#Conway Survival
The standalone rule:
is Alive
AND count Alive in [2, 3]
→ same
costs units:
| Cost | Component |
|---|---|
Alive count |
|
is Alive |
|
| Range check | |
Boolean AND |
|
| Rule branch | |
same outcome |
|
| Total |
When paired with Conway birth, the Alive count is already available. Adding survival therefore costs only additional units.
#Probabilistic Spread
A rule that matches Paper, requires at least Fire neighbor, and becomes Fire with probability costs units:
| Cost | Component |
|---|---|
Fire count |
|
is Paper |
|
min Fire 1 |
|
Boolean AND |
|
| Rule branch | |
| Probability hash/threshold guard | |
| Fixed outcome | |
| Total |
A failed roll continues to later rules.
#Ranked Majority
For:
different count >= 1
→ majority different
→ same on tie or fallback
the cost is: .
The fixed contains the different count clause, rule branch, and selected same tie/fallback path.
#Combine With Dead Priority
For the example with:
[Red, Blue, dead] → Ash
[Red, Blue] → Purple
default → dead
the cost is: .
The fixed contains:
| Cost | Component |
|---|---|
Rule branch + is dead |
|
dead-presence count |
|
| Lookup-row comparisons | |
| non-dead row-input references | |
| Default fixed outcome | |
| Total |
The base mask adds .
The explicit-dead row must be checked first because it has the same non-dead mask as the Red + Blue row.