PlanyDocs
API reference

EventService

api.plany.cloud:443Regional1 method

See how far Plany has got learning to read your game's log output. Plany works out when players join and leave from a game server's own log lines, so there is no SDK to integrate — and a game it has never seen shows no players until the patterns for those lines have been learned and proven, which takes hours. GetEventLearning shows that progress: the patterns found so far, and how much of the game's output they cover.

GetEventLearning

Read
plany.gamelog.v1.EventService/GetEventLearning

Says how far the platform has got understanding a game's log output.

The customer's view of the whole subsystem. A game Plany has never seen shows no players until a pattern for its join and leave lines has been learned and then trusted, which takes hours by design. Without this the wait looks exactly like a broken server, or one nobody is playing on.

Authorized on the game: anybody who may read the game may read this. For a game Plany publishes, the lines behind it come from every account running it, so the unmatched lines and the samples are withheld and only the counts and the patterns are returned.

Parameters

  • namestringRequired

    accounts/{account}/games/{game}/eventLearning, or games/{game}/eventLearning for a game Plany publishes.

Returns

EventLearning.

grpcurl -H "authorization: Bearer $PLANY_API_KEY" \
-d '{
"name": "accounts//games/my-game/eventLearning"
}' \
api.plany.cloud:443 plany.gamelog.v1.EventService/GetEventLearning
Example response
{
"name": "accounts//games/my-game/eventLearning",
"game": "",
"location": "",
"state": "STATE_AWAITING_LOGS",
"state_message": "",
"learning_enabled": false,
"templates": [
{
"template": "projects//locations//templates/my-template",
"game": "",
"inherited": false,
"kind": "KIND_PLAYER_CONNECTED",
"state": "STATE_PROPOSED",
"origin": "ORIGIN_BUILTIN",
"pattern": "",
"match_count": "0",
"coherent_count": "0",
"required_coherent_count": "0",
"incoherence_ratio": 0,
"max_incoherence_ratio": 0,
"earliest_promote_time": "2026-10-04T12:00:00Z",
"create_time": "2026-10-04T12:00:00Z",
"promote_time": "2026-10-04T12:00:00Z",
"progress_message": "",
"samples": [
""
]
}
],
"unmatched": [
{
"skeleton": "",
"example": "",
"occurrences": "0",
"first_seen_time": "2026-10-04T12:00:00Z",
"last_seen_time": "2026-10-04T12:00:00Z",
"last_asked_time": "2026-10-04T12:00:00Z"
}
],
"unmatched_shape_count": "0",
"unmatched_withheld": false,
"next_learn_time": "2026-10-04T12:00:00Z",
"min_occurrences": "0"
}

The TemplateProgress object

TemplateProgress is one pattern and how close it is to being trusted.

Attributes

  • templatestringOutput only

    projects/{project}/locations/{location}/templates/{template}

  • gamestringOutput only

    The game it is stored against. An ancestor of the game asked about when inherited is set: a pattern on games/minecraft-java serves every modpack under it.

  • inheritedboolOutput only
  • kindGameEvent.KindOutput only
    KIND_PLAYER_CONNECTEDKIND_PLAYER_DISCONNECTEDKIND_SERVER_READYKIND_SERVER_STOPPINGKIND_CHATKIND_ERROR
  • stateTemplate.StateOutput only
    STATE_PROPOSEDSTATE_ACTIVESTATE_REJECTED
  • originTemplate.OriginOutput only
    ORIGIN_BUILTINORIGIN_LEARNEDORIGIN_MANUAL
  • patternstringOutput only

    The RE2 pattern.

  • match_countint64Output only
  • coherent_countint64Output only

    Matches that made sense: a leave after a join for the same player, a join for somebody not already there.

  • required_coherent_countint64Output only

    What promotion needs. Set while the template is PROPOSED.

  • incoherence_ratiodoubleOutput only
  • max_incoherence_ratiodoubleOutput only
  • earliest_promote_timeTimestampOutput only

    The earliest it can be promoted, however well it behaves. The window in which a person can notice a bad pattern before it reaches a bill.

  • create_timeTimestampOutput only
  • promote_timeTimestampOutput only
  • progress_messagestringOutput only

    Why it is where it is. For a PROPOSED template, what promotion is still waiting on, worked out from the same policy the promotion loop runs.

  • samplesrepeated stringOutput only

    The lines it was derived from. Only for a pattern stored against the caller's own game: anything else may have been learned from another account's servers.

