Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/0x-unkwn0wn/simterm/llms.txt

Use this file to discover all available pages before exploring further.

simterm-engine is the reusable library at the heart of Simterm. It owns the immutable campaign data model, the mutable game-state runtime, the campaign loader, the semantic validator, and the asset-source abstraction — with no dependency on ratatui, crossterm, or any other UI library. Any Rust binary can pull it in and drive a full campaign loop without touching the terminal frontend.

When to use the library directly

If you are authoring a campaign in RON files and playing it through the standard simterm CLI, you do not need to depend on simterm-engine directly — the frontend already does that for you. Use simterm-engine directly when you want to:
  • Build an alternative frontend (web, headless server, embedded TUI)
  • Write integration tests that drive a campaign programmatically
  • Build tooling such as a campaign linter or validator
  • Embed the game loop in a larger application

Adding the dependency

[dependencies]
simterm-engine = { path = "../engine" }  # workspace

Minimal usage example

The following snippet — drawn from the crate’s own rustdoc — is the smallest possible headless session: load a campaign from disk, construct a GameState, and call the first action.
use simterm_engine::{load_campaign, GameState, actions};

let campaign = load_campaign("examples/sample_campaign").expect("valid campaign");
let mut game = GameState::new(campaign);
actions::recon(&mut game);
From here you can inspect game.intel, call actions::enumerate, actions::exploit, and so on to drive the full recon → enum → exploit → post loop.

Public re-exports

Everything the library exposes is re-exported from the crate root so you only need one use simterm_engine::… import. The exports are grouped below by layer.

Model types

These are the immutable definition types loaded from a campaign’s RON files. Once a Campaign is loaded they never change.
TypeDescription
CampaignRoot value: missions, theme, easter eggs, achievements, declarative commands
CampaignAchievementA data-driven achievement with an id, title, and trigger
CampaignAchievementTriggerEnum of unlock conditions (ReadFile, CompleteMission, ChooseEnding, CampaignComplete)
MissionSingle level definition: target, entry vector, detection limit, endings
EntryVectorHow a mission starts (Active, Cold, Passive, Pivot)
EndingA branching ending option displayed at mission close
NetHostA host inside a multi-host internal network
TargetNodeA compromisable host: services, vulnerabilities, VFS, token gating
ServiceA port/name/version entry on a target
VulnerabilityA hidden exploitable flaw attached to a service port
FsNodeA node in the virtual filesystem (Dir or File)
LootMechanical reward tied to reading a file (skill bonus, credential, token)
ThemeBranding and cosmetic text overrides for the campaign
EasterEggA flavor-only hidden command defined in campaign data
LanguageNarrative language selection (Es or En)
EngineTextLocalized string accessor obtained from Language::text(); provides all engine-generated UI strings
EnumToolStatic definition of an enumeration tool (name, affinities, noise, hit rates)
ServiceCatService category inferred from a service name (Web, Smb, Ssh, Db, Other)
IntelFindingA discovered finding in the intel list
FindingSourceHow a finding was produced (PortScan, DeepScan, Guess)
FindingStatusCurrent state of a finding (Unverified, VerifiedTrue, VerifiedFalse, Failed, Exploited)

Command types

Declarative commands are defined entirely in campaign data and dispatched by the runtime without any Rust code in the campaign.
TypeDescription
CampaignCommandA data-driven command with triggers, output lines, effects, and conditions
CommandEffectWhat a command does: AddLog, SetFlag, ClearFlag, AddTrace, UnlockAchievement, CompleteMission
CommandConditionWhen a command is available: FlagSet, FlagNotSet, Mission, Phase
TerminalCommandAn authored realistic shell command (presentational, no game-state effect)

Runtime

SymbolDescription
actionsModule of all player action functions (recon, enumerate, exploit, …)
GameStateThe full mutable session state created with GameState::new(campaign)
PhaseKill-chain phase enum: Recon, Enum, Exploit, Post
GameOutcomeTerminal game result: Victory or Defeat
AchievementIdBuilt-in engine achievement enum
ACHIEVEMENTSStatic slice of all built-in AchievementId values
ShellOutputReturn value from sysemu::run: output lines plus an exit code

Loader

SymbolDescription
load_campaignLoad a Campaign from a directory or .ron file path
load_open_campaignLoad a Campaign together with its AssetSource
LoadErrorError variants: NotFound, Parse, Empty
OpenCampaignStruct pairing a Campaign with a Box<dyn AssetSource>

Validation

SymbolDescription
validate_campaignPure semantic validation returning a ValidationReport
ValidationIssueA single issue with a location string and a message
ValidationReportContainer for errors and warnings vectors

Assets

TypeDescription
AssetSourceTrait: read(path) -> io::Result<Vec<u8>>
DirAssetSourceReads assets from a real directory on disk
MemAssetSourceHolds assets in a HashMap<String, Vec<u8>> (useful in tests)
NoAssetsRejects all reads; use when audio and binary assets are not needed

Engine / frontend boundary

simterm-engine never imports ratatui, crossterm, or any audio library. All presentation decisions — terminal rendering, input handling, help text, audio playback — belong to the frontend. The engine owns every state transition: phase advances, trace accumulation, detection checks, loot application, achievement unlocking, and mission completion. When building a custom frontend you pass the verb string to actions::campaign_command and call individual actions::* functions. The engine mutates GameState and appends to game.logs; your frontend reads those logs and renders them however it chooses.

Data Model

All campaign types and their fields

Runtime

GameState, Phase, and every action function

Validation API

validate_campaign and the ValidationReport

Build docs developers (and LLMs) love