Skip to main content

Create Account with OTP

The createWithOtp method registers new players using a one-time password (OTP). This creates a new player account and automatically logs them in.

Prerequisites

Before calling createWithOtp, you must:

  1. Generate an OTP using genOtp
  2. Player must have received the OTP via email/SMS
  3. Player must enter the OTP and choose a display name

Basic Usage

Create account with email or phone number, OTP, and player name.

Email Registration

MoitribeSDK('my-game-id', 'createWithOtp', {
emailid: 'newplayer@example.com',
otp: '123456',
name: 'PlayerName',
callback: (result) => {
if (result.success) {
console.log('Account created successfully');
startGame();
} else {
console.error('Account creation failed:', result.msg);
}
}
});

Phone Registration

MoitribeSDK('my-game-id', 'createWithOtp', {
phno: '+1234567890',
otp: '123456',
name: 'PlayerName',
callback: (result) => {
if (result.success) {
console.log('Account created successfully');
startGame();
} else {
console.error('Account creation failed:', result.msg);
}
}
});

Parameters

ParameterTypeRequiredDescription
emailidstringEither email or phonePlayer's email address
phnostringEither email or phonePlayer's phone number (E.164 format)
otpstringYes6-digit OTP code
namestringOptionalPlayer's display name
callbackfunctionYesCalled with creation result
info

The name parameter is optional but recommended. If omitted, a default name will be assigned. Players can update their name later using updateProfile.

Response Format

The callback receives:

{
success: boolean; // true if account created
msg?: string; // Error message (if failed)
statuscode?: number; // Error code (if failed)
}

Success Response

{
success: true
}

After successful account creation, the SDK's loginCallback is automatically called with the new player's data.

Error Response

{
success: false,
msg: 'Account already exists',
statuscode: 107
}

Common Status Codes

CodeMeaningAction
0SuccessAccount created and logged in
102Invalid OTPAsk player to re-enter OTP
104OTP expiredGenerate new OTP
107Account already existsUse loginWithOtp instead
108Invalid nameAsk player to choose different name

Complete Registration Flow

Here's a complete registration flow with email/OTP:

const GAME_ID = 'my-game-id';

// Step 1: Player enters email
function showRegistrationForm() {
const email = prompt('Enter your email:');

if (!email || !isValidEmail(email)) {
alert('Please enter a valid email');
return;
}

requestOtpForRegistration(email);
}

// Step 2: Generate OTP
function requestOtpForRegistration(emailid) {
showLoading('Sending verification code...');

MoitribeSDK(GAME_ID, 'genOtp', {
emailid: emailid,
callback: (result) => {
hideLoading();

if (result.success) {
showOtpAndNameInput(emailid);
} else {
alert('Failed to send code: ' + result.msg);
}
}
});
}

// Step 3: Player enters OTP and name
function showOtpAndNameInput(emailid) {
const otp = prompt(`Enter the 6-digit code sent to ${emailid}:`);

if (!otp || otp.length !== 6) {
alert('Please enter a valid 6-digit code');
showOtpAndNameInput(emailid);
return;
}

const name = prompt('Choose a display name:');

if (!name || name.trim().length === 0) {
alert('Please enter a name');
showOtpAndNameInput(emailid);
return;
}

createAccount(emailid, otp, name);
}

// Step 4: Create account
function createAccount(emailid, otp, name) {
showLoading('Creating account...');

MoitribeSDK(GAME_ID, 'createWithOtp', {
emailid: emailid,
otp: otp,
name: name,
callback: (result) => {
hideLoading();

if (result.success) {
console.log('Account created successfully!');
// SDK automatically calls loginCallback with player data
} else {
handleRegistrationError(result, emailid);
}
}
});
}

