Since the PubNub MCP requires system-level environment configuration, here's a step-by-step manual setup guide.
-
Go to PubNub Dashboard
- Visit https://dashboard.pubnub.com
- Log in with your account
-
Create New App
- Click "Create New App"
- Name: "Swap It Game"
- Click "Create"
-
Create New Keyset
- In your new app, click "Create New Keyset"
- Name: "Swap It Production" (or "Development")
- Click "Create"
In your keyset settings, enable and configure:
- ✅ Enable: ON
- Retention: 7 days (or more)
- Delete from history: ON
- Include presence events: OFF
- ✅ Enable: ON
- Region: aws-iad-1 (or closest to you)
- User metadata events: OFF
- Channel metadata events: OFF
- Membership events: OFF
- Referential integrity: OFF
- Disallow get all user metadata: OFF
- Disallow get all channel metadata: OFF
- Enable: OFF (not needed for MVP)
- Enable: OFF (not needed for MVP)
- This will be enabled when you create a function module
From your keyset page, copy:
- Publish Key (starts with
pub-c-) - Subscribe Key (starts with
sub-c-)
-
Navigate to Functions
- In your keyset, click "Functions" in the left sidebar
- Click "Create New Module"
-
Create Module
- Module Name: "Swap It Game Logic"
- Description: "Server-side game logic for Swap It multiplayer game"
- Click "Create"
-
Add Event Handler
- In your module, click "Create New Event Handler"
- Type: "Before Publish or Fire"
- Name: "Game Move Handler"
- Channel:
game.*(with asterisk) - Click "Create"
-
Copy Function Code
- Open
server/before-publish-function.jsfrom this project - Copy the ENTIRE contents
- Paste into the function editor in PubNub dashboard
- Click "Save"
- Open
-
Enable KV Store
- In module settings (gear icon), toggle "KV Store" to ON
- Click "Save"
-
Start Module
- Click "Start Module" button
- Wait for status to show "Started" (green indicator)
Create .env file in the project root:
cd /Users/craig/Documents/gits/swapit
cat > .env << 'EOF'
VITE_PUBNUB_PUBLISH_KEY=YOUR_PUBLISH_KEY_HERE
VITE_PUBNUB_SUBSCRIBE_KEY=YOUR_SUBSCRIBE_KEY_HERE
EOFReplace YOUR_PUBLISH_KEY_HERE and YOUR_SUBSCRIBE_KEY_HERE with your actual keys.
In PubNub Dashboard:
-
Go to Functions → Your Module → KV Store Tab
-
Add New Item
- Click "Add New Item" button
-
Set Key and Value
- Key:
swapit:game:TESTGAME - Value (copy this exactly):
- Key:
{
"gameId": "TESTGAME",
"phase": "CREATED",
"players": ["player1", "player2"],
"winnerPlayerId": null,
"tiles": {},
"goalOrder": null,
"initialOrder": null,
"startTT": null,
"winTT": null,
"lockedTT": null
}- Save
- Install dependencies (if not already done):
npm install- Start development server:
npm run dev-
Open in browser: http://localhost:3000
-
Test multiplayer:
- Open two browser windows side by side
- Window 1: Enter name "Player 1", Game ID "TESTGAME", click "Join Existing Game"
- Window 2: Enter name "Player 2", Game ID "TESTGAME", click "Join Existing Game"
- Either window: Click "Start Game"
- Both should see tiles appear
- Click tiles to swap - should see moves sync instantly
Check:
- Module status is "Started" (green)
- Channel pattern is exactly
game.* - KV Store is enabled for module
- Look at Function Logs for errors
Fix:
- Restart module (Stop → Start)
- Check syntax errors in function code
- Verify KV Store toggle is ON
Problem: Client generates random player IDs, but test game has fixed IDs
Quick Fix:
Temporarily modify client/src/components/Lobby.jsx:
Find this line (~line 22 and ~line 38):
const playerId = generatePlayerId();Replace with:
const playerId = window.prompt('Enter player ID (player1 or player2):', 'player1');This lets you manually choose player1 or player2 to match the test game state.
Check:
.envfile exists in project root- Keys are on lines starting with
VITE_ - No quotes needed around values
- Restart dev server after creating
.env
Fix:
# Verify file contents
cat .env
# Should show:
# VITE_PUBNUB_PUBLISH_KEY=pub-c-xxxxx
# VITE_PUBNUB_SUBSCRIBE_KEY=sub-c-xxxxxCheck:
- Game exists in KV Store with key
swapit:game:TESTGAME - Phase is set to
"CREATED"(not LIVE or LOCKED) - Player IDs match what clients are using
Fix:
- Re-create game state in KV Store
- Use player ID matching prompt method above
- Check Function logs for error messages
Check:
- Function is running (green status)
- No errors in Function logs
- Game phase is LIVE (after clicking Start)
Fix:
- Check browser console for errors
- Verify PubNub keys in
.envare correct - Ensure Before Publish function saved correctly
Before testing, verify:
- ✅ PubNub app created
- ✅ Keyset created with Message Persistence + App Context
- ✅ Function module created and started
- ✅ Before Publish handler on channel
game.* - ✅ KV Store enabled for module
- ✅ Test game state exists in KV Store
- ✅
.envfile has publish and subscribe keys - ✅ Dev server running without errors
Once working:
- Create new games dynamically (see next section)
- Remove player ID prompt hack
- Add more players to test
- Deploy to production
For each new game, add to KV Store:
Key Format: swapit:game:{GAME_ID}
Example for game "ABC12345":
{
"gameId": "ABC12345",
"phase": "CREATED",
"players": ["player_xyz123", "player_abc789"],
"winnerPlayerId": null,
"tiles": {},
"goalOrder": null,
"initialOrder": null,
"startTT": null,
"winTT": null,
"lockedTT": null
}Note: Player IDs must match what clients will generate. For testing, keep using the player ID prompt method until you implement proper game creation.
Before going live:
- Remove player ID prompt hack
- Implement proper game registration flow
- Add game cleanup (delete old games)
- Enable Access Manager (PAM) for security
- Set up monitoring and alerts
- Test with real users
- Consider using production keyset
If you encounter issues:
- Check browser console for client errors
- Check PubNub Function logs for server errors
- Verify all steps completed correctly
- Review PUBNUB_SETUP.md for more details
- Contact PubNub support: https://support.pubnub.com
Once you see both players' boards updating in real-time and can complete a game with a winner, you're all set! The game is working correctly.