What are Game Tokens?
Game tokens are cryptocurrencies that power your game economy. Players can earn tokens for achievements, spend them on items, or trade them with other players.
Tokens exist on the blockchain, so players truly own them. They can hold, trade, or sell tokens even outside your game.
Token Use Cases
Play-to-Earn
- Reward players with tokens for completing levels
- Players can sell earned tokens for real money
In-Game Currency
- Use tokens to buy items, upgrades, or cosmetics
- More transparent than traditional in-game currencies
Governance
- Token holders vote on game updates
- Community-driven game development
Staking
- Players stake tokens to earn rewards
- Incentivizes long-term holding
Creating a Game Token
G3Engine makes it easy to launch your own token:
Using Pump.fun (Solana)
Pump.fun is the easiest way to launch a Solana token:
import { executeTokenLaunch } from '@/lib/web3Runtime';
const result = await executeTokenLaunch(
ctx,
"My Game Token", // Token name
"MGT", // Token symbol
"https://cdn.game.com/token-logo.png" // Token image
);
console.log(`Token created: ${result.tokenMint}`);
console.log(`Transaction: ${result.txHash}`);
Pump.fun tokens start on a bonding curve. As players buy, the price increases. Once enough liquidity is reached, the token “graduates” to Raydium DEX.
Token Info Structure
export interface TokenInfo {
mint: string; // Unique token address
name: string; // "My Game Token"
symbol: string; // "MGT" (2-5 characters)
balance: number; // Player's balance
decimals: number; // Precision (usually 9 for Solana, 18 for EVM)
imageUri?: string; // Token logo URL
// Pump.fun specific
isPumpToken?: boolean; // Launched on Pump.fun?
bondingCurveComplete?: boolean; // Graduated to DEX?
priceInSol?: number; // Current price
}
Example Token
const gameToken: TokenInfo = {
mint: "7xKXtg2CW87d97TXJSDpbD5jBkheTqA83TZRuJosgAsU",
name: "Adventure Quest Token",
symbol: "AQT",
balance: 1000,
decimals: 9,
imageUri: "https://cdn.game.com/aqt-logo.png",
isPumpToken: true,
bondingCurveComplete: false,
priceInSol: 0.00001
}
Game Economy Configuration
Configure how tokens work in your game:
export interface GameEconomyConfig {
rewardTokenMint: string | null; // Which token to use for rewards
rewardPerLevel: number; // Tokens earned per level
tipJarEnabled: boolean; // Can players tip each other?
itemPrices: Array<{ // In-game item prices
itemId: string; // Item identifier
priceToken: string; // Which token to use
amount: number; // How many tokens
}>;
}
Example Economy
const economy: GameEconomyConfig = {
rewardTokenMint: "7xKXtg2CW87d97TXJSDpbD5jBkheTqA83TZRuJosgAsU",
rewardPerLevel: 10,
tipJarEnabled: true,
itemPrices: [
{
itemId: "sword_legendary",
priceToken: "7xKXtg2CW87d97TXJSDpbD5jBkheTqA83TZRuJosgAsU",
amount: 100
},
{
itemId: "health_potion",
priceToken: "7xKXtg2CW87d97TXJSDpbD5jBkheTqA83TZRuJosgAsU",
amount: 5
}
]
}
Rewarding Players
Give players tokens for achievements:
Level Completion Rewards
Use the Blueprint “Reward Player” node or call directly:
import { executeBuyToken } from '@/lib/web3Runtime';
// When player completes a level
const rewardAmount = economy.rewardPerLevel;
// Transfer tokens to player
await airdropTokens(
playerWalletAddress,
economy.rewardTokenMint,
rewardAmount
);
Achievement Rewards
const achievements = [
{ id: 'first_win', reward: 50 },
{ id: 'speed_run', reward: 100 },
{ id: 'perfect_game', reward: 500 }
];
// When player unlocks achievement
const achievement = achievements.find(a => a.id === unlockedId);
if (achievement) {
await airdropTokens(
playerWalletAddress,
economy.rewardTokenMint,
achievement.reward
);
}
Make sure you have enough tokens in your treasury wallet to distribute rewards. Running out of tokens will break your reward system.
Token-Gated Content
Require players to hold tokens to access content:
import { executeTokenGate } from '@/lib/web3Runtime';
const result = await executeTokenGate(
ctx,
economy.rewardTokenMint, // Which token to check
100 // Minimum balance required
);
if (result.hasAccess) {
// Player has enough tokens, grant access
unlockPremiumLevel();
} else {
// Show "You need 100 tokens to access this"
showTokenGateMessage(100 - result.balance);
}
Buying and Selling Tokens
Let players trade tokens:
Buying Tokens (Pump.fun)
import { executeBuyToken } from '@/lib/web3Runtime';
const result = await executeBuyToken(
ctx,
tokenMint, // Which token to buy
0.1, // Amount of SOL to spend
1 // Slippage tolerance (1%)
);
addNotification(`Bought ${result.tokensReceived} tokens!`);
Selling Tokens (Pump.fun)
import { executeSellToken } from '@/lib/web3Runtime';
const result = await executeSellToken(
ctx,
tokenMint, // Which token to sell
1000, // Number of tokens to sell
1 // Slippage tolerance (1%)
);
addNotification(`Sold for ${result.solReceived} SOL!`);
Slippage tolerance is how much price change you’ll accept. 1% means the transaction fails if price moves more than 1% before it confirms.
Viewing Player Tokens
Display all tokens a player owns:
import { useWeb3Store } from '@/store/web3Store';
function TokenList() {
const { tokens } = useWeb3Store();
return (
<div>
<h2>Your Tokens</h2>
{tokens.map(token => (
<div key={token.mint}>
{token.imageUri && <img src={token.imageUri} alt={token.name} />}
<h3>{token.name} ({token.symbol})</h3>
<p>Balance: {token.balance.toLocaleString()}</p>
{token.priceInSol && (
<p>Price: {token.priceInSol} SOL</p>
)}
</div>
))}
</div>
);
}
Token Pricing
Get the current price of a token:
import { executeGetTokenPrice } from '@/lib/web3Runtime';
const result = await executeGetTokenPrice(ctx, tokenMint);
console.log(`Price: ${result.priceInSol} SOL`);
console.log(`Market Cap: ${result.marketCap} SOL`);
In-Game Store
Let players buy items with tokens:
function GameStore() {
const { economy, tokens } = useWeb3Store();
const buyItem = async (item: typeof economy.itemPrices[0]) => {
// Check if player has enough tokens
const playerToken = tokens.find(t => t.mint === item.priceToken);
if (!playerToken || playerToken.balance < item.amount) {
alert('Not enough tokens!');
return;
}
// Transfer tokens from player to game treasury
await transferTokens(
item.priceToken,
item.amount,
gameTreasuryAddress
);
// Give player the item
givePlayerItem(item.itemId);
};
return (
<div>
{economy.itemPrices.map(item => (
<div key={item.itemId}>
<h3>{item.itemId}</h3>
<p>Price: {item.amount} tokens</p>
<button onClick={() => buyItem(item)}>Buy</button>
</div>
))}
</div>
);
}
Token Transfers
Players can send tokens to each other:
// Send tokens from one player to another
async function transferTokens(
tokenMint: string,
amount: number,
recipientAddress: string
) {
// Implementation depends on blockchain:
// - Solana: SPL Token transfer
// - EVM: ERC-20 transfer
const tx = await createTokenTransfer(
tokenMint,
amount,
recipientAddress
);
await ctx.signTransaction(tx);
return tx.signature;
}
Tip Jar
Let players tip each other:
if (economy.tipJarEnabled) {
const tipPlayer = async (recipientAddress: string, amount: number) => {
await transferTokens(
economy.rewardTokenMint,
amount,
recipientAddress
);
addNotification(`Tipped ${amount} tokens!`);
};
}
Checking Token Balance
Check a specific token balance:
import { executeCheckBalance } from '@/lib/web3Runtime';
const result = await executeCheckBalance(ctx, tokenMint);
console.log(`Balance: ${result.balance}`);
Token State Management
The Web3 store manages token state:
const web3Store = useWeb3Store();
// Add a token to the list
web3Store.addToken({
mint: "...",
name: "New Token",
symbol: "NEW",
balance: 0,
decimals: 9
});
// Update all tokens
web3Store.setTokens(newTokenList);
// Update economy config
web3Store.updateEconomy({
rewardPerLevel: 20 // Increase rewards
});
Best Practices
Token economies are complex. Start simple and iterate based on player behavior.
Do’s
- Start with conservative reward rates
- Monitor token supply and inflation
- Provide multiple ways to earn AND spend tokens
- Test thoroughly on devnet/testnet first
- Be transparent about tokenomics
Don’ts
- Don’t promise financial returns (legal issues)
- Don’t make rewards too easy to farm
- Don’t lock players out if they run out of tokens
- Don’t make sudden economy changes without notice
- Don’t launch on mainnet without auditing
Transaction History
Track all token transactions:
export interface Web3Transaction {
id: string;
type: 'token_launch' | 'buy' | 'sell' | 'transfer' | 'airdrop';
signature: string; // Blockchain transaction hash
status: 'pending' | 'confirmed' | 'failed';
description: string;
timestamp: number;
}
const { transactions } = useWeb3Store();
// Show recent transactions
transactions
.filter(tx => tx.type === 'buy' || tx.type === 'sell')
.forEach(tx => {
console.log(`${tx.type}: ${tx.status} - ${tx.description}`);
});
Next Steps
NFT Support
Add NFT collectibles to your game
Solana Integration
Deep dive into Solana features