// Step 5: Handle errors
function handleRegistrationError(result, emailid) {
if (result.statuscode === 102) {
alert('Invalid code. Please try again.');
showOtpAndNameInput(emailid);
} else if (result.statuscode === 104) {
alert('Code expired. Requesting a new one...');
requestOtpForRegistration(emailid);
} else if (result.statuscode === 107) {
alert('This email is already registered. Please log in.');
loginInstead(emailid);
} else if (result.statuscode === 108) {
alert('This name is not available. Please choose another.');
showOtpAndNameInput(emailid);
} else {
alert('Registration failed: ' + (result.msg || 'Unknown error'));
}
}

function isValidEmail(email) {
return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email);
}

Receiving Player Data

After successful registration, the SDK calls the loginCallback with new player data:

MoitribeSDK('my-game-id', 'init', {
loginCallback: (result) => {
if (result.success) {
// This is called after successful createWithOtp
const player = result.playerdata;

console.log('New player created:', player.name);
console.log('Player ID:', player.id);
console.log('Email:', player.emailid);

// Show welcome message
showWelcomeScreen(player);

// Start game
startGame(player);
}
}
});

TypeScript Example

import MoitribeSDK from '@veniso/moitribe-js';

interface CreateAccountResult {
success: boolean;
msg?: string;
statuscode?: number;
}

interface CreateAccountParams {
emailid?: string;
phno?: string;
otp: string;
name?: string;
callback: (result: CreateAccountResult) => void;
}

const GAME_ID = 'my-game-id';

function createAccountWithEmail(
email: string,
otp: string,
name: string
): void {
if (!isValidEmail(email)) {
showError('Invalid email address');
return;
}

if (!isValidOtp(otp)) {
showError('Invalid OTP format');
return;
}

if (!isValidName(name)) {
showError('Name must be 3-20 characters');
return;
}

const params: CreateAccountParams = {
emailid: email,
otp: otp,
name: name,
callback: (result: CreateAccountResult) => {
if (result.success) {
console.log('Account created successfully');
// SDK loginCallback will be called
} else {
handleRegistrationError(result);
}
}
};

MoitribeSDK(GAME_ID, 'createWithOtp', params);
}

function isValidEmail(email: string): boolean {
return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email);
}

function isValidOtp(otp: string): boolean {
return /^\d{6}$/.test(otp);
}

function isValidName(name: string): boolean {
return name.length >= 3 && name.length <= 20;
}

function handleRegistrationError(result: CreateAccountResult): void {
switch (result.statuscode) {
case 102:
showError('Invalid OTP. Please try again.');
break;
case 104:
showError('OTP expired. Please request a new one.');
break;
case 107:
showError('Account already exists. Please log in.');
navigateToLogin();
break;
case 108:
showError('Name not available. Please choose another.');
break;
default:
showError(result.msg || 'Registration failed. Please try again.');
}
}

Name Validation

Validate player names before submitting:

function isValidName(name) {
// 3-20 characters, letters, numbers, spaces, underscores
const nameRegex = /^[a-zA-Z0-9 _]{3,20}$/;
return nameRegex.test(name);
}

function validateAndCreateAccount(emailid, otp, name) {
// Trim whitespace
const trimmedName = name.trim();

if (trimmedName.length < 3) {
showError('Name must be at least 3 characters');
return;
}

if (trimmedName.length > 20) {
showError('Name must be no more than 20 characters');
return;
}

if (!isValidName(trimmedName)) {
showError('Name can only contain letters, numbers, spaces, and underscores');
return;
}

// Proceed with registration
MoitribeSDK('my-game-id', 'createWithOtp', {
emailid: emailid,
otp: otp,
name: trimmedName,
callback: handleResult
});
}

Handling Existing Accounts

If account already exists, redirect to login:

MoitribeSDK('my-game-id', 'createWithOtp', {
emailid: 'existing@example.com',
otp: '123456',
name: 'PlayerName',
callback: (result) => {
if (result.success) {
console.log('Account created');
} else if (result.statuscode === 107) {
// Account already exists
showDialog({
title: 'Account Exists',
message: 'An account with this email already exists. Would you like to log in?',
buttons: [
{
text: 'Log In',
action: () => {
// Redirect to login with same OTP
loginWithExistingOtp('existing@example.com', '123456');
}
},
{
text: 'Use Different Email',
action: () => showRegistrationForm()
}
]
});
}
}
});

