moymo,Docs
Skip to content
Games: the Moymo SDK

moymo.toml ​

moymo.toml lives next to your project and says what the game tells Moymo. moymo push checks it, writes the typed code your game calls, and uploads it. Commit it together with moymo.lock.

This page covers what Moymo reads today. A table that is planned but not built yet ([journey], [boards], [party], [saves], [pulse], [reach], [prefs], [live], [mods], [recap], [bridges]) gives a warning and is ignored. Any other unknown table is an error.

An example ​

moymo.toml
toml
[game]
id      = "starfall-outpost"               # the app key from the Developer Portal
name    = "Starfall Outpost"
locales = ["en", "cs"]                     # the first is used where a player's language is missing
modules = ["moments", "presence", "achievements"]

[codegen]
cpp = "Source/StarfallOutpost/Moymo.g.h"   # or csharp = "Assets/Moymo/Moymo.g.cs"

[lists]
paths = ["agrarian", "industrial", "martial"]

[labels.paths]                             # needed only where people read the symbols (presence)
agrarian   = { en = "farming", cs = "zemědělská" }
industrial = { en = "crafts", cs = "řemeslná" }
martial    = { en = "arms", cs = "vojenská" }

[events.raid_repelled]
fields = { wave = "int(1..)", losses = "int(0..)", minutes = "float" }

[events.path_chosen]
fields = { path = "enum(@paths)" }

[moments.raid_repelled]
on         = "raid_repelled"
importance = "epic"
clip       = { before = "25s", after = "4s" }
title      = { en = "Raid repelled · wave {wave}", cs = "Nájezd odražen · vlna {wave}" }

[presence.lines.defending]
text   = { en = "Defending the settlement · wave {wave}", cs = "Brání osadu · vlna {wave}" }
params = { wave = "int(1..)" }

[presence.lines.on_path]
text   = { en = "On the {path} path", cs = "Na cestě: {path}" }
params = { path = "enum(@paths)" }

[stats.raids_repelled]
kind = "counter"
from = "raid_repelled"

[stats.population]
kind = "max"                               # no `from`: the game puts it

[achievements.night_held]
name        = { en = "Not a Scratch", cs = "Ani škrábnutí" }
description = { en = "Repel a third-wave raid without losing anyone.", cs = "Odraz třetí vlnu bez ztrát." }
on          = "raid_repelled"
when        = "event.losses == 0 && event.wave >= 3"
steam       = "ACH_NOT_A_SCRATCH"

[achievements.full_household]
name        = { en = "A Full Household", cs = "Plný dvůr" }
description = { en = "Have 20 people living in your settlement.", cs = "Měj v osadě 20 obyvatel." }
rule        = "stats.population >= 20"

Names and text ​

  • Keys (raid_repelled, night_held) are lower_snake_case, at most 64 characters, starting with a letter. The generated code turns them into RaidRepelled, NightHeld.
  • Text is either one string for every language (title = "Raid {wave}") or one per language ({ en = "...", cs = "..." }). Every language in game.locales needs its text. {wave} puts in a field of the event (moments) or a parameter (presence lines).

[game] ​

Key
idThe app key the Developer Portal gave the game. Lower case, digits, - and _.
name1 to 100 characters.
localesThe languages you write text in. The first is the fallback.
modulesWhat the game uses: moments, presence, achievements. These are also what Moymo for Windows asks the player to allow.

[codegen] ​

