Reference

Everything on the Melay autoload. Calls marked await return a MelayResult.

Setup

Call Does
Melay.configure(url, game_id, game_version) Point at a relay. Wins over everything else.
Melay.set_display_name(name) Name other players see
Melay.set_api_key(key) Only if your relay requires one

Connecting

Call Does
await Melay.connect_to_relay() Connect
Melay.disconnect_from_relay() Disconnect

Rooms

Call Returns
await Melay.create_room(options) A MelayRoom
await Melay.join_room(code, password) A MelayRoom
await Melay.join_or_create(options) Joins any open room, or makes one
await Melay.list_rooms(filter) An array of room summaries
Melay.leave_room() Leaves, stays connected

create_room options, all optional:

{
	"name": "Mark's game",
	"max_players": 4,
	"visibility": "public",        # or "private", code only
	"tags": {"mode": "ffa"},       # filter the room list on these
	"password": "",
}

list_rooms filters: tags, only_joinable, limit.

Reading state

Call Returns
Melay.is_in_room() bool
Melay.is_host() bool
Melay.get_room() MelayRoom
Melay.get_rtt_us() Round-trip time in microseconds
Melay.get_relay_time_us() Relay clock, the same for every player
Melay.get_limits() What the relay allows this game
Melay.get_max_message_size() Largest packet you may send

Large packets

Send one. A packet too big for a single frame is split on the way out and put back together on the far side, the way ENet does it, so an initial world state or a level blob travels without you chunking it yourself.

# No special call. This is an ordinary rpc that happens to be large.
_receive_world.rpc_id(peer_id, world.serialise())

Melay.get_max_message_size() is the ceiling, 8 MB by default and set per game on the relay with max_message_size. Going over it fails loudly with a pushed error rather than silently dropping the packet, so size a full state against it.

A relay older than fragmentation reports the frame limit instead, and the addon then refuses to split anything, because those frames would be dropped without a word. Check the number rather than assuming 8 MB.

Analytics

Melay.track("level_complete", {"level": "3"})

Rooms, sessions and playtime are recorded without you doing anything. Use track only for your own events.

Signals

Signal When
connected Relay connection is up
disconnected(reason) Connection lost
room_joined(room) You are in a room
room_left You left
peer_joined(info) Somebody joined
peer_left(info, reason) Somebody left
error_received(code, message) Something failed
peer_ready(peer) See the note below

MelayResult

result.is_error()   # bool
result.message      # what went wrong
result.value        # what you asked for

MelayRoom

room.code           # the share code
room.self_peer_id   # your id
room.host_peer_id   # the host's id, always 1
room.peers          # peer_id -> MelayPeerInfo
room.is_host()
room.player_count()

MelayPeerInfo

info.peer_id
info.display_name
info.platform
info.is_host

Peer ids

The host is always peer 1, so multiplayer.is_server() behaves the way you expect. Everyone else gets 2 and up.

If you assign the peer yourself

By default Melay sets multiplayer.multiplayer_peer for you. If you turn off Auto Assign Peer in the project settings, do it in peer_ready and nowhere else:

Melay.peer_ready.connect(func(peer: MelayPeer) -> void:
	multiplayer.multiplayer_peer = peer
)

Doing it in room_joined is too late. Godot learns who else is in the room between those two moments, so a peer set afterwards sees nobody and your RPCs go nowhere.


Melay is MIT licensed.

This site uses Just the Docs, a documentation theme for Jekyll.