Skip to main content

Submit Tournament Score

The submit tournament score method allows players to submit their scores for tournaments they've joined. This is essential for updating tournament leaderboards and determining winners.

Overview

The submitTournamentScore method:

  • Submits player scores to tournament leaderboards
  • Validates player participation in tournament
  • Updates tournament rankings in real-time
  • Returns status code indicating success or failure

Method Signature

public function submitTournamentScore(
string $gameID,
string $tournamentID,
int $score,
string $scoreTag = '',
int $scoreTimeStamp = 0
): int

Parameters

Required Parameters

  • gameID (String) - The Game ID for the tournament
  • tournamentID (String) - The Tournament ID to submit score to
  • score (int) - The player's score to submit

Optional Parameters

  • scoreTag (String) - Additional score metadata or tag

    • Default: empty string
    • Can be used for score categorization
  • scoreTimeStamp (int) - Unix timestamp for when score was achieved

    • Default: 0 (current time)
    • Useful for offline score submission

Return Value

Returns an integer status code:

  • Positive value - Score submitted successfully
  • Zero or negative - Submission failed

Basic Usage

Simple Score Submission

use Veniso\Moitribe\Sdk\modules\classes\MoitribeApi;

$moitribe = new MoitribeApi([
'gameid' => 'your-game-id',
'channelid' => 'your-channel-id',
'playerid' => 'player-123'
]);

try {
$result = $moitribe->tournRequestsHandler->submitTournamentScore(
'your-game-id',
'tournament-123',
1500
);

if ($result > 0) {
echo "Score submitted successfully!\n";
echo "Submission ID: " . $result . "\n";
} else {
echo "Failed to submit score\n";
echo "Error code: " . $result . "\n";
}

} catch (Exception $e) {
echo "Error: " . $e->getMessage() . "\n";
}

Score Submission with Metadata

function submitGameScore($gameId, $tournamentId, $score, $gameSessionData) {
global $moitribe;

try {
$scoreTag = json_encode([
'level' => $gameSessionData['level'],
'time_played' => $gameSessionData['time_played'],
'difficulty' => $gameSessionData['difficulty'],
'character' => $gameSessionData['character']
]);

$scoreTimeStamp = $gameSessionData['end_time'] ?? time();

$result = $moitribe->tournRequestsHandler->submitTournamentScore(
$gameId,
$tournamentId,
$score,
$scoreTag,
$scoreTimeStamp
);

if ($result > 0) {
return [
'success' => true,
'message' => 'Score submitted successfully',
'submission_id' => $result
];
} else {
return [
'success' => false,
'message' => 'Failed to submit score',
'error_code' => $result
];
}

} catch (Exception $e) {
error_log("Score submission error: " . $e->getMessage());
return [
'success' => false,
'message' => 'Server error occurred'
];
}
}

// Usage
$gameSession = [
'level' => 15,
'time_played' => 1800, // 30 minutes
'difficulty' => 'hard',
'character' => 'warrior',
'end_time' => time()
];

$result = submitGameScore('your-game-id', 'tournament-123', 2500, $gameSession);

if ($result['success']) {
echo "Success: " . $result['message'] . "\n";
} else {
echo "Error: " . $result['message'] . "\n";
}

Integration Examples

Game Session Score Submission

