The interaction between the BF2 engine and Python programs is largely event-driven: when an "event" happens in a game, BF2 checks to see if any Python programs have registered to be notified of that particular event; if they have, they are called (a "callback"). One way to think about this: the events are "hooks" into the game engine to which you can attach your own Python code.
Multiple callbacks can be registered for any given event; all registered callbacks will be executed when the event occurs. For example, if three different programs have registered for the "PlayerConnect" event, then when a new player connects, all three of those programs will be run.
Types of Events
The BF2 engine supports five types of events:
These are events that occur during the normal course of game play.
To register to receive a callback for a particular standard event:
host.registerHandler('EventName', pythonEventHandler[, parameter])
This registration will typically be done in the init() method of an object, but could be done anywhere in your code.
Game Status Events
The BF2 engine generates these events when the status of the game changes. You register to receive callbacks for these events with:
The possible states game status can be in (as enumerated in
Game status events are usually used to kick off pre-game initialization or post-game clean-up processing.
"Trigger" events activate when a vehicle comes within a specified distance of an object. Triggers are created and registered for by:
bf2.triggerManager.createHemiSphericalTrigger (object, triggerEventHandler, objectName, radius[, data])
bf2.triggerManager.createRadiusTrigger (object, triggerEventHandler, objectName, radius[, data])
In standard Battlefield 2, trigger events are used to track scoring for flag captures (triggers activate whenever a player enters or leaves a fixed radius around each control point), as well as effects such as birds (birds are triggered to take flight whenever a player enter their trigger radius).
"Timer" events activate when a certain amount of time has elapsed. Timers are created and registered for by:
bf2.Timer(timerEventHandler, delta, alwaysTrigger[, data])
(see the description of the
bf2.Timer class for details).
In standard Battlefield 2, timer events are used to cause periodic status checks related to scoring, ranking, punishing TKs, etc.
Descriptions of Events
EA/DICE have not published a list of events, but here is a list of events that have been discovered so far. The format of this information is
- EventName(handlerParameter1, handlerParameter2, ...)
- Description of event
The "EventName" is the name of the event to register for with
host.registerHandler; the parameters are the parameters your handler should receive when called.
Some notes about some of the arguments used in these descriptions:
- playerObject: An instance of
- playerID: As players connect to the server they are assigned playerID numbers from "1" up.
- squadID: Squads for each side are independently numbered beginning at "1" and increasing thereafter. Players not on a squad, including team commanders, are assigned to squad "0".
- teamID: "0" for US, "1" for China or MEC
- fires when a player connects to the game.
- PlayerSpawn(playerObject, soldierObject)
- Occurs when a player spawns, and associates a playerObject "spirit" with a soldierObject "body".
- PlayerChangeTeams(playerObject, humanHasSpawned)
- HumanHasSpawned is 1 if the player the event is firing for is a human (as opposed to an AI). Does not fire due to team change from "setTeam"!
- PlayerChangeWeapon(playerObject, oldWeaponObject, newWeaponObject)
- Player has changed which weapon they are holding.
- PlayerChangedSquad(playerObject, oldSquadID, newSquadID)
- SquadID is 0 for players who are not members of any squad (including the team commander).
- PlayerScore(playerObject, difference)
- Difference is change to player's score (positive or negative)
- PlayerHealPoint(givingPlayerObject, receivingSoldierObject)
- Occurs whenever a player heals another player; there is no indication of how much health was restored.
- PlayerRepairPoint(givingPlayerObject, receivingVehicleObject)
- Occurs whenever a player repairs a vehicle; there is no indication of how much damage was repaired.
- PlayerGiveAmmoPoint(givingPlayerObject, receivingPhysicalObject)
- Occurs whenever a player replenishes the ammo in another player or vehicle. There is no indication of how much ammo was replenished.
- PlayerTeamDamagePoint(playerObject, victimSoldierObject)
- Occurs whenever a player damages another player on their own team. There is no indication of how much damage was done.
- PlayerKilled(victimPlayerObject, attackerPlayerObject, weaponObject, assists, victimSoldierObject)
- This event occurs when a player is "critically injured", but still capable of being revived. If any players assisted in the kill, then "assists" will be a tuple of tuples: the top-level tuple will contain one lower-level tuple for each assisting player; the lower-level tuples will each have two elements: a playerObject for one of the assisting players, and a number indicating the type of assist (1=targeting assist, 2=kill damage assist, 3=driver assist)
- PlayerRevived(revivedPlayerObject, medicPlayerObject)
- Player has been revived from a "critically injured" condition to full health by a medic using "shock paddles". Players can only be revived in the interval between a PlayerKilled event and a subsequent PlayerDeath event.
- PlayerDeath(playerObject, soldierObject)
- This event occurs when a player is decisively dead, and cannot be revived; they will only return to the game by respawning. SoldierObject is the soldier "body" (which is now discarded) for the playerObject "spirit" (which will persist through the next spawn).
- PlayerBanned(playerObject, time, type)
- Player has been kicked off the server.
- Player has disconnected from the server.
Vehicle and Kit Events
- EnterVehicle(playerObject, vehicleObject[, freeSoldier])
- Player represented by playerObject has entered the vehicle represented by vehicleObject. "freeSoldier" is 1 if the player is a passenger of the vehicle and is able to use weapons/objects of his kit. i.e. seat 4(+) of a black hawk. --Kiff 11:21, 25 January 2006 (MST)
- ExitVehicle(playerObject, vehicleObject)
- Player has exited a vehicle.
- VehicleDestroyed(vehicleObject, attackerObject)
- VehicleObject has been destroyed by attackerObject.
- PickupKit(playerObject, kitObject)
- Player has picked up a kit. This occurs both when a player physically picks up a kit, as well as when a player spawns.
- DropKit(playerObject, kitObject)
- Player has dropped a kit; can occur either because a player has died, or because a player has picked up a different kit.
- ChangedCommander(teamID, oldCommanderPlayerObject, newCommanderPlayerObject)
- Occurs when a team changes commanders; the old or new commander may be "None".
- ChangedSquadLeader(squadID, oldLeaderPlayerObject, newLeaderPlayerObject)
- Occurs when a squad changes squad leaders; the old or new squad leader may be "None".
- ControlPointChangedOwner(controlPointObject, attackingTeamID)
- Event fires when the fixed time limit for a round expires (not sure what "value" is)
- TicketLimitReached(team, limitID)
- ConsoleSendCommand(command, args)
- This event is triggered by someone using the
pythonHost.sendCommandconsole command. Unfortunately, this command/event mechanism appears to be disabled in non-ranked servers. (As a workaround, you can achieve a similar effect by creating and registering your own custom RCon commands).
- RemoteCommand(playerId, cmd)
- Event fires when a game client gives an RCon (remote console) command. Cmd is the command the player gave. This event is used by the admin module to receive and process RCon commands from players; RCon commands from TCP connections are received by the admin module directly, and do not fire this event.
- ClientCommand(command, issuerPlayerObject, args)
- This event occurs when a game client issues certain in-game commands. The only such commands identified so far are: command=100 means player wants to punish teammate for teamkill; command=101 means player wants to forgive. In both cases, args=1. This response is generated by the player responding to an on-screen prompt caused by a call to the
- PlayerUnlocksResponse(succeeded, player, unlocks)
- Unlocks are requested and received asynchronously. This event is triggered when the response for player (which is an object of type Player) are received. If the ranking server did not successfully find the player in question, succeeded is set to false, else true. unlocks is a list of kit ids, which are 11, 22, 33 .. 77.
- ChatMessage(playerId, text, channel, flags)
- Channel is "Squad", "Team", ,"Global", "ServerTeamMessage" or "ServerMessage". Text is the text of the message sent, prefixed by "HUD_TEXT_CHAT_TEAM" or "HUD_TEXT_CHAT_SQUAD" if the message is sent to the Team or Squad channel; there is no prefix if it is sent to the Global channel. PlayerId is -1 for all server messages. If the player sending the message is dead, their message is also prefixed by HUD_CHAT_DEADPREFIX. (Strings such as HUD_TEXT_CHAT_TEAM, HUD_CHAT_DEADPREFIX, and so on, are used as keys by the game engine to match and replace with localized text.)
- PlayerStatsResponse(succeeded, player, response)
- This type of event is registered for with
statusis an integer status code enumerated by
- TriggerEvent(triggerID, object, vehicle, enter, userData)
- This type of event is registered for with
triggerIDis activated when
vehiclecomes within the preset radius of
- This type of event fires when a timer established with
bf2.Timerexpires. "data" is an optional piece of information (of any type) that can be set when the timer is established.
These strings were found in the server executable, and appear to be internal game engine events. They seem to not be accessible from Python, except in a few cases, where there is a correspondence between these "events" and Python events (e.g. "BeginRoundEvent" may be the same as "BeginRound"). For more information, see BF2 Internals.
- EndOfRoundEvent → EndRound
- BeginRoundEvent → BeginRound
- ExitVehicleEvent → ExitVehicle
- EnterVehicleEvent → EnterVehicle
While each event documented here corresponds to a discrete change of game state, there are certain actions that happen in the game that cause a fixed sequence of events to happen every time--a PlayerSpawn event, for example, is always followed by a PlayerChangeWeapon event and a PickupKit event. This section documents some of these recurring patterns.
Player Spawn Pattern
- PlayerSpawn (player becomes associated with a SoldierObject)
- PlayerChangeWeapon (from "None" to a WeaponObject)
Player Killed Pattern
- DropKit (the victim drops their kit)
- ExitVehicle ( if player is inside a vehicle )
Player Revived Pattern
- PlayerScore (for attacker)
- DropKit (victim drops their kit)
- PickupKit (revived player picks up the nearest kit [hopefully, but not necessarily, their old one]; if there is no kit nearby, they default to picking up an "assault" kit)
- PlayerScore (for medic who did the revive)
Flag Change Pattern
- ControlPointChangedOwner (when neutralized)
- PlayerScoreEvent (score for having neutralized flag, repeated for each attacker in CP radius)
- ControlPointChangedOwner (when capture complete)
- PlayerScoreEvent (score for having completed capture, repeated for each attacker in CP radius)
Player Kicked Pattern
Player Banned Pattern
Overall Game State Change Pattern
- StatusChange (to "PreGame")
- Reset (this event doesn't happen in the first round after a server starts)
- StatusChange (to "Playing"; stay here until enough players connect)
- StatusChange (to "PreGame", once enough players have connected)
- StatusChange (to "Playing"--the real game round now begins)
- (play game, beginning with players spawning in)
- StatusChange (to "EndGame")
- DropKit (for each player still in game at end)
Custom Project Reality events
Project Reality overrides the vanilla event system and adds many useful events. See realityevents.py for a full list of custom events.
To add a custom event, add it to the list realityevents.py, and fire it with:
event = realityevents.getEvents( "PlayerSpawn" )
realityevents.sendToHandlers( event, arg1, arg2, arg3.....)