Skip to main content

Decentralized JavaScript Games with Internet Identity

Learn how to build pure JavaScript games with Internet Identity authentication and deploy them on the Internet Computer Protocol for decentralized gaming experiences

Decentralized JavaScript Games with Internet Identity

Introduction

Learn how to create simple, pure JavaScript games with Internet Identity authentication and host them on the Internet Computer Protocol (ICP) for truly decentralized gaming experiences.

Why Decentralized Games?

Traditional web games rely on centralized servers, leaving users vulnerable to data loss, privacy concerns, and platform shutdowns. By hosting games on ICP with Internet Identity, you can create:

  • Truly owned user accounts - Players control their identity
  • Permanent deployment - Games live on the blockchain
  • No backend servers - Pure JavaScript frontends with smart contract storage
  • Privacy-first - No email or password required
  • Cross-platform identity - One identity across all ICP dApps

What is Internet Identity?

Internet Identity is ICP's decentralized authentication system that provides:

  • Anonymous, cryptographic authentication
  • No passwords or email addresses
  • Biometric support (fingerprint, face recognition)
  • Multi-device sync
  • Complete user privacy

Building Your First Decentralized Game

Prerequisites

  • Node.js and npm installed
  • DFX (Internet Computer SDK)
  • Basic JavaScript knowledge
  • Understanding of HTML5 Canvas or game frameworks

Project Setup

		# Install DFX
sh -ci "$(curl -fsSL https://internetcomputer.org/install.sh)"
 
# Create new project
dfx new my-game --type=motoko
cd my-game
	

Integrating Internet Identity

		import { AuthClient } from "@dfinity/auth-client";
 
let authClient;
 
async function init() {
  authClient = await AuthClient.create();
 
  if (await authClient.isAuthenticated()) {
    handleAuthenticated();
  }
}
 
async function login() {
  await authClient.login({
    identityProvider: "https://identity.ic0.app",
    onSuccess: handleAuthenticated,
  });
}
 
function handleAuthenticated() {
  const identity = authClient.getIdentity();
  const principal = identity.getPrincipal().toString();
  console.log("Logged in as:", principal);
  // Start game with authenticated user
}
	

Simple Game Example - Click Battle

Here's a simple example using pure JavaScript and HTML5 Canvas:

		// game.js - Simple click counter game
let score = 0;
let authenticated = false;
let playerPrincipal = "";
 
class Game {
  constructor() {
    this.canvas = document.getElementById('gameCanvas');
    this.ctx = this.canvas.getContext('2d');
    this.setupAuth();
  }
 
  async setupAuth() {
    this.authClient = await AuthClient.create();
    if (await this.authClient.isAuthenticated()) {
      this.onAuthenticated();
    }
  }
 
  async login() {
    await this.authClient.login({
      identityProvider: "https://identity.ic0.app",
      onSuccess: () => this.onAuthenticated(),
    });
  }
 
  onAuthenticated() {
    const identity = this.authClient.getIdentity();
    playerPrincipal = identity.getPrincipal().toString();
    authenticated = true;
    this.loadScore();
    this.render();
  }
 
  async loadScore() {
    // Load score from ICP canister
    // const savedScore = await backend.getScore(playerPrincipal);
    // score = savedScore;
  }
 
  async saveScore() {
    // Save score to ICP canister
    // await backend.saveScore(playerPrincipal, score);
  }
 
  handleClick() {
    if (!authenticated) {
      alert("Please login first!");
      return;
    }
    score++;
    this.saveScore();
    this.render();
  }
 
  render() {
    this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);
    this.ctx.font = '30px Arial';
    this.ctx.fillText(`Score: ${score}`, 50, 50);
 
    if (authenticated) {
      this.ctx.font = '14px Arial';
      this.ctx.fillText(`Player: ${playerPrincipal.slice(0, 10)}...`, 50, 80);
    }
  }
}
 
const game = new Game();
	

Backend Canister for Score Storage

		// main.mo - Simple score storage
import HashMap "mo:base/HashMap";
import Principal "mo:base/Principal";
import Nat "mo:base/Nat";
import Hash "mo:base/Hash";
 
actor GameBackend {
 
  private var scores = HashMap.HashMap<Principal, Nat>(0, Principal.equal, Principal.hash);
 
  public shared(msg) func saveScore(score : Nat) : async () {
    scores.put(msg.caller, score);
  };
 
  public shared(msg) func getScore() : async ?Nat {
    scores.get(msg.caller)
  };
 
  public func getLeaderboard() : async [(Principal, Nat)] {
    var leaderboard : [(Principal, Nat)] = [];
    for ((principal, score) in scores.entries()) {
      leaderboard := Array.append(leaderboard, [(principal, score)]);
    };
    leaderboard
  };
}
	

Deployment to ICP

		# Start local replica
dfx start --background
 
# Deploy canisters
dfx deploy
 
# Get canister URL
dfx canister call my-game-frontend http_request '(record {url="/"; method="GET"; headers=vec{}; body=vec{}})'
	

Game Frameworks Compatible with ICP

Phaser.js

  • Popular 2D game framework
  • Large community and examples
  • Easy to integrate with Internet Identity

PixiJS

  • High-performance 2D rendering
  • WebGL support
  • Great for browser games

Babylon.js / Three.js

  • 3D game development
  • Advanced graphics capabilities
  • Can run entirely in browser

Pure JavaScript

  • No dependencies
  • Full control
  • Lightweight and fast

Best Practices

  1. Keep Game State On-Chain - Store critical data in canisters
  2. Use Internet Identity - Don't build custom auth
  3. Optimize Assets - Minimize canister storage costs
  4. Progressive Enhancement - Work offline, sync when online
  5. Test Locally - Use dfx for development before mainnet deployment

Example Projects

Click Battle

Simple click counter game with leaderboard

Decentralized Chess

Turn-based chess with on-chain game state

NFT Card Game

Collectible card game with NFT integration

Resources

Conclusion

Building decentralized games with Internet Identity and ICP combines the best of web gaming with blockchain benefits. Start simple with pure JavaScript, integrate Internet Identity for authentication, and deploy to ICP for a truly decentralized gaming experience. Your players will own their identities, and your games will live forever on the blockchain.