Skip to content

Latest commit

 

History

History
143 lines (112 loc) · 7.11 KB

File metadata and controls

143 lines (112 loc) · 7.11 KB

MGEMod — Agent Guide

Project Overview

MGEMod is a 1v1 and 2v2 duel training plugin for Team Fortress 2, built on SourceMod and written in SourcePawn. It creates arena-based duel environments where players fight in realistic game situations (spire, badlands mid, granary last, etc.) with ELO rating, stats tracking, and multiple game modes.

This is a fork of sappho's MGEMod with significant additions: PostgreSQL support, 2v2 mode, per-map arena configs, API forwards/natives, ELO verification, and more.

Current version: 3.1.0-beta14

Architecture

Compilation Unit

mge.sp is the single compilation entry point. It #includes all modules — there are no separately compiled plugins. Compile with:

spcomp -i"./addons/sourcemod/scripting/include/" addons/sourcemod/scripting/mge.sp -o ./addons/sourcemod/plugins/mge.smx

SourcePawn version: 1.12.x (see .github/workflows/build.yml).

Module Layout

addons/sourcemod/scripting/
├── mge.sp                    # Entry point, ConVars, lifecycle hooks
├── mge/
│   ├── globals.sp            # All global state: arrays, handles, enums
│   ├── arenas.sp             # Map config loading, spawn parsing, arena setup
│   ├── player.sp             # Player lifecycle, queue, damage hooks, menus
│   ├── match.sp              # Match flow, frag limits, round end, queue rotation
│   ├── elo.sp                # ELO rating calculations
│   ├── sql.sp                # DB connection, driver detection, queries
│   ├── migrations.sp         # Schema migrations (SQLite/MySQL/PostgreSQL)
│   ├── hud.sp                # HUD text rendering (scores, timers, HP)
│   ├── spectator.sp          # Spectator behavior
│   ├── statistics.sp         # Stats and rank display
│   ├── gamemodes/
│   │   ├── bball.sp          # Basketball mode
│   │   ├── koth.sp           # King of the Hill mode
│   │   ├── 2v2.sp            # 2v2 team mode
│   │   ├── ammomod.sp        # Ammomod mode
│   │   └── endif.sp          # Endif mode
│   └── api/
│       ├── forwards.sp       # Plugin forwards for extension hooks
│       └── natives.sp        # CreateNative API for other plugins
├── include/
│   ├── mge.inc               # Public API: constants, enums, forwards, natives
│   ├── morecolors.inc        # Chat color formatting library
│   └── convar_class.inc      # ConVar helper methodmap

Key Include: mge.inc

The public API header. Contains:

  • Gamemode bitmask constants (MGE_GAMEMODE_MGE, MGE_GAMEMODE_BBALL, etc.)
  • Slot and team constants
  • MGEPlayerStats and MGEArenaInfo enum structs
  • Arena status enum (AS_IDLE through AS_WAITING_READY)
  • All forward and native declarations

Core Concepts

Concept Description
Arena A labeled duel area on a map. Defined per-map in configs/mge/<mapname>.cfg. Max 63 arenas, 15 spawns each.
Gamemode Per-arena mode: mge, bball, koth, ammomod, midair, endif, ultiduo, turris. Stored as bitmask flags.
Slot Player position in an arena (1–4). Slots 1–2 for 1v1, slots 1–4 for 2v2.
Queue Players join arenas via !add or menu. Losers rotate out when queue has waiting players.
Arena Status State machine: IDLE → PRECOUNTDOWN → COUNTDOWN → FIGHT → AFTERFIGHT → REPORTED. Also WAITING_READY for 2v2.
ELO Persistent rating stored in DB. Optional — plugin works without a database.
Frag Limit Score target to win a match. Configurable per-arena.

Data Model

State is managed through parallel global arrays indexed by arena ID and client index (defined in globals.sp). There are no heavy OOP abstractions — this is idiomatic SourcePawn.

Key arrays include per-arena score, spawn points, gamemode flags, KOTH entities, and per-player arena membership, slot assignment, and stats.

Map Configuration Format

Arena definitions live in addons/sourcemod/configs/mge/<mapname>.cfg using KeyValues format:

"SpawnConfigs"
{
    "Arena Display Name"
    {
        "gamemode"              "mge"
        "team_size"             "2v2 1v1"
        "frag_limit"            "20"
        "countdown_seconds"     "3"
        "allowed_classes"       "scout soldier demoman"
        "hp_multiplier"         "1.25"
        "infinite_ammo"         "0"
        "show_hp"               "0"
        "min_spawn_distance"    "350"
        "spawns"
        {
            "red" { ... }
            "blu" { ... }
        }
    }
}

Additional per-arena keys: min_elo, max_elo, airshot_min_height, knockback_boost, visible_hoops, early_leave_threshold, allow_koth_switch, koth_team_spawns, respawn_delay, allow_class_change, koth_round_time.

Coding Conventions

  • #pragma semicolon 1 and #pragma newdecls required — enforced globally.
  • Prefixes: globals use g_ prefix (g_bLate, g_iDefaultFragLimit, g_sMapName). Hungarian-ish notation: b = bool, i = int, s = string/char array, h = Handle.
  • Constants: SCREAMING_SNAKE_CASE (MAXARENAS, SLOT_ONE, MODEL_POINT).
  • Functions: PascalCase for public/stock functions, matching SourceMod conventions.
  • Enums: PascalCase with descriptive prefixes (AS_IDLE, DB_SQLITE).
  • ConVars: created via the Convar methodmap from convar_class.inc.
  • Chat colors: use <morecolors> library (CPrintToChat, etc.).
  • Translations: all user-facing strings go through mgemod.phrases.txt using %t formatting.
  • MAXPLAYERS hack: redefined to 101 at the top of mge.sp for unrestricted player support.

Database

Supports three backends (auto-detected from SourceMod's databases.cfg):

  • SQLite (default, no setup needed)
  • MySQL
  • PostgreSQL (≤9.6 due to SourceMod driver limitations)

Schema is managed through migrations.sp — migrations run automatically on plugin load. The plugin functions without a database (stats/ELO disabled).

Build & Release

  • Local: run spcomp with the include path pointing at addons/sourcemod/scripting/include/.
  • CI: GitHub Actions (.github/workflows/build.yml) triggers on v* tags. Uses rumblefrog/setup-sp with SourcePawn 1.12.x, compiles, downloads large map BSPs, zips into a release artifact.
  • Output: addons/sourcemod/plugins/mge.smx (compiled binary — not committed to repo).

Important Constraints

  • TF2 only: plugin fails to load on non-TF2 engines (Engine_TF2 check in AskPluginLoad2).
  • SourcePawn limitations: no classes/inheritance, limited string handling, fixed-size arrays. Use enum struct for structured data.
  • Include order matters: modules in mge.sp are included in dependency order. Don't rearrange without checking cross-references.
  • No separate compilation: all .sp files under mge/ are #included into mge.sp. They share the global scope.
  • Array bounds: MAXARENAS (63) and MAXSPAWNS (15) are hard limits. Always bounds-check arena/spawn indices.