Skip to content

Adding a Simulator

To add support for a new simulator, implement IGameLiveSampler and register it.


Step 1: Implement IGameLiveSampler

Create a new class in SimCopilot.Connectors/:

public class MySimSampler : IGameLiveSampler
{
    public string GameSourceId => "MySim";
    public bool IsConnected { get; private set; }

    public Task<bool> ConnectAsync()
    {
        // Open shared memory / UDP socket / etc.
        IsConnected = true;
        return Task.FromResult(true);
    }

    public Task DisconnectAsync()
    {
        IsConnected = false;
        return Task.CompletedTask;
    }

    public bool TryPeekLive(out GameLiveSample sample)
    {
        // Read latest telemetry snapshot without blocking.
        // Return false if no data available.
        sample = default;
        return false;
    }
}

Step 2: Add a GameSourceId enum value

In SimCopilot.Core/GameSourceId.cs, add your simulator:

public enum GameSourceId
{
    // ... existing values ...
    MySim,
}

Step 3: Register in ConnectorCatalog

In SimCopilot.Connectors/ConnectorCatalog.cs, add an entry:

new ConnectorInfo
{
    GameSourceId = GameSourceId.MySim,
    DisplayName  = "My Simulator",
    Status       = ConnectorStatus.Beta,
    Protocol     = "UDP",  // or "SHM" or whatever
}

Step 4: Register in GameSamplerFactory

In SimCopilot.Connectors/GameSamplerFactory.cs, add a case:

GameSourceId.MySim => new MySimSampler(settings),

Step 5: Wire into LiveCaptureService

If your sampler uses the generic polling loop (most simulators except LMU), GenericLiveRecorder handles it automatically via GameSamplerFactory. No changes needed in LiveCaptureService unless you need custom session lifecycle logic.


Step 6: Add French UI string

In SimCopilot.App/I18n.cs, add a display name string for the connector:

public static string GameSourceMySim => "Mon Simulateur";

Validation

Test that the sampler: 1. Returns IsConnected = true after ConnectAsync() when the simulator is running 2. Returns IsConnected = false and does not throw after DisconnectAsync() 3. Returns telemetry points with non-zero Distance and Speed during an active session 4. The completed lap appears in the session library after the session ends