Zone Drawing Callbacks#

Zone drawing callbacks allow you to draw custom zones, shapes, and labels on the map. This works with all map mods that integrate with MapDrawer.

Important: Zone drawing callbacks are only for drawing visual elements on the map. They do NOT provide zone-related functionality like zone entry/exit events, player state changes, or exit timers. For those features, use the server-side callbacks (ZoneEventCallback, PlayerStateChangeCallback, ExitTimerCallback) registered in MissionServer.OnInit().

Interface#

class ZoneDrawingCallback
{
    // Called before zones are drawn - mods can draw their own zones here
    // @param mapDrawer - The MapDrawer instance providing access to drawing methods
    // @param zones - Array of all zones that will be drawn
    void OnBeforeZonesDrawn(MapDrawer mapDrawer, array zones) {}
    
    // Called after zones are drawn - mods can draw overlays or additional content here
    // @param mapDrawer - The MapDrawer instance providing access to drawing methods
    // @param zones - Array of all zones that were drawn
    void OnAfterZonesDrawn(MapDrawer mapDrawer, array zones) {}
}

Drawing Methods#

The MapDrawer instance provides the following methods:

DrawCircle#

void DrawCircle(
    vector pos,              // World position (center of circle)
    float radius,            // Radius in meters
    int color,              // ARGB color (e.g., ARGB(255, 255, 0, 0) for red)
    bool drawStrike = false, // Whether to draw strike lines
    bool hideWhenNested = true, // Whether to hide when nested in other zones
    int priority = 1        // Drawing priority (higher = drawn on top)
)

DrawPolygon#

void DrawPolygon(
    array vertices,  // Array of world positions forming the polygon
    int color,              // ARGB color
    bool drawStrike = false, // Whether to draw strike lines
    bool hideWhenNested = true, // Whether to hide when nested in other zones
    int priority = 1        // Drawing priority (higher = drawn on top)
)

DrawLabel#

void DrawLabel(
    vector worldPos,        // World position where to draw the label
    string label,           // Text to display
    int color,              // ARGB color
    float offsetYPixels = 0, // Vertical offset in pixels (optional)
    vector customOffsetMeters = "0 0 0" // Custom offset in meters (optional)
)

Registration#

Client-side only (map drawing happens on client):

You can register drawing callbacks in MissionGameplay.OnInit() or in your map menu's Init() method.

Note: If you're integrating with a custom map menu (unsupported map mod), use the map menu example below instead of MissionGameplay.OnInit(). This ensures the callback is registered when your specific map menu initializes.

Option 1: Register in MissionGameplay.OnInit()#

(Recommended for supported map mods)

// In your mod's MissionGameplay.c file
modded class MissionGameplay
{
    override void OnInit()
    {
        super.OnInit();
        
        // Register drawing callback on client side
        MyDrawingCallback myCallback = new MyDrawingCallback();
        MapDrawer.RegisterZoneDrawingCallback(myCallback);
        
        Print("[MyMod] Drawing callback registered successfully.");
    }
}

// Define your callback class
class MyDrawingCallback : ZoneDrawingCallback
{
    override void OnBeforeZonesDrawn(MapDrawer mapDrawer, array zones)
    {
        if (!mapDrawer || !zones)
            return;
        
        // Draw your custom zones before default zones
        // Example: Draw a custom circle
        vector customPos = "5000 0 5000";
        float radius = 300.0;
        int color = ARGB(255, 0, 255, 0); // Green
        mapDrawer.DrawCircle(customPos, radius, color, false, false, 5);
    }
    
    override void OnAfterZonesDrawn(MapDrawer mapDrawer, array zones)
    {
        if (!mapDrawer || !zones)
            return;
        
        // Draw overlays or additional content after default zones
        // Example: Draw a label
        vector labelPos = "5000 0 5000";
        mapDrawer.DrawLabel(labelPos, "My Custom Zone", ARGB(255, 255, 255, 255));
    }
}

Option 2: Register in your map menu's Init() method#

(Required for custom/unsupported map mods)

If you're integrating with a custom map menu that isn't natively supported, register the callback in your map menu's Init() method. This ensures the callback is available when your specific map menu is used:

// In your map menu modded class (e.g., MapMenu, ExpansionMapMenu, MyCustomMapMenu, etc.)
modded class MyCustomMapMenu  // Replace with your map menu class name
{
    override Widget Init()  // Or OnInit(), or whatever initialization method exists
    {
        super.Init();
        
        // Register drawing callback
        MyDrawingCallback myCallback = new MyDrawingCallback();
        MapDrawer.RegisterZoneDrawingCallback(myCallback);
        
        Print("[MyMod] Drawing callback registered for custom map menu.");
        
        return layoutRoot;
    }
}

When to use each option:

Color Format#

Colors use ARGB format: ARGB(alpha, red, green, blue)

Examples:

Use Cases#