SimArena is a powerful toolkit for creating, configuring, and running simulations with multiple agents in various scenarios. It provides a robust foundation for AI research and development, with support for custom objectives, brains, weapons, and maps.
The Map Analysis System is designed to be easily extended to track other events on the map and provide analysis tools for those events as well.
This guide will walk you through the process of creating a custom map analyzer for tracking and analyzing custom events on the map.
To create a custom analyzer, implement the IMapAnalysis<TData>
interface. The TData
type represents the
type of data you want to track.
public class CustomAnalysis : IMapAnalysis<CustomData>
{
// Implement interface methods
public override string AnalysisType => "Custom";
}
The CustomData
type should implement the IPositionalData
interface to provide position and timestamp information.
public class CustomData : IPositionalData
{
public int X { get; set; }
public int Y { get; set; }
public DateTime Timestamp { get; set; }
public int Step { get; set; }
}
To have your custom analyzer automatically created and initialized when a simulation starts, register it with the Simulation
class.
public class MySimulation : Simulation
{
public MySimulation()
{
// Register the custom analyzer
if (Map != null)
{
var customAnalysis = new CustomAnalysis();
customAnalysis.Initialize(Map.Width, Map.Height);
MapAnalyzers.Add(customAnalysis);
// Subscribe to relevant events
// For example: (CustomEvent does not exist)
Events.CustomEvent += OnCustomEvent;
}
}
private void OnCustomEvent(object sender, CustomEventArgs e)
{
var customAnalysis = GetMapAnalyzer<CustomAnalysis>();
if (customAnalysis != null)
{
var customData = new CustomData { X = e.X, Y = e.Y, Timestamp = DateTime.Now, Step = CurrentStep };
customAnalysis.RecordData(customData);
}
}
}
You can access your custom analyzer in the same way as the built-in analyzers.
var customAnalysis = simulation.GetMapAnalyzer<CustomAnalysis>();
or by overriding the AnalysisType
property and giving it a unique name:
var customAnalysis = simulation.GetMapAnalyzer("Custom");
Let’s say you want to track where agents have been sighted on the map.
public class SightingData : IPositionalData
{
public int X { get; set; }
public int Y { get; set; }
public DateTime Timestamp { get; set; }
public int Step { get; set; }
public string AgentName { get; set; }
}
public class SightingAnalysis : IMapAnalysis<SightingData>
{
// Implement interface methods
public override string AnalysisType => "Sightings";
}
Register it with the simulation:
public class MySimulation : Simulation
{
public MySimulation()
{
// Register the sighting analyzer
if (Map != null)
{
var sightingAnalysis = new SightingAnalysis();
sightingAnalysis.Initialize(Map.Width, Map.Height);
MapAnalyzers.Add(sightingAnalysis);
// Subscribe to relevant events
// For example: (OnAgentSighted does not exist)
Events.OnAgentSighted += OnAgentSighted;
}
}
private void OnAgentSighted(object sender, AgentSightedEventArgs e)
{
var sightingAnalysis = GetMapAnalyzer<SightingAnalysis>();
if (sightingAnalysis != null)
{
var sightingData = new SightingData { X = e.X, Y = e.Y, Timestamp = DateTime.Now, Step = CurrentStep, AgentName = e.AgentName };
sightingAnalysis.RecordData(sightingData);
}
}
}
And access it in your code:
var sightingAnalysis = simulation.GetMapAnalyzer<SightingAnalysis>();