This page covers how events are defined, emitted, and consumed in go-dota2. There are two parallel event mechanisms: direct GC events (protobuf messages from the GC delivered via the go-steam event bus) and SOCache events (shared-object lifecycle events delivered via typed Go channels). For details on the SOCache itself, see SOCache System (2.1) For how GC packets are dispatched to produce these events, see Communication Flow (2.3)
When the Dota 2 Game Coordinator sends an unsolicited message to the client, go-dota2 converts it into a typed event value and broadcasts it. Consumers receive these events by listening on the go-steam event bus or by subscribing to a SOCache container channel.
| Mechanism | Source | Delivery | Package |
|---|---|---|---|
| Direct GC event | GC protobuf message | go-steam Emit / event bus | events/ |
| SOCache event | GC shared-object update | Buffered chan *CacheEvent | socache/ |
| Session event | Client state transition | go-steam Emit / event bus | events/ |
Event InterfaceEvery direct GC event implements the Event interface defined in events/event.go9-16:
| Method | Return type | Purpose |
|---|---|---|
GetDotaEventMsgID() | protocol.EDOTAGCMsg | The GC message ID that triggers this event |
GetEventBody() | proto.Message | The embedded protobuf message, used as the unmarshal target |
GetEventName() | string | Human-readable event name |
Each generated event struct embeds its corresponding protocol message directly. For example, AccountGuildEventDataUpdated embeds protocol.CMsgGCToClientAccountGuildEventDataUpdated events/generated.go10-12
events/generated.go)The file events/generated.go is produced by the apigen tool. It contains one struct per GC-to-client message classified by the generator as an event. The generator creates thousands of lines of boilerplate to wrap protobuf messages into the Event interface. Examples:
| Event struct | Embedded proto | GC message ID |
|---|---|---|
AccountGuildEventDataUpdated | CMsgGCToClientAccountGuildEventDataUpdated | k_EMsgGCToClientAccountGuildEventDataUpdated |
ActiveGuildChallengeUpdated | CMsgGCToClientActiveGuildChallengeUpdated | k_EMsgGCToClientActiveGuildChallengeUpdated |
BroadcastNotification | CMsgDOTABroadcastNotification | k_EMsgGCBroadcastNotification |
CandyShopUserDataUpdated | CMsgGCToClientCandyShopUserDataUpdated | k_EMsgGCToClientCandyShopUserDataUpdated |
Sources: events/generated.go8-27 events/generated.go155-174 events/generated.go177-195 events/event.go9-16
Several events are defined manually in the events package to handle common chat, invitation, or session transitions that require specific naming or logic:
| Event struct | Trigger / Purpose | File Reference |
|---|---|---|
ChatMessage | k_EMsgGCChatMessage received | events/chat.go9-27 |
JoinedChatChannel | k_EMsgGCJoinChatChannelResponse received | events/chat.go29-46 |
InvitationCreated | k_EMsgGCInvitationCreated received | events/invite.go9-26 |
GCConnectionStatusChanged | GC connection state update | events/session.go9-16 |
ClientWelcomed | Received CMsgClientWelcome | events/session.go19-22 |
ClientStateChanged | Internal Dota2State transition | events/state.go8-13 |
UnhandledGCPacket | Emitted when a packet has no handler | events/session.go25-28 |
Diagram: Direct GC Event — Packet to Consumer
Sources: events/event.go9-16 events/chat.go14-16 events/generated.go15-17 events/session.go25-28
Diagram: Code Entities in the Direct Event System
Sources: events/event.go9-16 events/generated.go10-12 events/chat.go9-11 events/invite.go9-11 events/session.go9-16
SOCache events notify consumers when a shared object (lobby, party, etc.) is created, updated, or destroyed in the cache. These are separate from the main Steam event bus and are handled by specialized cache handlers in the client client_cache.go17-70
The client implements specific handlers to process SOCache packets and update the local cache state. These are triggered by the following message types:
handleCacheSubscribed: Handles CMsgSOCacheSubscribed client_cache.go17-28handleCacheUnsubscribed: Handles CMsgSOCacheUnsubscribed client_cache.go30-42handleCacheUpdateMultiple: Handles CMsgSOMultipleObjects client_cache.go44-56handleCacheDestroy: Handles CMsgSOSingleObject client_cache.go58-70Applications can also trigger cache-related events by requesting refreshes. For example, RequestCacheSubscriptionRefresh sends a CMsgSOCacheSubscriptionRefresh to the GC client_cache.go10-14
| Property | Direct GC Events | SOCache Events |
|---|---|---|
| Trigger | Specific EDOTAGCMsg | Shared Object lifecycle change |
| Delivery | go-steam event bus | chan *CacheEvent |
| Implementation | Struct embedding Protobuf | Wrapper struct with proto.Message |
| Package | github.com/paralin/go-dota2/events | github.com/paralin/go-dota2/socache |
| Example | ChatMessage events/chat.go9 | Lobby update |
The event system relies on apigen logic and specific overrides in apigen/msg_overrides.go to distinguish between events and request responses.
msgSenderOverrides to determine if a message is sent by the Client, the GC, or neither. Messages marked as MsgSenderGC (e.g., EDOTAGCMsg_k_EMsgGCOtherJoinedChannel) are primary candidates for the Event system apigen/msg_overrides.go21-22msgMethodNameOverrides. For instance, k_EMsgGCReadyUp is renamed to SendReadyUp apigen/msg_overrides.go126-129msgResponseOverrides apigen/msg_overrides.go148-154 ensuring that responses are treated as completions for requests (via MakeRequest) rather than unsolicited events.Sources: apigen/msg_overrides.go10-154 events/generated.go1-15 client_cache.go17-70 events/session.go1-29
Refresh this wiki