function loginWithExistingOtp(emailid, otp) {
MoitribeSDK('my-game-id', 'loginWithOtp', {
emailid: emailid,
otp: otp,
callback: (result) => {
if (result.success) {
console.log('Logged in successfully');
}
}
});
}

Registration Form Example

Complete HTML registration form:

<div id="registration-form">
<h2>Create Your Account</h2>

<div id="step-1">
<input type="email" id="email-input" placeholder="Email address">
<button onclick="sendOtp()">Send Code</button>
</div>

<div id="step-2" style="display: none;">
<p>Enter the code sent to <span id="email-display"></span></p>
<input type="text" id="otp-input" placeholder="6-digit code" maxlength="6">
<input type="text" id="name-input" placeholder="Display name">
<button onclick="createAccount()">Create Account</button>
<button onclick="resendOtp()">Resend Code</button>
</div>
</div>

<script>
let currentEmail = '';

function sendOtp() {
const email = document.getElementById('email-input').value;

if (!isValidEmail(email)) {
alert('Please enter a valid email');
return;
}

currentEmail = email;

MoitribeSDK('my-game-id', 'genOtp', {
emailid: email,
callback: (result) => {
if (result.success) {
document.getElementById('step-1').style.display = 'none';
document.getElementById('step-2').style.display = 'block';
document.getElementById('email-display').textContent = email;
} else {
alert('Failed to send code: ' + result.msg);
}
}
});
}

function createAccount() {
const otp = document.getElementById('otp-input').value;
const name = document.getElementById('name-input').value;

if (!otp || otp.length !== 6) {
alert('Please enter the 6-digit code');
return;
}

if (!name || name.trim().length < 3) {
alert('Please enter a name (at least 3 characters)');
return;
}

MoitribeSDK('my-game-id', 'createWithOtp', {
emailid: currentEmail,
otp: otp,
name: name.trim(),
callback: (result) => {
if (result.success) {
alert('Account created successfully!');
// SDK will call loginCallback
} else {
if (result.statuscode === 107) {
alert('Account already exists. Redirecting to login...');
// Switch to login flow
} else {
alert('Registration failed: ' + result.msg);
}
}
}
});
}

function resendOtp() {
sendOtp();
}

function isValidEmail(email) {
return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email);
}
</script>

Best Practices

1. Welcome New Players

Show a welcome message after successful registration:

MoitribeSDK('my-game-id', 'init', {
loginCallback: (result) => {
if (result.success && result.playerdata) {
showWelcomeDialog({
title: `Welcome, ${result.playerdata.name}!`,
message: 'Your account has been created successfully. Let\'s get started!',
action: () => startTutorial()
});
}
}
});

2. Suggest Usernames

Help players choose available names:

function suggestUsernames(email) {
const username = email.split('@')[0];
const suggestions = [
username,
username + Math.floor(Math.random() * 1000),
username + '_' + new Date().getFullYear()
];

return suggestions;
}

3. Show Password-Free Benefit

Explain the advantage of OTP authentication:

showMessage(
'No Password Required',
'We\'ll send you a code each time you log in. No password to remember!'
);

4. Collect Additional Info Later

Don't overwhelm new players. Collect only essential information during registration:

// Minimal registration
MoitribeSDK('my-game-id', 'createWithOtp', {
emailid: email,
otp: otp,
name: name,
callback: (result) => {
if (result.success) {
// Update profile later
promptForAdditionalInfo();
}
}
});

function promptForAdditionalInfo() {
// Show optional profile completion during gameplay
setTimeout(() => {
showProfileCompletionPrompt();
}, 60000); // After 1 minute
}
tip

Keep registration as simple as possible. Only require email/phone, OTP, and name. Collect additional information later to reduce friction.

Next Steps

After creating an account:

Related authentication topics: