Appearance
Steam Lobbies and P2P
Multiplayer features with Steam networking.
Lobbies
requestLobbyList()
Search for available lobbies. Returns an array of lobby ID strings.
javascript
const lobbies = await steam.requestLobbyList();
// ['109775241234567890', '109775241234567891', ...]Returns: string[] — array of lobby Steam IDs
createLobby(type, maxMembers)
Create a new lobby.
javascript
const lobbyId = await steam.createLobby(2, 4); // Public, 4 playersLobby Types:
0- Private1- Friends Only2- Public3- Invisible
joinLobby(lobbyId)
Join an existing lobby.
javascript
await steam.joinLobby(lobbyId);leaveLobby()
Leave current lobby.
javascript
await steam.leaveLobby();getLobbyData(key)
Get lobby metadata from current lobby.
javascript
const mapName = await steam.getLobbyData('map');setLobbyData(key, value)
Set lobby metadata (owner only).
javascript
await steam.setLobbyData('map', 'forest');
await steam.setLobbyData('mode', 'deathmatch');getLobbyMembers()
Get list of members in current lobby.
javascript
const members = await steam.getLobbyMembers();
// Array of Steam IDsgetLobbyOwner()
Get the lobby owner's Steam ID (uses current lobby).
javascript
const owner = await steam.getLobbyOwner();
// '76561198012345678'Returns: Steam ID string, or empty string if no current lobby.
getLobbyMemberCount(lobbyId)
Get the number of members currently in a lobby.
javascript
const count = await steam.getLobbyMemberCount(lobbyId);Parameters:
lobbyId- Steam lobby ID string
Returns: number — member count (0 if lobby not found or not yet joined)
getLobbyMemberByIndex(lobbyId, index)
Get the Steam ID of a specific lobby member by index.
javascript
const memberId = await steam.getLobbyMemberByIndex(lobbyId, 0); // first memberParameters:
lobbyId- Steam lobby ID stringindex- Zero-based member index
Returns: Steam ID string, or empty string if index out of range.
getLobbyMemberLimit()
Get maximum number of members allowed.
javascript
const max = await steam.getLobbyMemberLimit();setLobbyJoinable(joinable)
Set whether the lobby can be joined.
javascript
await steam.setLobbyJoinable(false); // Lock lobbyinviteUserToLobby(steamId)
Invite a user to the lobby.
javascript
await steam.inviteUserToLobby('76561198012345678');P2P Networking
sendP2PPacket(steamId, data, type)
Send data to another player.
javascript
const packet = JSON.stringify({ type: 'move', x: 100, y: 200 });
await steam.sendP2PPacket(targetSteamId, packet, 2);Channel Types:
0- Unreliable1- Unreliable, no delay2- Reliable3- Reliable, buffered
readP2PPacket()
Read incoming packet.
javascript
const packet = await steam.readP2PPacket();
if (packet) {
const data = JSON.parse(packet.data);
const sender = packet.steamId;
}acceptP2PSessionWithUser(steamId)
Accept incoming connection.
javascript
await steam.acceptP2PSessionWithUser(steamId);closeP2PSessionWithUser(steamId)
Close connection.
javascript
await steam.closeP2PSessionWithUser(steamId);Examples
Host Game
javascript
async function hostGame(maxPlayers = 4) {
// 0 = Private, 1 = FriendsOnly, 2 = Public, 3 = Invisible
const lobbyId = await steam.createLobby(2, maxPlayers);
if (lobbyId) {
console.log('Lobby created:', lobbyId);
const members = await steam.getLobbyMembers();
console.log('Members:', members);
}
return lobbyId ?? null;
}Browse Lobbies
javascript
async function findLobbies() {
const lobbies = await steam.requestLobbyList();
// lobbies is an array of lobby ID strings
const details = [];
for (const lobbyId of lobbies) {
const memberCount = await steam.getLobbyMemberCount(lobbyId);
details.push({ lobbyId, memberCount });
}
return details;
}Full Lobby Flow
javascript
async function lobbyDemo() {
// Create a public lobby for up to 4 players
const lobbyId = await steam.createLobby(2, 4);
if (!lobbyId) return;
// Check who joined
const members = await steam.getLobbyMembers();
const owner = await steam.getLobbyOwner();
console.log(`Owner: ${owner}, Members: ${members.join(', ')}`);
// Get count using explicit ID (useful when browsing lobbies)
const count = await steam.getLobbyMemberCount(lobbyId);
const first = await steam.getLobbyMemberByIndex(lobbyId, 0);
// Leave when done
steam.leaveLobby();
}Network Loop
javascript
function networkUpdate() {
// Process incoming packets
let packet;
while ((packet = steam.readP2PPacket())) {
handlePacket(packet.steamId, JSON.parse(packet.data));
}
}
function handlePacket(sender, data) {
switch (data.type) {
case 'move':
updatePlayerPosition(sender, data.x, data.y);
break;
case 'chat':
addChatMessage(sender, data.message);
break;
case 'action':
handlePlayerAction(sender, data.action);
break;
}
}
// Send position update
function sendPosition(x, y) {
const packet = JSON.stringify({ type: 'move', x, y });
for (const playerId of connectedPlayers) {
steam.sendP2PPacket(playerId, packet, 1); // Unreliable, no delay
}
}Reliable Messages
javascript
async function sendReliableMessage(steamId, data) {
const packet = JSON.stringify(data);
await steam.sendP2PPacket(steamId, packet, 2); // Reliable
}
// Use for important events
async function onPlayerScored(steamId, points) {
await sendReliableMessage(steamId, {
type: 'score',
points,
timestamp: Date.now()
});
}Best Practices
- Use reliable for important data - Score updates, game state changes
- Use unreliable for frequent updates - Position, rotation
- Validate incoming data - Never trust client data
- Handle disconnections - Clean up player state
- Rate limit sends - Don't flood the network
