(the context for below is as part of gg.bayes.model.message for the live-data-message model)
All messages transmitted have a generic format called LiveDataMessage
.
Note: These code samples are frequently updated based on the most recent releases.
In case of any further questions, please reach out to us support@bayesesports.com
When receiving live-data through BEDEX, messages will be wrapped inside a BayesMessageEnvelope
, which itself will be wrapped inside a DataProviderMessage
:
{
"type" : "object",
"id" : "urn:jsonschema:gg:bayes:bedex:model:transports:DataProviderMessage",
"properties" : {
"path": {"type": "string"},
"seqIdx": {"type": "number"},
"timeSent": {"type": "string", "format": "date-time"},
"payload": {"type": "object"},
"version": {"type": "string"}
}
}
The path
property identifies the stream to which a message belongs, for example a path could be esports/lol/riot/lcs/123456789
.
seqIdx
is a sequence index - a strictly increasing number relative to that stream, starting at 1.
The payload
will contain a BayesMessageEnvelope
.
After unwrapping the DataProviderMessage
and BayesMessageEnvelope
, a LiveDataMessage
is obtained.
This allows you to easily (and early on in your processing) identify key information such as:
createdAt
: When we created the messageliveDataMatchUrn
: A unique ID for the live match we generatetitle
: The game title (for example, Dota 2)type
: The type of message (see below)subject
: The subject of the message (see below)action
: The action within the message (see below)payload
: The actual message payload which is title-specific.additionalProperties
: Extra information about the match we may append such as gameState
, esportsGameId
.Types, Subjects, and Actions
This is the paradigm we use for messages in an attempt to be game-agnostic (which means integrating multiple games becomes easier to understand and implement over time).
All message payloads are specific to the given title
.
Let’s start with subject first - it’s simply the entity (a noun) that the message is about: a player, a team, or an entire match (a match might include information about players & teams bundled in).
If subjects are the nouns within our system, then actions are the verbs: these are the operations which we the messages are describing.
Finally, types group/define actions into categories to simplify message understanding, so each of the following types also has the possible verbs for that type.
Below shows the possible hierarchies for messages. First there is a list of each message type, all valid subjects for that type, all valid actions for that subject, and then a mapping to the underlying Java POJO which can deserialize the message payload.
An example deserializer for java is available via live-data-message-model-simple
, which does not include handling of the wrappers at the moment, but it can give you and idea of how to implement it:
final String messagePayloadString = recv(); // receive the message from somewhere
// create the handler
final LiveDataMessageHandlerSimple handler = LiveDataMessageHandlerSimple
.<BayesMessageEnvelope>builder()
.objectMapper(objectMapper)
.lolHandler(matchId -> new MyLolHandler(matchId))
.csgoHandler(matchId -> new MyCsgoHandler(matchId))
.envelopeClass(BayesMessageEnvelope.class)
.build();
// then use it to process events contained in received messages:
handler.handleMessage(messagePayloadString);
INFO
INFO
messages are general match-specific bits of information which describe metdata about the match. They are very infrequently updated after the match begins, and rarely edited (already set field being changed to another value). Examples within info messages could be a match URN, a list of participants.
CONTROL
message communicate general information on the match data status, such as timeouts and recovery.
subject | action | lol-payload | csgo-payload |
---|---|---|---|
MATCH | ANNOUNCE | gg.bayes.model.message.event.lol.MatchInfoEvent | gg.bayes.model.message.event.csgo.MatchInfoEvent |
MATCH | UPDATE | gg.bayes.model.message.event.lol.MatchInfoEvent | gg.bayes.model.message.event.csgo.MatchInfoEvent |
MATCH | ROLLBACK | gg.bayes.model.message.event.lol.ChronobreakEvent | gg.bayes.model.message.event.csgo.RoundRollbackEvent |
CONTROL | ANNOUNCE | gg.bayes.model.message.control.ControlAnnounceEvent | gg.bayes.model.message.control.ControlAnnounceEvent |
CONTROL | ERROR | gg.bayes.model.message.control.ControlErrorEvent | gg.bayes.model.message.control.ControlErrorEvent |
GAME_EVENT
GAME_EVENT
messages fire immediately after key ingame events happen (a kill, a building was destroyed).
subject | action | lol-payload | csgo-payload |
---|---|---|---|
MATCH | START_MAP | gg.bayes.model.message.event.lol.MapEvent | gg.bayes.model.message.event.csgo.MapEvent |
MATCH | END_MAP | gg.bayes.model.message.event.lol.MapEndEvent | gg.bayes.model.message.event.csgo.MapEndEvent |
MATCH | START_PAUSE | gg.bayes.model.message.event.lol.GameEvent | gg.bayes.model.message.event.csgo.RoundPauseEvent |
MATCH | END_PAUSE | gg.bayes.model.message.event.lol.GameEvent | gg.bayes.model.message.event.csgo.RoundResumeEvent |
MATCH | START_ROUND | gg.bayes.model.message.event.csgo.RoundStartEvent | |
MATCH | END_ROUND | gg.bayes.model.message.event.csgo.RoundEndEvent | |
MATCH | ANNOUNCED_ANCIENT | gg.bayes.model.message.event.lol.AncientAnnounceEvent | |
MATCH | SPAWNED_ANCIENT | gg.bayes.model.message.event.lol.AncientSpawnEvent | |
TEAM | BANNED_HERO | gg.bayes.model.message.event.lol.BanEvent | |
TEAM | UPDATE_SCORE | gg.bayes.model.message.event.lol.ScoreboardEvent | |
TEAM | KILLED_ANCIENT | gg.bayes.model.message.event.lol.AncientKillEvent | |
TEAM | TOOK_OBJECTIVE | gg.bayes.model.message.event.lol.BuildingDestroyedEvent | |
TEAM | EXPLODED_BOMB | gg.bayes.model.message.event.csgo.BombExplodedEvent | |
PLAYER | SELECTED_HERO | gg.bayes.model.message.event.lol.PickEvent | |
PLAYER | PLACED_WARD | gg.bayes.model.message.event.lol.WardPlacedEvent | |
PLAYER | KILLED_WARD | gg.bayes.model.message.event.lol.WardKilledEvent | |
PLAYER | KILL | gg.bayes.model.message.event.lol.KillEvent | gg.bayes.model.message.event.csgo.KillEvent |
PLAYER | SPECIAL_KILL | gg.bayes.model.message.event.lol.SpecialKillEvent | |
PLAYER | PURCHASED_ITEM | gg.bayes.model.message.event.lol.ItemChangeEvent | gg.bayes.model.message.event.csgo.ItemPurchaseEvent |
PLAYER | PICKED_UP_ITEM | gg.bayes.model.message.event.csgo.ItemPickupEvent | |
PLAYER | SOLD_ITEM | gg.bayes.model.message.event.lol.ItemChangeEvent | |
PLAYER | UNDO_ITEM | gg.bayes.model.message.event.lol.ItemChangeEvent | |
PLAYER | CONSUMED_ITEM | gg.bayes.model.message.event.lol.ItemChangeEvent | |
PLAYER | THREW_ITEM | gg.bayes.model.message.event.csgo.ItemThrowEvent | |
PLAYER | LEVEL_UP | gg.bayes.model.message.event.lol.LevelUpEvent | |
PLAYER | DIED | gg.bayes.model.message.event.lol.DeathEvent | gg.bayes.model.message.event.csgo.DeathEvent |
PLAYER | SPAWN | gg.bayes.model.message.event.lol.SpawnEvent | |
PLAYER | DEALT_DAMAGE | gg.bayes.model.message.event.csgo.DamageDealtEvent | |
PLAYER | PLANTED_BOMB | gg.bayes.model.message.event.csgo.BombPlantedEvent | |
PLAYER | STARTED_DEFUSING_BOMB | gg.bayes.model.message.event.csgo.BombDefuseStartedEvent | |
PLAYER | DEFUSED_BOMB | gg.bayes.model.message.event.csgo.BombDefusedEvent |
SNAPSHOT
SNAPSHOT
messages are periodically sent (every 5, or 10 seconds for example) and provide an overall view of the match at that point in time. This doesn’t include prior events, although some data here could be normalized and processed (for example - you might not know from a snapshot which wards are placed by which player, but you’ll know how many wards are placed by each player).
subject | action | lol-payload | csgo-payload |
---|---|---|---|
MATCH | UPDATE | gg.bayes.model.message.gamestate.lol.GameState | gg.bayes.model.message.gamestate.csgo.GameState |
TEAM | UPDATE | gg.bayes.model.message.gamestate.lol.Draft |
Some properties are stored as Strings, when in a non-dynamic system they would be stored as enums. This is to prevent things breaking if there are changes in the data we receive: for example if there was a new building type, or a new weapon type, or a new location. Per-game examples are below.
League of Legends
lane
:undefined
,top
,mid
,bot
buildingType
:undefined
,turret
,inhibitor
,nexus
turretTier
:outer
,inner
,base
,nexus
,fountain
monsterType
:dragon
,baron
,vileMaw
,riftHerald
,blueCamp
,redCamp
,scuttleCrab
gameState
: (only updated during draft phase)PRE_CHAMP_SELECT
,CHAMP_SELECT
,POST_CHAMP_SELECT
killType
:multi
,ace
,firstBlood
,shutdown
dragonType
:air
,water
,fire
,earth
,elder
wardType
:sight
,vision
,yellowTrinket
,yellowTrinketUpgrade
,explorer
,teemoMushroom
,ghost
,blueTrinket
,control
,unknown
Counter-Strike: Global Offensive
side
:TERRORIST
CT