.agents/skills/amxx-modding-kit/api/rounds/SKILL.md
Guide for Rounds API usage managing round-based gameplay including timing, win conditions, and round events.
npx skillsauth add hedgefog/amxx-modding-kit amxx-modding-kit-api-roundsInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Flexible round management for game modes, supporting both integration with existing round systems (like Counter-Strike) and custom round implementation.
For complete API documentation, see README.md.
For games without native round systems:
public plugin_init() {
Round_UseCustomManager();
}
// Check if round has started
if (Round_IsStarted()) {
// Round is active
}
// Check if round has ended
if (Round_IsEnd()) {
// Round is over
}
// Check if in freeze period
if (Round_IsFreezePeriod()) {
// Players are frozen
}
// Check if waiting for players
if (Round_IsPlayersNeeded()) {
// Not enough players to start
}
// Set round duration in seconds
Round_SetTime(300); // 5 minutes
// Get remaining time
new Float:flRemaining = Round_GetRemainingTime();
client_print(0, print_chat, "Time remaining: %.0f seconds", flRemaining);
// Get round start time
new Float:flStartTime = Round_GetStartTime();
// Get total round time
new Float:flRoundTime = Round_GetTime();
// Get freeze/intro time
new Float:flIntroTime = Round_GetIntroTime();
// Get restart time
new Float:flRestartTime = Round_GetRestartTime();
Declare winning team with delay:
// Team wins after delay
Round_DispatchWin(TEAM_CT, 5.0); // CTs win in 5 seconds
Round_DispatchWin(TEAM_T, 3.0); // Ts win in 3 seconds
End round immediately or with delay:
// Terminate immediately
Round_Terminate(0.0, TEAM_CT);
// Terminate after delay
Round_Terminate(2.0, TEAM_T);
// Draw (no winner)
Round_Terminate(0.0, 0);
Manually trigger win condition check:
Round_CheckWinConditions();
Implement these forwards to react to round events:
public Round_OnInit() {
// Called when new round is initialized
// Good place to reset variables, prepare map
ResetGameState();
}
public Round_OnStart() {
// Called when round starts (after freeze period)
client_print(0, print_chat, "Round started! Fight!");
StartGameplay();
}
public Round_OnEnd(iWinnerTeam) {
// Called when round ends with winning team
switch (iWinnerTeam) {
case TEAM_CT: client_print(0, print_chat, "Counter-Terrorists Win!");
case TEAM_T: client_print(0, print_chat, "Terrorists Win!");
default: client_print(0, print_chat, "Draw!");
}
}
public Round_OnExpired() {
// Called when round timer runs out
client_print(0, print_chat, "Time's up!");
// Handle timeout - e.g., draw or specific team wins
Round_Terminate(0.0, TEAM_CT); // CTs win on timeout
}
public Round_OnRestart() {
// Called when round restarts
ResetAllPlayers();
}
public Round_OnTimerTick() {
// Called every second during round
UpdateTimerDisplay();
}
public Round_OnUpdateTimer(iRemainingTime) {
// Called when timer updates
if (iRemainingTime <= 30) {
client_print(0, print_center, "%d seconds remaining!", iRemainingTime);
}
}
Important: These forwards return Round_CheckResult enum, NOT PLUGIN_* constants.
public Round_CheckResult:Round_OnCanStartCheck() {
new iPlayersNum = 0;
for (new pPlayer = 1; pPlayer <= MaxClients; ++pPlayer) {
if (!is_user_connected(pPlayer)) continue;
if (IsPlayerSpectator(pPlayer)) continue;
iPlayersNum++;
}
// Allow round to start only if players present
return iPlayersNum > 0 ? Round_CheckResult_Continue : Round_CheckResult_Supercede;
}
public Round_CheckResult:Round_OnCheckWinConditions() {
// Block default win condition check
return Round_CheckResult_Supercede;
}
| Value | Description |
|-------|-------------|
| Round_CheckResult_Continue | Allow default behavior |
| Round_CheckResult_Supercede | Block default behavior |
// Check win conditions when player dies
public HamHook_Player_Killed_Post(pPlayer, pKiller, iShouldGib) {
Round_CheckWinConditions();
return HAM_HANDLED;
}
public Round_CheckResult:Round_OnCheckWinConditions() {
// Block default check, handle manually
return Round_CheckResult_Supercede;
}
CheckWinConditions() {
new iSurvivorsAlive = CountPlayersWithRole(ROLE_SURVIVOR);
new iZombiesAlive = CountPlayersWithRole(ROLE_ZOMBIE);
if (iSurvivorsAlive == 0) {
Round_DispatchWin(TEAM_ZOMBIE, 3.0);
} else if (iZombiesAlive == 0) {
Round_DispatchWin(TEAM_SURVIVOR, 3.0);
}
}
public Round_OnStart() {
// Adjust round time based on player count
new iPlayers = GetPlayerCount();
new iRoundTime = 180 + (iPlayers * 15); // Base 3 min + 15 sec per player
Round_SetTime(iRoundTime);
}
public Round_OnExpired() {
if (IsObjectiveIncomplete()) {
// Add overtime
Round_SetTime(60); // 1 minute overtime
client_print(0, print_center, "OVERTIME! 60 seconds added!");
return;
}
// Normal timeout
Round_Terminate(0.0, TEAM_DEFENDER);
}
Round_UseCustomManager() for non-CS gamesRound_OnStart and Round_OnEndRound_OnExpired for timeout logicRound_CheckWinConditions() after relevant eventsRound_DispatchWin for delayed win announcementsRound_Terminate for immediate round endRound_CheckResult from check forwards (not PLUGIN_*)tools
Best practices for organizing large AMX Mod X projects with multiple plugins sharing entities, weapons, events, and other definitions. Use when creating mod-scale projects that need consistent namespace patterns and shared constants.
development
Guide for Waypoint Markers API creating 3D waypoint sprites visible through walls with per-player visibility.
development
Guide for States API usage implementing state machines with transitions, guards, and lifecycle hooks.
development
Guide for Shops API usage creating in-game shops with items, custom balance systems, and access control.