| name | sae-snippets |
| description | SAE UTP module snippet operations: listing available snippets, parsing the GetAllAvailableSnippets response, activating and starting snippets by path, and uploading snippet XML files. Use when working with SAE snippets, calling GetAllAvailableSnippetsAsync, parsing snippet lists, activating snippets by path, or verifying a snippet was uploaded. CRITICAL: the response is a JsonArray of JsonObject group entries, each with a "Snippets" property containing a JsonArray of plain string paths — NOT a flat list of strings or objects with a "Name" property. stages: test-implementation, test-validation |
SAE Snippets
When to Use
- Listing all available snippets on the EGM
- Parsing the
GetAllAvailableSnippets UTP response
- Activating a snippet by path and starting it
- Uploading snippet XML files before activation
- Verifying a snippet was successfully uploaded
CRITICAL: Response Shape of GetAllAvailableSnippets
The GetAllAvailableSnippets UTP command returns a JsonNode that is a JsonArray.
Each element of the outer array is a JsonObject representing a snippet group. Each group object has a "Snippets" property containing a JsonArray of plain string values — those strings are the snippet paths to pass to ActivateSnippetByPath.
JsonArray ← outer array (groups)
└─ JsonObject { "Snippets": … } ← one entry per group
└─ JsonArray ← the snippet paths
└─ "Type.Category.Name" ← plain string path
Correct Parsing Pattern (matches SnippetController)
private const string SnippetsProperty = "Snippets";
var allPaths = new List<string>();
if (rawSnippets is JsonArray jsonArray)
{
foreach (var entry in jsonArray)
{
if (entry?[SnippetsProperty] is JsonArray snippetArray)
{
allPaths.AddRange(
snippetArray
.Select(s => s?.ToString())
.Where(s => !string.IsNullOrEmpty(s))
.Cast<string>());
}
}
}
Common Mistakes
| Mistake | Why It Fails |
|---|
Treating the outer node as a JsonObject and accessing ["Snippets"] directly | The outer node is a JsonArray, not an object — InvalidOperationException: The node must be of type 'JsonObject' |
Calling GetValue<string>() on each outer element | Outer elements are JsonObject, not JsonValue — same exception |
Accessing elementObj["Name"] or elementObj["Path"] | Snippet groups have a "Snippets" property, not "Name" or "Path" |
Using node.ToString() to extract a snippet path | Serializes to JSON with quotes — produces an invalid path like "Type.Category.Name" (with quotes), causing Path could not be parsed! from UTP |
Component Reference
| Component | Location | Purpose |
|---|
SaeFacade | Shared/Facades/SaeFacade.cs | Wraps all SAE UTP commands |
SnippetController | Shared/Controllers/Game/SnippetController.cs | Upload/activate/start snippets; contains the authoritative parsing logic |
SnippetXmlParser | (Utilities) | Extracts snippet name from XML file |
Available SAE Commands (via SaeFacade)
| Method | UTP Command | Notes |
|---|
GetAllAvailableSnippetsAsync() | GetAllAvailableSnippets | Returns JsonNode — parse as described above |
ActivateSnippetByPathAsync(path, instanceId) | ActivateSnippetByPath | Path format: Type.Category.SnippetName; instanceId defaults to 0 |
StartActivatedSnippetsAsync() | StartActivatedSnippets | Call after activating |
UploadSnippetsAsync(xmlContent) | UploadSnippets | Upload raw XML string |
ClearSnippetsAsync() | ClearSnippets | Clears all snippets |
AutoClearSelectedSnippetsAsync(bool) | AutoClearSelectedSnippets | Enable/disable auto-clear at sim end |
Preferred: Use SnippetController
For typical upload-activate-start flows, prefer SnippetController over calling SaeFacade directly:
await snippetController.UploadActivateAndStartSnippetAsync(filePath, instanceId: 0, cancellationToken);
await snippetController.ActivateAndStartSnippetByNameAsync(snippetName, instanceId: 0, cancellationToken);
SnippetController handles the parsing and validation internally.
Snippet Path Format
Snippet paths follow the pattern Type.Category.SnippetName, e.g.:
Simulation.BaseGame.WildSpin
Automation.FreeGame.AllWildReels
These exact strings are what GetAllAvailableSnippets returns inside the "Snippets" arrays, and what ActivateSnippetByPath expects as input.