tiny-soccersim-rust/docs/tsrc-language
2026-09-24 22:59:45 -04:00
..
README.md Add docs, new define directive and ASCII table output as an option 2026-09-24 22:59:45 -04:00

.tsrc Language Reference

.tsrc (Tiny Soccer Sim Rust C) is a minimal C-like DSL for scripting soccer matches in tssr. It lets you define teams, assign players, script goals, and control output format — all from a plain text file.

Invocation

Via --script flag

tssr --script match.tsrc              # table output
tssr --script match.tsrc --json       # JSON output

Via shebang

Add this as the first line of your .tsrc file:

#!/usr/bin/env tssr

Then make it executable and run directly:

chmod +x match.tsrc
./match.tsrc

Language Syntax

Team Declaration

string var_name = "Team Name";

Declares a variable that holds a team name. Variables can be referenced later in players[], goal(), and match().

Rules:

  • Variable names must be alphanumeric + underscores
  • Duplicate variable names are an error
  • The string value is the team's display name

Player Assignment

players["Player Name"] = var_name;
players["Player Name"] = "Team Name";

Assigns a player to a team. The right side can be either a previously declared variable or a string literal.

Rules:

  • The team (right side) must resolve to a team that appears in match()
  • The same player cannot be added to the same team twice
  • Variables must be declared before use (forward references are an error)

Scripted Goals

goal(minute, team, player);

Scripts a specific goal event. When any goal() appears, the match score becomes deterministic.

Argument Type Description
minute integer (1-90) Minute the goal was scored
team variable or string The team that scored
player string literal The player who scored

Rules:

  • Minute must be between 1 and 90
  • Team must be one of the two match teams
  • Player must be on that team's roster
  • The same player cannot score at the same minute twice
  • Variables must be declared before use

Match Selection

match(var_home, var_away);

Selects which two teams play. Required — every .tsrc script must contain exactly one match().

Rules:

  • Both variables must be previously declared
  • Home and away must be different teams
  • Both teams must have at least one player assigned

Output Mode Directive

#define JSON
#define ASCII_TABLE
#define UNICODE_TABLE

Sets the output format for the match. Optional — defaults to UNICODE_TABLE.

Rules:

  • Only one #define per script
  • Must be one of the three known modes
  • Unknown names produce an error

The --json CLI flag always overrides the script's #define.

Complete Grammar

script          = statement*
statement       = define | string_decl | player_insert | goal_stmt | match_stmt
define          = "#define" identifier
string_decl     = "string" identifier "=" string_literal ";"
player_insert   = "players" "[" string_literal "]" "=" (identifier | string_literal) ";"
goal_stmt       = "goal" "(" number "," (identifier | string_literal) "," string_literal ")" ";"
match_stmt      = "match" "(" identifier "," identifier ")" ";"
comment         = "//" .* "\n"
shebang         = "#!" .* "\n"

Output Modes

Mode #define CLI flag Description
Unicode table UNICODE_TABLE (default) — Box-drawing characters (╔, ═, ║)
ASCII table ASCII_TABLE — ASCII-only (+, -, `
JSON JSON --json Machine-readable JSON

Scripted Goals Behavior

When goal() is used, the match becomes deterministic:

Field Behavior with goal() Behavior without
Score Count of goals per team Random 0-5
Scorers Exact (player, minute) from script Random names + minutes
Shots max(score, random(4..=18)) — floor = goals Random 4-18
Shots on target max(score, random(1..shots)) Random
Possession Still random Random

Variable Resolution

Variables are resolved at parse time by looking up their declared value:

string home = "GNU United";
string away = "BSD Athletic";

players["Richard Stallman"] = home;        // resolves to "GNU United"
players["Theo de Raadt"] = away;           // resolves to "BSD Athletic"

goal(12, home, "Richard Stallman");        // goal for "GNU United"
goal(34, "BSD Athletic", "Theo de Raadt"); // literal also works

match(home, away);                          // GNU United vs BSD Athletic

You can mix variables and literals freely. Forward references (using a variable before its string declaration) are an error.

Validation

The parser is strict. Any inconsistency produces an error and exits immediately.

Error Conditions

Error Cause
undefined variable 'x' Variable used before string x = ... declaration
variable 'x' redefined Two string x = ... declarations
players[...] = "X" which is not a match team Roster team isn't in match()
duplicate player "X" on team "Y" Same player added to same team twice
"X" has no players assigned A match team has zero players
match() has the same team for both home and away Both match() args resolve to same team
no match() directive found Missing match()
goal() minute must be between 1 and 90 Invalid minute
player "X" is not on team "Y" Goal references unregistered player
duplicate goal Same player scores same minute twice
undefined variable 'x' in goal() Goal uses undeclared team variable
duplicate #define More than one #define in script
unknown #define 'FOO' Unrecognized output mode

Full Example

#!/usr/bin/env tssr

// GNU United vs BSD Athletic
#define ASCII_TABLE

string home = "GNU United";
string away = "BSD Athletic";

players["Richard Stallman"] = home;
players["Brian Fox"] = home;
players["Linus Torvalds"] = home;
players["Theo de Raadt"] = away;
players["Jordan Hubbard"] = away;
players["Ken Thompson"] = away;

goal(12, home, "Richard Stallman");
goal(34, away, "Theo de Raadt");
goal(56, home, "Brian Fox");
goal(78, "BSD Athletic", "Ken Thompson");
goal(89, home, "Linus Torvalds");

match(home, away);

Output:

+------------------------------------+
+         TSSR MATCH RESULT          +
+------------------------------------+
+   GNU United  3-2  BSD Athletic    +
+------------------------------------+
+                                    +
+Shots          4     5              +
+On Target      3     2              +
+Possession   48%   52%              +
+                                    +
+Goals:                              +
+GNU United: Richard Stallman (12')  +
+GNU United: Brian Fox (56')         +
+GNU United: Linus Torvalds (89')    +
+BSD Athletic: Theo de Raadt (34')   +
+BSD Athletic: Ken Thompson (78')    +
+------------------------------------+