TemplateProgress
{
"template": "projects//locations//templates/my-template",
"game": "",
"inherited": false,
"kind": "KIND_PLAYER_CONNECTED",
"state": "STATE_PROPOSED",
"origin": "ORIGIN_BUILTIN",
"pattern": "",
"match_count": "0",
"coherent_count": "0",
"required_coherent_count": "0",
"incoherence_ratio": 0,
"max_incoherence_ratio": 0,
"earliest_promote_time": "2026-10-04T12:00:00Z",
"create_time": "2026-10-04T12:00:00Z",
"promote_time": "2026-10-04T12:00:00Z",
"progress_message": "",
"samples": [
""
]
}

The UnmatchedShape object

UnmatchedShape is one kind of line nothing recognises.

Attributes

  • skeletonstringOutput only

    The line with its variable parts replaced by placeholders.

  • examplestringOutput only

    One real line of this shape.

  • occurrencesint64Output only
  • first_seen_timeTimestampOutput only
  • last_seen_timeTimestampOutput only
  • last_asked_timeTimestampOutput only

    When it was last put in front of a model. Unset if never.

UnmatchedShape
{
"skeleton": "",
"example": "",
"occurrences": "0",
"first_seen_time": "2026-10-04T12:00:00Z",
"last_seen_time": "2026-10-04T12:00:00Z",
"last_asked_time": "2026-10-04T12:00:00Z"
}

EventLearning

EventLearning is where the platform has got with one game's log output, in the region that answered.

Regional, because templates are: one learned in eu-west-2 does not appear in us-east-1, so a game can be understood in one region and still be learning in another.

  • namestringIdentifier

    accounts/{account}/games/{game}/eventLearning, or games/{game}/eventLearning.

  • gamestringOutput only

    The game this describes.

  • locationstringOutput only

    The region that answered.

  • stateEventLearning.StateOutput only
    STATE_AWAITING_LOGSSTATE_LEARNINGSTATE_NO_PATTERN_FOUNDSTATE_VERIFYINGSTATE_ACTIVESTATE_LEARNING_DISABLED
  • state_messagestringOutput only

    One sentence for a person, saying what is happening and what happens next.

  • learning_enabledboolOutput only

    Whether this region can learn a new pattern at all.

  • templatesrepeated TemplateProgressOutput only

    Every pattern this game resolves to, inherited ones included, in the order they are tried: trusted first.

    Show child attributes
    • templatestringOutput only

      projects/{project}/locations/{location}/templates/{template}

    • gamestringOutput only

      The game it is stored against. An ancestor of the game asked about when inherited is set: a pattern on games/minecraft-java serves every modpack under it.

    • inheritedboolOutput only
    • kindGameEvent.KindOutput only
      KIND_PLAYER_CONNECTEDKIND_PLAYER_DISCONNECTEDKIND_SERVER_READYKIND_SERVER_STOPPINGKIND_CHATKIND_ERROR
    • stateTemplate.StateOutput only
      STATE_PROPOSEDSTATE_ACTIVESTATE_REJECTED
    • originTemplate.OriginOutput only
      ORIGIN_BUILTINORIGIN_LEARNEDORIGIN_MANUAL
    • patternstringOutput only

      The RE2 pattern.

    • match_countint64Output only
    • coherent_countint64Output only

      Matches that made sense: a leave after a join for the same player, a join for somebody not already there.

    • required_coherent_countint64Output only

      What promotion needs. Set while the template is PROPOSED.

    • incoherence_ratiodoubleOutput only
    • max_incoherence_ratiodoubleOutput only
    • earliest_promote_timeTimestampOutput only

      The earliest it can be promoted, however well it behaves. The window in which a person can notice a bad pattern before it reaches a bill.

    • create_timeTimestampOutput only
    • promote_timeTimestampOutput only
    • progress_messagestringOutput only

      Why it is where it is. For a PROPOSED template, what promotion is still waiting on, worked out from the same policy the promotion loop runs.

    • samplesrepeated stringOutput only

      The lines it was derived from. Only for a pattern stored against the caller's own game: anything else may have been learned from another account's servers.

  • unmatchedrepeated UnmatchedShapeOutput only

    Line shapes this game printed that nothing recognises, busiest first. Empty when unmatched_withheld is set.

    Show child attributes
    • skeletonstringOutput only

      The line with its variable parts replaced by placeholders.

    • examplestringOutput only

      One real line of this shape.

    • occurrencesint64Output only
    • first_seen_timeTimestampOutput only
    • last_seen_timeTimestampOutput only
    • last_asked_timeTimestampOutput only

      When it was last put in front of a model. Unset if never.

  • unmatched_shape_countint64Output only

    How many distinct unrecognised shapes there are, which may be more than unmatched lists.

  • unmatched_withheldboolOutput only

    Set for a game Plany publishes. Its lines come from every account running it, so they are not shown to any one of them.

  • next_learn_timeTimestampOutput only

    When the queued lines will next be put to a model. Unset when nothing is waiting to be asked about, or learning is disabled.

  • min_occurrencesint64Output only

    How many times a shape must be seen before it is worth asking about.

