metrics reference

discussion

events.critelli.technology supports metric expressions, which allow combinations of basic metrics with operators and functions

there are five types of basic metrics. simulator metrics are supported directly in the simulator. nicknames stand in for predefined metric expressions. time-based metrics have to do with submission time and are only supported on the website. output interval metrics return a list rather than a single number. the metrics of these four types are listed below. and finally, numbers are literally just numbers, like 1.5 or 700

the characters +-*/,() are used to write operators and functions that combine basic metrics together. these operators and functions are also listed below

any basic metric can be enclosed in quotation marks—either "double" or 'single'. a basic metric enclosed in quotation marks can include the characters +-*/,() without these characters being treated as part of an operator

simulator metrics

parsed cycles
parsed cost
parsed area
parsed instructions
returns the value for this metric recorded in the solution file. if no value is recorded (the solution hasn't completed), returns zero
cycles
runs the solution to completion and returns the cycle the last output was dropped
cost
returns the combined cost of all components
area
area (approximate)
runs the solution to completion in the same way as "cycles", but returns the area instead. the version with the (approximate) qualifier is there for historical reasons—both return the same value, equal to the area as measured by the game
instructions
counts each instruction like the game does, expanding repeat and reset instructions
instructions with hotkey hotkeys
counts instructions according to their in-game hotkey (QWERTASDFG). repeat and reset instructions are expanded before instructions are counted -- specifying a C or V hotkey will produce an error, since they have already been expanded. you can specify multiple hotkeys: e.g. "instructions with hotkey ADQE" to count rotations and pivots
executed instructions
runs the solution to completion and counts each instruction like the game does, ignoring instructions that are never executed before the solution completes
instruction executions
runs the solution to completion and counts each instruction like the game does, counting each execution of each instruction. instructions that execute multiple times are counted once per execution; instructions that are never executed are not counted
instruction executions with hotkey hotkeys
similar to instruction executions, but only counts instructions with the given in-game hotkey or hotkeys.
instruction tape period
counts how many cycles elapse before the instruction tape loops
height
runs the solution to completion, then measures the length of the area footprint perpendicular to each axis. the smallest measured length is returned
width*2
runs the solution to completion, then measures the length of the area footprint parallel to each axis. the smallest measured length is multiplied by two (to avoid fractional results) and returned
omniheight
runs the solution to completion, then measures the length of the area footprint perpendicular to each axis. the largest measured length is returned
omniwidth*2
runs the solution to completion, then measures the length of the area footprint parallel to each axis. the largest measured length is multiplied by two (to avoid fractional results) and returned
height at 0 degrees
runs the solution to completion, then measures the length of the area footprint perpendicular to the horizontal axis
height at 60 degrees
runs the solution to completion, then measures the length of the area footprint perpendicular to the axis 60 degrees from horizontal
height at 120 degrees
runs the solution to completion, then measures the length of the area footprint perpendicular to the axis 120 degrees from horizontal
width*2 at 0 degrees
runs the solution to completion, then measures the length of the area footprint perpendicular to the vertical axis, multiplied by two
width*2 at 60 degrees
runs the solution to completion, then measures the length of the area footprint perpendicular to the axis 60 degrees from vertical, multiplied by two
width*2 at 120 degrees
runs the solution to completion, then measures the length of the area footprint perpendicular to the axis 120 degrees from vertical, multiplied by two
minimum hexagon
runs the solution to completion, then measures the side length of the smallest axis-aligned regular hexagon containing the area footprint
per repetition cycles
throughput cycles
runs the solution until it enters a repeating loop, then returns the number of cycles in the loop. if the solution doesn't enter a repeating loop, produces an error
per repetition outputs
throughput outputs
runs the solution until it enters a repeating loop, then returns the number of outputs produced in the loop. if the solution doesn't enter a repeating loop, produces an error
per repetition area
runs the solution until it enters a repeating loop, then returns the amount the area grows each loop. produces an error if the area doesn't grow by a consistent value each repetition
per repetition^2 area
runs the solution until it enters a repeating loop, then returns the amount that area growth accelerates each loop in the limit. the value is normalized so that a stick growing by one atom per loop that swings through one sextant has a "per repetition^2 area" of 1. note that this value can be non-integral and even irrational in some cases, so make sure to use the verifier_evaluate_approximate_metric function to measure it if you're using libverify directly
throughput waste
runs the solution until it loops. if the solution grows larger forever, a positive number is returned. if the solution reaches a steady state without area growth, zero is returned
product n metric
measures any simulator metric metric which "runs the solution to completion" as if the solution were to complete after the n-th product instead of after the product count specified in the puzzle file. for example, "product 1 cycles" will measure the latency for the first product
reaches steady state
runs the solution until it enters a repeating loop, then returns 1. if the solution doesn't enter a repeating loop, returns 0 without producing an error
steady state metric
measures any simulator metric metric which "runs the solution to completion" as if the the solution were to complete after entering a repeating steady state. for example, "steady state area" will measure the area in the steady state. measuring a metric which increases each time the steady state repeats itself will produce an error
parts of type type
returns the number of parts in the solution of type type. possible types include
parts of type arm1
parts of type arm2
parts of type arm3
parts of type arm6
parts of type piston
parts of type track
parts of type baron
van berlo's wheel
parts of type bonder
parts of type unbonder
parts of type bonder-prisma
triplex bonder
parts of type bonder-speed
multi-bonder
parts of type glyph-calcification
parts of type glyph-dispersion
parts of type glyph-disposal
parts of type glyph-duplication
parts of type glyph-life-and-death
glyph of animismus
parts of type glyph-marker
glyph of equilibrium
parts of type glyph-projection
parts of type glyph-purification
parts of type glyph-unification
parts of type input
parts of type out-rep
repeating (infinite) product
parts of type out-std
non-repeating product
parts of type pipe
conduit
atoms grabbed
runs the solution to completion, measuring the number of times an atom is grabbed. a hex-arm grabbing six atoms counts as six atoms grabbed
atoms grabbed of type type
runs the solution to completion, measuring the number of times atoms of a particular type are grabbed. the possible types are
atoms grabbed of type salt
atoms grabbed of type air
atoms grabbed of type earth
atoms grabbed of type fire
atoms grabbed of type water
atoms grabbed of type quicksilver
atoms grabbed of type gold
atoms grabbed of type silver
atoms grabbed of type copper
atoms grabbed of type iron
atoms grabbed of type tin
atoms grabbed of type lead
atoms grabbed of type vitae
atoms grabbed of type mors
atoms grabbed of type quintessence
number of track segments
iterates over each track piece, counts all the segments in that piece, and returns the combined total
number of arms
returns the number of arms (the van berlo's wheel is considered an arm)
maximum absolute arm rotation
runs the solution to completion while recording the absolute value of the rotation of each arm on every cycle. the maximum absolute rotation value is returned
overlap
places each part in the solution, counting each hex of area that is placed on top of an existing part's area (not including grabbers or arm bases that overlap track)
duplicate reagents
counts how many reagents appear more than once in the solution. each appearance after the first of each reagent adds one to the total count. reagents that don't appear in the puzzle (and would cause the solution to crash when loaded) are not counted
duplicate products
counts how many products appear more than once in the solution in the same way that "duplicate reagents" counts reagents
maximum track gap^2
iterates over each track piece, measuring the distance between each segment in that piece and the next segment. the square of the maximum distance is returned. this will always be either 1 or 0 for solutions created in-game
visual loop start cycle
visual loop end cycle
returns cycles between which the solution visibly loops

operators

a + b
a * b
a - b
a / b
(a)
the standard arithmetic operators with the usual PEMDAS precedence
a ** b
returns a to the b'th power

functions

min()
returns the smallest value passed to it. accepts any number of values. for example, min(100, 2, 18) returns 2
max()
returns the largest value passed to it. accepts any number of values. for example, max(7, 8) returns 8
sqrt()
returns the square root of the value passed to it. for example, sqrt(4) returns 2
abs()
returns the absolute value of the value passed to it. for example, abs(-4) returns 4

nicknames

width
"width*2"/2
omniwidth
"omniwidth*2"/2
throughput
per repetition outputs / per repetition cycles
rate
1 / throughput
gold
cost
sum
cost + cycles + area
sum4
sum + instructions
arms
number of arms
track
number of track segments
latency
product 1 cycles
default restrictions
overlap + max(0, parts of type baron - 1) + max(0, "parts of type glyph-disposal" - 1) + duplicate reagents + duplicate products + max(0, "maximum track gap^2" - 1)

time-based metrics

minutes elapsed since date
seconds elapsed since date
milliseconds elapsed since date

returns the time interval between the given date and the instant the solution is validated. the interval measured by the server (when submitting a solution) is the one recorded, not the one measured by the web browser on the submission page

possible date formats include

minutes elapsed since 2022-06-23T19:01
minutes elapsed since 2022-06-23T19:01Z
minutes elapsed since 2022-06-23T19:01+00:00
the number of minutes since 19:01 on 2022-06-23 in the UTC time zone
milliseconds elapsed since 2022-06-23T19:02-07:00
milliseconds since 19:02 on 2022-06-23 in the PDT (UTC -7) time zone
seconds elapsed since 2022-06-23T19:01:59
seconds since 19:01:59 on 2022-06-23 in the UTC time zone
milliseconds elapsed since 2022-06-23T19:01:59.999
milliseconds since 19:01:59.999 on 2022-06-23 in the UTC time zone

note that, to avoid the - signs being parsed as operators, all time-based metrics must be enclosed in quotes. for example, "milliseconds elapsed since 2022-06-23T19:01:59.999"

output interval metrics

output intervals

unlike most other metrics, this returns a list. the list begins with the cycle when the first product set is dropped. the second item in the list is the interval between the cycle when the first product set is dropped and the cycle when the second product set is dropped. the third item in the list is the interval between the second product set and the third product set, and so on. if the solution loops, the list may repeat forever; the repeating part is marked with square brackets