class TournamentScoreManager {
private $moitribe;
private $gameId;
private $currentSession;

public function __construct($moitribe, $gameId) {
$this->moitribe = $moitribe;
$this->gameId = $gameId;
$this->currentSession = null;
}

public function startGameSession($tournamentId, $playerData) {
$this->currentSession = [
'tournament_id' => $tournamentId,
'player_id' => $playerData['player_id'],
'start_time' => time(),
'start_score' => $playerData['current_score'] ?? 0,
'level' => $playerData['level'] ?? 1,
'difficulty' => $playerData['difficulty'] ?? 'normal',
'character' => $playerData['character'] ?? 'default'
];

return $this->currentSession;
}

public function endGameSession($finalScore, $additionalData = []) {
if (!$this->currentSession) {
throw new Exception('No active game session');
}

$sessionData = array_merge($this->currentSession, [
'end_time' => time(),
'final_score' => $finalScore,
'duration' => time() - $this->currentSession['start_time'],
'score_gained' => $finalScore - $this->currentSession['start_score']
]);

$sessionData = array_merge($sessionData, $additionalData);

$result = $this->submitScore($sessionData);

$this->currentSession = null;
return $result;
}

private function submitScore($sessionData) {
try {
// Validate session data
if ($sessionData['final_score'] < 0) {
throw new InvalidArgumentException('Score cannot be negative');
}

// Prepare score tag with session metadata
$scoreTag = json_encode([
'session_id' => uniqid('session_', true),
'duration' => $sessionData['duration'],
'level' => $sessionData['level'],
'difficulty' => $sessionData['difficulty'],
'character' => $sessionData['character'],
'score_gained' => $sessionData['score_gained'],
'enemies_defeated' => $sessionData['enemies_defeated'] ?? 0,
'accuracy' => $sessionData['accuracy'] ?? 0
]);

$result = $this->moitribe->tournRequestsHandler->submitTournamentScore(
$this->gameId,
$sessionData['tournament_id'],
$sessionData['final_score'],
$scoreTag,
$sessionData['end_time']
);

if ($result > 0) {
// Log successful submission
$this->logScoreSubmission($sessionData, $result);

return [
'success' => true,
'submission_id' => $result,
'score' => $sessionData['final_score'],
'tournament_id' => $sessionData['tournament_id']
];
} else {
return [
'success' => false,
'error_code' => $result,
'message' => $this->getScoreSubmissionError($result)
];
}

} catch (Exception $e) {
error_log("Score submission error: " . $e->getMessage());
return [
'success' => false,
'message' => 'Failed to submit score'
];
}
}

private function logScoreSubmission($sessionData, $submissionId) {
$logData = [
'submission_id' => $submissionId,
'player_id' => $sessionData['player_id'],
'tournament_id' => $sessionData['tournament_id'],
'score' => $sessionData['final_score'],
'duration' => $sessionData['duration'],
'timestamp' => $sessionData['end_time']
];

error_log("Score submitted: " . json_encode($logData));
}

private function getScoreSubmissionError($errorCode) {
switch ($errorCode) {
case 0:
return 'Failed to submit score';
case -1:
return 'Player not registered for tournament';
case -2:
return 'Tournament not found';
case -3:
return 'Tournament has ended';
case -4:
return 'Invalid score value';
default:
return 'Unknown error occurred';
}
}
}

// Usage
$scoreManager = new TournamentScoreManager($moitribe, 'your-game-id');

// Start game session
$session = $scoreManager->startGameSession('tournament-123', [
'player_id' => 'player-456',
'level' => 10,
'difficulty' => 'hard',
'character' => 'mage'
]);

// Game logic here...
// Player plays game and achieves score

// End session and submit score
$result = $scoreManager->endGameSession(3500, [
'enemies_defeated' => 150,
'accuracy' => 87.5
]);

if ($result['success']) {
echo "Score submitted! ID: " . $result['submission_id'] . "\n";
echo "Score: " . $result['score'] . "\n";
} else {
echo "Submission failed: " . $result['message'] . "\n";
}

Batch Score Submission

function submitBatchScores($gameId, $scoreSubmissions) {
global $moitribe;

$results = [];
$successCount = 0;
$failureCount = 0;

foreach ($scoreSubmissions as $submission) {
try {
$result = $moitribe->tournRequestsHandler->submitTournamentScore(
$gameId,
$submission['tournament_id'],
$submission['score'],
$submission['score_tag'] ?? '',
$submission['timestamp'] ?? time()
);

if ($result > 0) {
$results[] = [
'success' => true,
'submission_id' => $result,
'tournament_id' => $submission['tournament_id'],
'score' => $submission['score']
];
$successCount++;
} else {
$results[] = [
'success' => false,
'error_code' => $result,
'tournament_id' => $submission['tournament_id'],
'score' => $submission['score']
];
$failureCount++;
}

} catch (Exception $e) {
$results[] = [
'success' => false,
'error' => $e->getMessage(),
'tournament_id' => $submission['tournament_id'],
'score' => $submission['score']
];
$failureCount++;
}

// Small delay to avoid overwhelming the API
usleep(100000); // 0.1 second
}

return [
'total_submissions' => count($scoreSubmissions),
'successful' => $successCount,
'failed' => $failureCount,
'results' => $results
];
}

