Send Message to Specific Player
Send messages to specific players in an endless room using their participant IDs. This is ideal for private messages, targeted game events, and player-specific updates.
Method
MoitribeSDK('game-id', 'endlessmessage', params, callback)
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
messageData | ArrayBuffer | Yes | Message data to send |
participantIds | string[] | Yes | Array of participant IDs to send to |
isReliable | boolean | No | Whether message must be delivered (default: true) |
Response Format
{
success: boolean;
msg?: string;
}
Examples
JavaScript Example
// Send private message to a specific player
function sendPrivateMessage(participantId, text) {
const encoder = new TextEncoder();
const messageData = encoder.encode(text);
MoitribeSDK('my-game', 'endlessmessage', {
messageData: messageData.buffer,
participantIds: [participantId],
isReliable: true
}, (result) => {
if (result.success) {
console.log('Private message sent to:', participantId);
} else {
console.error('Failed to send private message:', result.msg);
}
});
}
// Send game event to specific players
function sendGameEventToPlayers(participantIds, eventType, data) {
const eventData = {
type: eventType,
data: data,
timestamp: Date.now()
};
const encoder = new TextEncoder();
const messageData = encoder.encode(JSON.stringify(eventData));
MoitribeSDK('my-game', 'endlessmessage', {
messageData: messageData.buffer,
participantIds: participantIds,
isReliable: true
}, (result) => {
console.log(`Event sent to ${participantIds.length} players:`, result.success);
});
}
// Send power-up to specific player
function sendPowerUp(participantId, powerUpType) {
const buffer = new ArrayBuffer(2);
const view = new DataView(buffer);
view.setUint8(0, 1); // Message type: power-up
view.setUint8(1, powerUpType);
MoitribeSDK('my-game', 'endlessmessage', {
messageData: buffer,
participantIds: [participantId],
isReliable: true
}, (result) => {
if (result.success) {
console.log(`Power-up ${powerUpType} sent to player`);
}
});
}
TypeScript Example
import MoitribeSDK from '@veniso/moitribe-js';
// Send targeted game event
interface TargetedEvent {
type: 'damage' | 'heal' | 'powerup' | 'effect';
targetPlayerId: string;
value: number;
sourcePlayerId: string;
timestamp: number;
}
function sendTargetedEvent(event: TargetedEvent): void {
const messageData = encodeTargetedEvent(event);
MoitribeSDK('my-game', 'endlessmessage', {
messageData: messageData,
participantIds: [event.targetPlayerId],
isReliable: true
}, (result: any) => {
if (result.success) {
console.log(`Targeted event sent: ${event.type} to ${event.targetPlayerId}`);
} else {
console.error('Failed to send targeted event:', result.msg);
}
});
}
// Send to multiple specific players
function sendTeamMessage(teamMemberIds: string[], message: string): void {
const encoder = new TextEncoder();
const messageData = encoder.encode(message);
MoitribeSDK('my-game', 'endlessmessage', {
messageData: messageData.buffer,
participantIds: teamMemberIds,
isReliable: true
}, (result: any) => {
console.log(`Team message sent to ${teamMemberIds.length} members:`, result.success);
});
}
// Helper function to encode targeted events
function encodeTargetedEvent(event: TargetedEvent): ArrayBuffer {
const json = JSON.stringify(event);
const encoder = new TextEncoder();
return encoder.encode(json).buffer;
}
// Usage examples
sendTargetedEvent({
type: 'damage',
targetPlayerId: 'player123',
value: 25,
sourcePlayerId: 'player456',
timestamp: Date.now()
});
Finding Participant IDs
From Room Object
// Get participant IDs from room object
function getParticipantIds(room) {
return room.participants.map(participant => participant.participantID);
}
// Get specific participant ID by player name
function getParticipantIdByName(room, playerName) {
const participant = room.participants.find(p => p.name === playerName);
return participant ? participant.participantID : null;
}
// Usage
onConnectedToRoom: (room) => {
const allPlayerIds = getParticipantIds(room);
const targetPlayerId = getParticipantIdByName(room, 'Alice');
if (targetPlayerId) {
sendPrivateMessage(targetPlayerId, 'Hello Alice!');
}
}
From Message Events
// Store participant IDs when they join
const participantMap = new Map();
onPeerJoined: (room, participantList) => {
room.participants.forEach(participant => {
participantMap.set(participant.playerID, participant.participantID);
});
};
onMessageReceived: (messageData, senderParticipantID, isReliable) => {
// senderParticipantID is the participant ID you can reply to
sendPrivateMessage(senderParticipantID, 'Message received!');
};
Use Cases
Private Chat System
function sendPrivateChat(recipientPlayerId, message) {
const recipientParticipantId = participantMap.get(recipientPlayerId);
if (!recipientParticipantId) {
console.error('Player not found in room');
return;
}
const chatData = {
type: 'private_chat',
message: message,
sender: getCurrentPlayerId(),
timestamp: Date.now()
};
const encoder = new TextEncoder();
const messageData = encoder.encode(JSON.stringify(chatData));
MoitribeSDK('my-game', 'endlessmessage', {
messageData: messageData.buffer,
participantIds: [recipientParticipantId],
isReliable: true
});
}
Team Communication
function sendTeamChat(teamId, message) {
const teamMembers = getTeamMembers(teamId);
const teamParticipantIds = teamMembers.map(member =>
participantMap.get(member.playerId)
).filter(Boolean);
const teamData = {
type: 'team_chat',
teamId: teamId,
message: message,
sender: getCurrentPlayerId(),
timestamp: Date.now()
};
const encoder = new TextEncoder();
const messageData = encoder.encode(JSON.stringify(teamData));
MoitribeSDK('my-game', 'endlessmessage', {
messageData: messageData.buffer,
participantIds: teamParticipantIds,
isReliable: true
});
}
Targeted Game Events
// Send damage to specific player
function dealDamage(targetPlayerId, damageAmount, sourcePlayerId) {
const targetParticipantId = participantMap.get(targetPlayerId);
if (!targetParticipantId) return;
const damageData = {
type: 'damage',
amount: damageAmount,
source: sourcePlayerId,
timestamp: Date.now()
};
const encoder = new TextEncoder();
const messageData = encoder.encode(JSON.stringify(damageData));
MoitribeSDK('my-game', 'endlessmessage', {
messageData: messageData.buffer,
participantIds: [targetParticipantId],
isReliable: true
});
}
// Send healing to specific player
function healPlayer(targetPlayerId, healAmount) {
const targetParticipantId = participantMap.get(targetPlayerId);
if (!targetParticipantId) return;
const healData = {
type: 'heal',
amount: healAmount,
timestamp: Date.now()
};
const encoder = new TextEncoder();
const messageData = encoder.encode(JSON.stringify(healData));
MoitribeSDK('my-game', 'endlessmessage', {
messageData: messageData.buffer,
participantIds: [targetParticipantId],
isReliable: true
});
}
Multiple Recipients
Send to Group
function sendToGroup(participantIds, data) {
const encoder = new TextEncoder();
const messageData = encoder.encode(JSON.stringify(data));
MoitribeSDK('my-game', 'endlessmessage', {
messageData: messageData.buffer,
participantIds: participantIds,
isReliable: true
}, (result) => {
console.log(`Message sent to ${participantIds.length} players:`, result.success);
});
}
// Usage
const selectedPlayers = ['participant1', 'participant2', 'participant3'];
sendToGroup(selectedPlayers, {
type: 'group_invite',
gameId: 'battle_royale_001'
});
Send to All Except One
function sendToAllExcept(excludeParticipantId, data) {
const allParticipantIds = Array.from(participantMap.values());
const recipients = allParticipantIds.filter(id => id !== excludeParticipantId);
const encoder = new TextEncoder();
const messageData = encoder.encode(JSON.stringify(data));
MoitribeSDK('my-game', 'endlessmessage', {
messageData: messageData.buffer,
participantIds: recipients,
isReliable: true
});
}
Error Handling
function sendTargetedMessageWithErrorHandling(participantIds, messageData, isReliable = true) {
MoitribeSDK('my-game', 'endlessmessage', {
messageData,
participantIds,
isReliable
}, (result) => {
if (!result.success) {
console.error('Targeted message failed:', result.msg);
// Handle specific errors
if (result.msg?.includes('invalid participant')) {
console.error('One or more participant IDs are invalid');
// Remove invalid participants from local cache
cleanupInvalidParticipants(participantIds);
} else if (result.msg?.includes('not in room')) {
showReconnectDialog();
}
}
});
}
Performance Considerations
Batch Targeted Messages
// Instead of sending multiple individual messages
function sendIndividualUpdates(players, updates) {
players.forEach((player, index) => {
sendPrivateMessage(player, updates[index]);
});
}
// Batch them when possible
function sendBatchedUpdates(players, updates) {
const batchData = {
type: 'batched_updates',
updates: players.map((player, index) => ({
playerId: player,
data: updates[index]
}))
};
// Send to all players and let them filter their own data
sendToAll(batchData);
}
Best Practices
Validate Participant IDs
function validateParticipantIds(participantIds) {
const allValidIds = Array.from(participantMap.values());
return participantIds.filter(id => allValidIds.includes(id));
}
// Usage
const requestedIds = ['id1', 'id2', 'invalid_id'];
const validIds = validateParticipantIds(requestedIds);
if (validIds.length > 0) {
sendToGroup(validIds, messageData);
}
Rate Limiting
const messageTimestamps = new Map();
const RATE_LIMIT_MS = 1000; // 1 second between messages to same player
function sendWithRateLimit(participantId, messageData) {
const now = Date.now();
const lastSent = messageTimestamps.get(participantId) || 0;
if (now - lastSent >= RATE_LIMIT_MS) {
MoitribeSDK('my-game', 'endlessmessage', {
messageData,
participantIds: [participantId],
isReliable: true
});
messageTimestamps.set(participantId, now);
} else {
console.log('Rate limited - message not sent');
}
}
Next Steps
- Send to All Players - Broadcast to entire room
- Send to Server - Communicate with game server
- Receive Messages - Handle incoming messages
- Room Callbacks - Manage room events
Pro Tip
Keep a mapping of player IDs to participant IDs for easy targeting. Update this mapping whenever players join or leave the room.