Enums

EventLearning.State

The stage a game is at, in the order a new game passes through them.

Derived on every read from the templates and the unmatched lines, never stored, so it cannot disagree with them.

ValueDescription
STATE_UNSPECIFIED
STATE_AWAITING_LOGSNo server of this game has logged anything Plany could not already read, and nothing matches a join or a leave yet. Start a server and let somebody join it.
STATE_LEARNINGLines nothing recognises are queued, and a model will be asked to propose patterns for them.
STATE_NO_PATTERN_FOUNDA model was asked and proposed nothing it could stand behind. Asked again at `next_learn_time`, or sooner if the game starts printing lines of a shape it has not seen.
STATE_VERIFYINGPatterns for joining and leaving exist and are being checked against real sessions before their events are trusted. Players are detected, provisionally.
STATE_ACTIVEJoining and leaving are both recognised by trusted patterns. Done.
STATE_LEARNING_DISABLEDThis region has no model configured, so a game whose lines nothing recognises stays that way until a person writes a pattern for it.

GameEvent.Kind

ValueDescription
KIND_UNSPECIFIED
KIND_PLAYER_CONNECTEDA player joined. What starts a billable session.
KIND_PLAYER_DISCONNECTEDA player left. What ends one.
KIND_SERVER_READYThe server announced it is accepting connections. Distinct from the instance being RUNNING, which only says a process started — a Minecraft server takes a further minute loading its world, and a player who connects in between gets a refused connection.
KIND_SERVER_STOPPINGThe server is shutting down of its own accord: an in-game command, a scheduled restart, a crash handler.
KIND_CHATA player sent a chat message. Never carries the message body — see `attributes`.
KIND_ERRORThe server logged something it called an error. Useful for support long before it is useful for billing.

Template.Origin

ValueDescription
ORIGIN_UNSPECIFIED
ORIGIN_BUILTINShipped with Plany, in `internal/patterns`. Starts ACTIVE: these come with tests over real log samples, which is a stronger guarantee than shadowing gives.
ORIGIN_LEARNEDProposed by a model from unmatched lines.
ORIGIN_MANUALWritten by hand rather than learned.

Template.State

ValueDescription
STATE_UNSPECIFIED
STATE_PROPOSEDProposed and validated, but not yet trusted. Events it produces are published as PROVISIONAL. Everything new lands here. A regular expression that matches slightly too much would invent player connections, and an invented connection is a wrong invoice — so a template earns its way out of this state by behaving, not by being plausible.
STATE_ACTIVETrusted. Events it produces are CONFIRMED.
STATE_REJECTEDWithdrawn. Kept rather than deleted, so the same shape is not proposed again next week and so there is a record of what was tried.