.tsrc (Tiny Soccer Sim Rust C) language.
- Rust 100%
| .cargo | ||
| docs | ||
| src | ||
| tests | ||
| .gitignore | ||
| .rustfmt.toml | ||
| Cargo.lock | ||
| Cargo.toml | ||
| defines-test-match.tsrc | ||
| gnu-bsd-soccer.tsrc | ||
| LICENSE | ||
| README.md | ||
| scripted_match.tsrc | ||
| situation-demo.tsrc | ||
| STYLE.md | ||
| test_match.tsrc | ||
tssr — Tiny Soccer Simulator Rust
A blazing-fast CLI that generates completely random soccer matches on the spot — or run scripted matches with the .tsrc (Tiny Soccer Sim Rust C) language.
Author
Mark Robillard Jr (MARKMENTAL)
Build
cargo build --release
The binary will be at target/release/tssr.
Usage
./tssr # random match (Unicode table)
./tssr --json # random match (JSON)
./tssr --script match.tsrc # scripted match (table)
./tssr --script match.tsrc --json # scripted match (JSON)
./tssr --help # show usage info
Shebang
#!/usr/bin/env tssr
string home = "Team A";
string away = "Team B";
match(home, away);
chmod +x match.tsrc
./match.tsrc
Output Modes
| Mode | How to enable |
|---|---|
| Unicode table | Default (no flag, no #define) |
| ASCII table | #define ASCII_TABLE in script |
| JSON | --json CLI flag or #define JSON in script |
The --json CLI flag always takes priority over #define.
Unicode table (default)
╔════════════════════════════════════════╗
║ TSSR MATCH RESULT ║
╠════════════════════════════════════════╣
║ Man Page City 2 - 1 Libre Pool║
╠════════════════════════════════════════╣
║ ║
║ Shots 10 8 ║
║ On Target 4 3 ║
║ Possession 55% 45% ║
║ ║
╠════════════════════════════════════════╣
║ Goals: ║
║ Man Page City: Marco Smith (23') ║
║ Libre Pool: Dan Garcia (45') ║
╚════════════════════════════════════════╝
ASCII table (#define ASCII_TABLE)
+--------------------------------------------+
| TSSR MATCH RESULT |
+--------------------------------------------+
| Man Page City 2 - 1 Libre Pool |
+--------------------------------------------+
| |
| Shots 10 8 |
| On Target 4 3 |
| Possession 55% 45% |
+--------------------------------------------+
JSON (--json or #define JSON)
{
"home": {
"team": "Man Page City",
"score": 2,
"shots": 10,
"shots_on_target": 4,
"possession": 55,
"scorers": [
{"player": "Marco Smith", "minute": 23}
]
},
"away": {
"team": "Libre Pool",
"score": 1,
"shots": 8,
"shots_on_target": 3,
"possession": 45,
"scorers": [
{"player": "Dan Garcia", "minute": 45}
]
}
}
Scripting with .tsrc
.tsrc (Tiny Soccer Sim Rust C) is a minimal C-like DSL for defining teams, players, goals, and output mode.
Quick example
#!/usr/bin/env tssr
#define ASCII_TABLE
string home = "GNU United";
string away = "BSD Athletic";
players["Richard Stallman"] = home;
players["Brian Fox"] = home;
players["Theo de Raadt"] = away;
goal(12, home, "Richard Stallman");
goal(34, away, "Theo de Raadt");
goal(78, "BSD Athletic", "Theo de Raadt");
match(home, away);
Language syntax
| Statement | Purpose |
|---|---|
string var = "Team"; |
Declare a team variable |
players["Player"] = var; |
Assign player to team (variable or literal) |
goal(min, team, "Player"); |
Script a goal at a specific minute |
match(home, away); |
Select teams for the match (required) |
#define JSON / ASCII_TABLE / UNICODE_TABLE |
Set output mode |
When goal() is used, the score becomes deterministic — goals, minutes, and scorers are exact. Shots are floored at the goal count. Without goal(), everything is fully randomized.
The parser is strict: any inconsistency produces a clear error and exits immediately.
See docs/tsrc-language/README.md for the full language reference.
Formatting
This project uses a custom style (Anti-GNU, Anti-1TBS) — see STYLE.md. rustfmt is disabled.
A custom formatter binary is provided:
cargo fmt-tssr # format all .rs files in src/ and tests/
cargo fmt-tssr path/to/file.rs # format a specific file
cargo fmt-tssr src/ dir/ # format specific directories
Testing
cargo test
19 integration tests covering:
- Goal validation (player on team, minute range, duplicates, undefined variables)
- Script validation (undefined variables, same team, missing match, no players, duplicate variables)
#definedirective (all modes, duplicate, unknown)- Happy paths (valid scripts, variable references, full scripted match)
Documentation
| Document | Description |
|---|---|
docs/tsrc-language/README.md |
Full .tsrc language reference, grammar, validation rules |
docs/engine/README.md |
Engine internals: random generation, scripted override, output formatting |
Performance
- Single runtime dependency (
rand) - Release profile uses LTO, single codegen unit, panic=abort, symbol stripping
- Sub-second cold compilation
- Binary size: ~340KB stripped
License
This project is licensed under the GNU General Public License v3.0 — see LICENSE.