// Usage for offline scores
$offlineScores = [
[
'tournament_id' => 'tournament-123',
'score' => 1200,
'timestamp' => time() - 3600, // 1 hour ago
'score_tag' => json_encode(['device' => 'mobile', 'version' => '1.2.3'])
],
[
'tournament_id' => 'tournament-456',
'score' => 2800,
'timestamp' => time() - 1800, // 30 minutes ago
'score_tag' => json_encode(['device' => 'web', 'version' => '1.2.3'])
]
];

$batchResult = submitBatchScores('your-game-id', $offlineScores);

echo "Batch submission results:\n";
echo "Successful: " . $batchResult['successful'] . "\n";
echo "Failed: " . $batchResult['failed'] . "\n";

foreach ($batchResult['results'] as $result) {
if ($result['success']) {
echo "✓ Tournament {$result['tournament_id']}: {$result['score']} points\n";
} else {
echo "✗ Tournament {$result['tournament_id']}: Failed\n";
}
}

Error Handling

Common Error Scenarios

  • Player not registered - Player hasn't joined the tournament
  • Tournament not found - Invalid tournament ID
  • Tournament ended - Submission period is over
  • Invalid score - Negative or unrealistic score values
  • Duplicate submission - Same score submitted multiple times
  • Network issues - API communication problems

Error Handling Example

function safeSubmitScore($gameId, $tournamentId, $score, $scoreTag = '', $timestamp = 0) {
global $moitribe;

try {
// Validate inputs
if (empty($gameId) || empty($tournamentId)) {
throw new InvalidArgumentException("Game ID and Tournament ID are required");
}

if (!is_int($score) || $score < 0) {
throw new InvalidArgumentException("Score must be a non-negative integer");
}

if ($timestamp < 0) {
$timestamp = time();
}

$result = $moitribe->tournRequestsHandler->submitTournamentScore(
$gameId,
$tournamentId,
$score,
$scoreTag,
$timestamp
);

if ($result > 0) {
return [
'success' => true,
'submission_id' => $result,
'message' => 'Score submitted successfully'
];
} else {
return [
'success' => false,
'error_code' => $result,
'message' => getScoreErrorMessage($result)
];
}

} catch (InvalidArgumentException $e) {
return [
'success' => false,
'message' => 'Invalid input: ' . $e->getMessage()
];
} catch (Exception $e) {
error_log("Score submission error: " . $e->getMessage());
return [
'success' => false,
'message' => 'Failed to submit score'
];
}
}

function getScoreErrorMessage($errorCode) {
switch ($errorCode) {
case 0:
return 'Score submission failed';
case -1:
return 'Player is not registered for this tournament';
case -2:
return 'Tournament not found';
case -3:
return 'Tournament has ended - no more scores accepted';
case -4:
return 'Invalid score value';
case -5:
return 'Duplicate score submission';
default:
return 'Unknown error occurred';
}
}

Best Practices

  1. Validate Score Values

    • Ensure scores are non-negative integers
    • Check for realistic score ranges
    • Validate against game rules
  2. Include Score Metadata

    • Use score tags for additional context
    • Include game session information
    • Track difficulty level and other factors
  3. Handle Offline Scenarios

    • Store scores when offline
    • Submit in batches when connection restored
    • Use timestamps for accurate timing
  4. Implement Rate Limiting

    • Avoid spamming score submissions
    • Implement cooldown periods
    • Queue submissions for optimal timing