Key
csharpThe C# file to write (Unity), relative to moymo.toml, for example Assets/Moymo/Moymo.g.cs.
cppThe C++ header to write (Unreal Engine, any C++ engine), for example Source/MyGame/Moymo.g.h.
namespaceDefault Moymo.Game (C#) or moymo::game (C++). Write it with dots: MyGame.Moymo.

Both paths stay inside the project: no .. and no absolute paths.

[lists] and [labels] ​

A list is a named set of symbols that fields and rules share: paths = ["agrarian", "martial"]. A field uses it as enum(@paths). A rule reads it as lists.paths.

[labels.<list>] gives each symbol a text, in every language. A presence line can show a list's symbol only if every symbol has a label: a friend reads farming, not agrarian.

[events.<key>] ​

Something that happens in the game. Moments, stats and achievements follow events, so the game usually only emits.

Key
fieldsUp to 8 fields: int, a range such as int(1..), int(0..10) or int(..5), float, bool, enum(walls, gate), or enum(@list).
analyticstrue marks the event as analytics.

[moments.<key>] ​

A big moment. Moymo for Windows keeps a clip of it if the player records clips, and names the clip by its title. Needs moments in game.modules.

Key
onThe event that marks it. Without on, the game marks it from code.
importanceminor, notable (the default), major or epic.
clipHow much to keep before and after: { before = "25s", after = "4s" }. Default 10 s before, 3 s after. At most 120 s before and 60 s after.
titleText. It can use the event's fields: {wave}.

[presence.lines.<key>] ​

A line under the player's name that friends read, in the friend's own language. Needs presence in game.modules.

Key
textText with {param} placeholders.
paramsWhole numbers (int, int(1..)), or enum(@list) of a list with a label for every symbol. Never free text: a friend only ever reads what you wrote here.

[stats.<key>] ​

A number or a set the game keeps per player. Rules read stats to unlock achievements. Stats are kept on the player's PC; Moymo does not merge them across PCs yet.

kindKeepsFrom an event (from)
counterA total that only grows.Adds add (default 1) for each event.
max / minThe highest or lowest value seen.value, for example event.wave or event.minutes * 60.0.
setDistinct symbols, such as the kinds of building built.value, for example event.kind.
flagBecomes true and stays true.value (a condition), or true for any event.
  • from: the event that feeds the stat. Without it, the game puts the value itself (Stats.Put in C#, moymo::Stats::PutInt and the rest in C++).
  • when: a condition on the event. Only matching events count.
  • type: int (the default) or float, for a counter, a max or a min.

[achievements.<key>] ​

Shown on the player's Moymo profile once unlocked. Needs achievements in game.modules.

Key
name, descriptionText.
hiddentrue: the name stays hidden until unlocked.
steamIts API name in Steamworks. The SDK unlocks it on Steam too (Unity and C++; see your engine's page).

How it unlocks. Pick one way; the code can always unlock it too:

(nothing)Only the game unlocks it: Achievements.Unlock(Ach.FirstBanner).
onAn event unlocks it. Add when for a condition on the event's fields.
ruleA condition on stats, checked whenever they change: stats.population >= 20.
requiresOther achievements that must all be unlocked first: requires = ["night_held", "full_household"]. It can be combined with rule.

An unlock is never taken back, even if you change a rule later. A manifest that adds a rule the player's stats already meet unlocks it the next time the game starts.

Conditions (CEL) ​

when, add, value and rule are short expressions in CEL. moymo check runs each one on sample values and says what is wrong before you push.

WhereIt can read
when, add, valueevent.<field>, lists.<list>
rulestats.<stat>, lists.<list>, achievements (the keys already unlocked)
text
event.losses == 0 && event.wave >= 3
stats.raids_repelled >= 10
lists.paths.all(p, p in stats.paths_taken)
size(achievements) >= 5
'night_held' in achievements && stats.population >= 50

moymo.lock ​

moymo push (and moymo codegen) gives every event, moment, presence line, achievement and stat a number the first time it sees it, and writes it to moymo.lock. Commit that file. A number is never reused, so a build made today keeps working after you add more. To rename a key, add a new one; a typo in a name or a description can be fixed freely.

Limits ​

256 events, 128 moments, 64 presence lines, 512 stats and 1000 achievements per game. Each event has at most 8 fields.

The wiki is for Moymo's members and developers. Something wrong or missing? Use "Suggest a change" on any page.