Language reference
EZScript is the small language behind every scriptable field in Poker Club HQ. This page is the syntax; Tournament data is the list of things to point it at.
Values
Section titled “Values”| Kind | Examples |
|---|---|
| Number | 10, 1.5, -20 |
| Text | "1st", " • ", "\n" |
| True or false | true, false |
| List | [100, 60, 40] |
| Object | {name: "Alice", chips: 12000} |
Names and assignment
Section titled “Names and assignment”Give a value a name with =, then use the name:
places = 1 + totalBuyIns / 5+=, -=, *=, /=, and %= update an existing name in place.
In a multi-line script, several statements can share one line if you separate them with ; — useful inside a template, where the whole script has to fit between one pair of braces:
{{ cards = highHand.pokerHandToCards; cards.pokerCardsToHandName }}Operators
Section titled “Operators”| Category | Operators |
|---|---|
| Arithmetic | + - * / % |
| Comparison | == != < > <= >= |
| Logical | && || ! |
Precedence follows normal arithmetic: * / % bind tighter than + -, comparisons come next, then &&, then \|\|. Use parentheses when in doubt.
+ joins text as well as adding numbers:
{{ chipLeaderPlayer.shortName + " — " + chipLeaderChips.round.toCompactDecimalString }}Conditions
Section titled “Conditions”if is an expression — it produces a value rather than just choosing a branch, so you can use it anywhere a value belongs, including in the middle of a bigger calculation:
if totalBuyIns < 10 { [100, 60, 40] }else if totalBuyIns < 17 { [150, 90, 60] }else { [180, 110, 70, 40] }{{ "Players" + if (currentPlayerCount == 1) { "" } else { "s" } }}The test must genuinely be true or false. A number or a piece of text won’t do — write count > 0, not count.
Parentheses around the test are optional.
Most of the time a list method like map or where is shorter and clearer than a loop, but loops are there when you need them:
// Over the items of a listfor p in playersActive { … }
// With the position as well — index first, item secondfor i, p in playersActive { … }
// While something holdswhile (n > 0) { n -= 1 }
// Countingfor i = 0; i < 10; i += 1 { … }break leaves a loop early and continue skips to the next pass. A loop’s variables belong to the loop and disappear when it ends.
Functions
Section titled “Functions”A function is written with func, and is most often handed straight to a list method:
players.where(func(p) { p.bountyChipWinnings > 0 })Give one a name when you want to use it more than once:
func toName(p) { p.shortName }A function returns the value of its last line — there’s no return.
Lists and objects
Section titled “Lists and objects”amounts = [100, 60, 40]amounts[0] // 100amounts.count // 3amounts[1] = 75 // change an entry
player = {name: "Alice", chips: 12000}player.name // Aliceplayer.chips = 15000player.seat = 4 // a name that didn't exist is addedObjects also accept player["name"], which is handy when the key is itself in a variable.
Comments
Section titled “Comments”// This is a commentpoints = ln(c + 1) / p * 10 // and so is thisComments are the tidiest way to keep an alternative formula around without deleting it — the built-in points formula ships with two disabled alternatives above the active line.
Built-in functions
Section titled “Built-in functions”| Function | Description |
|---|---|
now() | The current time, in milliseconds |
round(x) | Round to the nearest whole number |
min(a, b, …), max(a, b, …) | Smallest / largest of the values |
asNumber(x), asInteger(x), asString(x) | Convert between kinds |
sqrt(x), cbrt(x), hypot(a, b) | Roots and hypotenuse |
exp(x), ln(x), log10(x), log2(x) | Exponential and logarithms |
sin(x), cos(x), tan(x) | Trigonometry, in radians |
asin(x), acos(x), atan(x) | Inverse trigonometry |
degToRad(x), radToDeg(x) | Angle conversion |
PI is available as a constant.
Formatting numbers
Section titled “Formatting numbers”These are the properties that turn a raw number into something worth putting on a screen. Write them without parentheses.
| Property | Turns 1250 into | Good for |
|---|---|---|
toCompactDecimalString | 1.25K | Blinds and chip counts |
toCurrencyString | $1,250 | Payouts and prize pools |
toCompactCurrencyString | $1.25K | Money in tight spaces |
toPercentString | — | Fractions shown as percentages |
withOrdinalSuffix | 1250th | Finishing places — 1st, 2nd, 3rd |
round, ceil, floor, abs | 1250 | Tidying up a division |
toInt, toDouble, toString | Changing kind | |
isEven, isOdd | Alternating output | |
isFinite, isInfinite, isNaN | Guarding against divide-by-zero |
The compact forms keep three significant digits, so 1500 becomes 1.5K but 1250 becomes 1.25K. Round first if you want a shorter result.
Times and durations
Section titled “Times and durations”These read a number as milliseconds, which is the unit now() and every …Dt value use. A count of seconds needs * 1000 first.
| Property | Example output |
|---|---|
toTimeString | 8:15:00 PM |
toHMTimeString | 8:15 PM |
toDateString | Jul 20 — with the year added when it isn’t this year |
toDateAndTimeString | Jul 20, 8:15:00 PM |
toDateIfNotTodayAndTimeString | 8:15:00 PM today, with the date added on other days |
toTimeDurationString | 0:20:00 |
toCompactTimeDurationString | 20:00 |
{{ (secondsLeftInLevel * 1000).toCompactTimeDurationString }}{{ now().toTimeString }}Working with text
Section titled “Working with text”Properties — written without parentheses:
isEmpty, isNotEmpty, count, length, toUpperCase, toLowerCase, toSentenceCase, toNumber, toInt
Methods — written with parentheses:
| Method | Description |
|---|---|
contains(text) | Does it contain this? |
startsWith(text), endsWith(text) | Does it begin or end with this? |
indexOf(text) | Where does it appear? -1 if it doesn’t |
replace(from, to), replaceAll(from, to) | Substitute text |
substring(start [, end]) | A piece of it |
slice(start [, end]) | Same, but negative positions count from the end |
split(separator) | Break into a list |
strip([characters]) | Trim the ends |
Working with lists
Section titled “Working with lists”Properties: isEmpty, isNotEmpty, count, length, first, last
Methods:
| Method | Description |
|---|---|
map(fn) | Transform every item |
where(fn) | Keep the items that match |
sort([keyFn]) | A sorted copy — by natural order, or by whatever the function returns |
take(n), skip(n) | The first n, or everything after the first n |
takeFirstWhere(n, fn), takeLastWhere(n, fn) | The first or last n matches |
reverse() | A reversed copy |
reduce(fn [, initial]) | Combine everything into one value |
flatMap(fn) | Transform, then flatten the results |
join([separator [, lastSeparator]]) | Join into text |
zip(list, … [, combineFn]) | Pair up with other lists, item by item |
Two of these deserve a closer look.
sort takes a key. To sort descending, negate the key:
players.sort(func(p) { -p.totalEliminated })join takes a second separator for the last item, which is what makes a spoken alert sound human:
{{ e.players.map(func(p) { p.toPlayerName() }).join(", ", ", and ") }}With three players that reads “Alice, Bob, and Carol” rather than “Alice, Bob, Carol”. The last separator is used exactly as written, so include the comma — with two players it gives “Alice, and Bob”.
Use "\n" as a separator to put each item on its own line — that’s how the payout and knockout widgets build their columns.
Templates
Section titled “Templates”In a Value or TTS text field, anything outside {{ }} is literal and anything inside is an expression:
Level {{ blindLevelNumber }} of {{ blindLevelCount }}An expression that fails, or produces nothing, contributes an empty string.
There’s one rule worth knowing: if every expression in a template comes out empty, the whole template is treated as empty — the literal text around the braces is dropped too. So this:
Ante {{ anteText }}renders as nothing at all when anteText is empty, rather than leaving a stranded Ante . It’s how the built-in title and subtitle items disappear on levels that don’t have them, without needing a condition.
The rule is all-or-nothing. If a template has two expressions and only one comes out empty, the literal text stays and the empty one just leaves a gap.