11 KiB
Game System Summary - Points/Score/Lives Analysis
Project: Cocos Creator WeChat Mini-Game ("写英语" - Write English)
Date Analyzed: April 5, 2026
Analysis Scope: Complete TypeScript codebase (21 source files)
Executive Summary
This game uses a LIVES-based economy rather than traditional points/coins:
- Currency: Lives (renewable resource)
- Starting Value: 10 lives per new player
- Earning Mechanic: +1 life per completed level
- Spending Mechanic: -1 life per hint unlock (optional, 2 hints available)
- Net Effect: Players naturally gain lives if they solve without hints, stay stable with 1 hint/level, or lose lives if using both hints
The system is fully persistent (saved to localStorage) and progression-aware (can replay earlier levels while advancing).
Files Analyzed (21 total)
Core Game Logic (4 files)
- PageLevel.ts (786 lines) - Main gameplay, hint system, answer validation
- LevelDataManager.ts (312 lines) - API calls, level caching, image loading
- StorageManager.ts (240 lines) - Lives & progress persistence
- PageLoading.ts (88 lines) - App initialization, preloading
UI/Navigation (3 files)
- ViewManager.ts (320 lines) - Page stack management
- BaseView.ts (132 lines) - View lifecycle
- PassModal.ts (155 lines) - Victory screen with rewards
Utilities (5 files)
- ToastManager.ts (59 lines) - Toast notifications
- WxSDK.ts (188 lines) - WeChat API wrapper
- HttpUtil.ts (76 lines) - HTTP requests
- Toast.ts (50 lines) - Toast display component
- LevelTypes.ts (59 lines) - TypeScript interfaces
Prefabs & Entry Points (3 files)
- PageHome.ts (78 lines) - Home page
- main.ts (59 lines) - App entry point
- Plus UI utilities (BackgroundScaler, RoundedRectMask)
The Complete Points/Lives Flow
🟢 EARNING Lives
| Event | Amount | Condition |
|---|---|---|
| Correct Answer | +1 | Submitted answer matches API answer exactly (case-sensitive, trimmed) |
| New Game | +10 | First time players only (default) |
| Cannot Earn | 0 | Wrong answers, timeouts, hint unlocks, returning players don't reset |
🔴 SPENDING Lives
| Event | Amount | Condition |
|---|---|---|
| Unlock Hint 2 | -1 | Player clicks unlock, must have lives > 0 |
| Unlock Hint 3 | -1 | Player clicks unlock, must have lives > 0 |
| No Other Costs | - | No penalties for wrong answers or timeouts |
📊 Net Economy Per Level
Best Case (No Hints): +1 life/level → Infinite scaling
Average Case (1 Hint): 0 lives/level → Stable indefinitely
Hard Case (2 Hints): -1 life/level → Runs out after 10-20 levels
Data Persistence
localStorage Keys
{
"game_lives": "10", // Current lives count
"game_progress": "{ // Player progression
\"currentLevelIndex\": 0,
\"maxUnlockedLevelIndex\": 0
}"
}
Lifespan
- Initial: Set when first loading game
- Updates: Every level completion or hint unlock
- Persistence: Survives app close/reopen (native browser storage)
- Manual Reset: Available via
StorageManager.resetAll()
Level Progression System
Mechanics
- Level 1 Always Unlocked - New players start here
- Sequential Unlocking - Beat level N to unlock level N+1
- Non-Linear Progress - Can replay earlier levels anytime
- Max Tracking - Tracks highest level reached for achievements
Data Structure
{
currentLevelIndex: number, // Which level to play next (0-based)
maxUnlockedLevelIndex: number // Highest level player has beaten
}
Example Progression
User beats Level 3 (index 2)
↓
currentLevelIndex → 2+1 = 3 (level 4)
maxUnlockedLevelIndex → max(2, previous) = 2
↓
Can now play levels 0-3
Must complete level 3 to unlock level 4
Hint System
Mechanics
- Hint 1: Always visible, completely free
- Hint 2: Hidden by default, costs 1 life to unlock
- Hint 3: Hidden by default, costs 1 life to unlock
Implementation
onUnlockClue(index: 2|3) {
if (!hasLives()) return; // Must have >= 1 life
consumeLife(); // Deduct 1 life
showClue(index); // Reveal the clue content
}
Strategic Element
Players must decide if they want to spend lives for hints or solve blindly to accumulate more lives for future levels.
Gameplay Loop
Per-Level Sequence
- Load level image from API cache
- Display Hint 1 (free) + two "Unlock" buttons
- Start 60-second countdown
- Player can:
- Unlock hints by spending lives (optional, repeatable)
- Type their answer in single text box
- Submit answer
- Outcome:
- Correct: Reward +1 life, show victory modal
- Wrong: No penalty, show error toast, can retry
- Timeout: Play fail sound, can still submit
Victory Rewards
onSubmitAnswer(userAnswer) {
if (userAnswer.trim() === correctAnswer) {
playSuccessSound();
addLife(); // +1 life
StorageManager.onLevelCompleted(currentLevel);
showPassModal(); // Next/Share buttons
}
}
API Integration
Endpoint
GET https://ilookai.cn/api/v1/wechat-game/levels
Response Format
{
success: boolean,
message: string | null,
data: {
levels: [
{
id: "uuid",
level: 1,
imageUrl: "https://...",
hint1: "Free clue",
hint2: "Paid clue",
hint3: "Paid clue",
answer: "CORRECT_ANSWER",
sortOrder: 1
},
// ... more levels
],
total: number
}
}
Reliability Features
- Retry Logic: 2 attempts on failure
- Timeout: 8 seconds per request
- Fallback: Shows error message if all retries fail
- Caching: All levels cached in memory after first load
WeChat Integration
Features Implemented
- Sharing - Share game to friends with level parameter
- Vibration - Haptic feedback on errors
- Platform Detection - Gracefully degrade on non-WeChat platforms
Share Implementation
// On victory, user can click "Share"
WxSDK.shareAppMessage({
title: "快来一起玩这款游戏吧",
query: `level=${victoryLevelIndex}`
});
// Opens WeChat share dialog with referral link
Not Implemented
- ❌ User authentication (wx.login)
- ❌ Backend progress sync
- ❌ Analytics
- ❌ Ads/Monetization
- ❌ Leaderboards
User Journey Example
New User Opens Game
↓
[Initialize: 10 lives, Level 1]
↓
Attempt Level 1
├─ Unlocks Hint 2 (-1 life) → 9 lives
├─ Unlocks Hint 3 (-1 life) → 8 lives
├─ Submits Answer
│
├─ CORRECT
│ ├─ Awards +1 life → 9 lives
│ ├─ Saves progress (level → 2)
│ └─ Shows PassModal
│ ├─ Can click "Next Level" → Level 2
│ └─ Can click "Share" → wx.share
│
└─ WRONG
├─ No penalty → 9 lives unchanged
├─ Shows error toast
└─ Can retry immediately
Loading & Initialization
On App Start
-
Detect New vs. Returning User
- Check localStorage "game_lives" key
- New: Initialize to 10
- Returning: Restore value
-
Load Level Metadata
- API call to fetch all levels
- Retry up to 2 times on failure
- Cache all level data in memory
-
Preload First Level
- Download image for level 1
- Cache in memory for instant display
-
Show Home Screen
- Display "Start Game" button
- Initialize WeChat sharing
On Subsequent Game Sessions
- Restore lives from localStorage
- Restore progress from localStorage
- Resume at saved level
- API already cached (no refetch unless app restarted)
Key Constants
| Constant | Value | Usage |
|---|---|---|
| DEFAULT_LIVES | 10 | New player starting amount |
| MIN_LIVES | 0 | Cannot go negative |
| LEVEL_TIME_LIMIT | 60 seconds | Countdown timer |
| API_TIMEOUT | 8000ms | HTTP request timeout |
| API_RETRY_COUNT | 2 | Attempts on failure |
| HINT_COST | 1 life each | Unlock clue 2 or 3 |
| WIN_REWARD | 1 life | Completion bonus |
| MODAL_Z_INDEX | 999 | Victory modal layer |
Business Logic Highlights
Win Condition
userAnswer.trim() === correctAnswer
- Case-sensitive
- Whitespace trimmed
- Must match exactly
No Lose Condition
- Wrong answers: No penalty
- Time up: No penalty
- Can retry infinitely on same level
Safety Checks
- Can't unlock hints if lives ≤ 0
- Can't go below 0 lives
- Can't exceed total levels
- Invalid data resets to defaults
Performance Optimizations
- Image Caching - Downloaded images cached in memory
- Level Metadata Caching - API data cached to avoid re-fetching
- Progress Caching - localStorage data cached to reduce reads
- Async Preloading - Next level preloaded silently
- Efficient UI - Single EditBox (not per-character)
- Lazy Loading - Pages cached after first load
Missing Features / Gaps
| Feature | Status | Impact |
|---|---|---|
| User Authentication | ❌ | No way to sync across devices |
| Backend Progress Save | ❌ | Progress lost if localStorage clears |
| Monetization | ❌ | No revenue stream |
| Ads | ❌ | No ad integration |
| Analytics | ❌ | Can't track player behavior |
| Leaderboards | ❌ | No competition mechanics |
| Sound Toggle | ❌ | Always plays sounds |
| Difficulty Levels | ❌ | All players see same levels |
Testing Scenarios
Test Case 1: Lives Economy
1. New game → 10 lives
2. Beat level without hints → 11 lives
3. Beat level with 1 hint → 11 lives (net 0)
4. Beat level with 2 hints → 10 lives (net -1)
→ Verify localStorage updated after each
Test Case 2: Progression
1. Complete level 1
2. Verify currentLevel → 2
3. Verify maxUnlocked → 1
4. Restart app
5. Verify levels still saved
6. Replay level 1
7. Verify no duplicate progress
Test Case 3: Hint Cost
1. Start with 10 lives
2. Unlock hint 2 → 9 lives displayed
3. Unlock hint 3 → 8 lives displayed
4. Can't unlock again (button inactive)
5. Wrong answer → 8 lives still
6. Correct answer → 9 lives (net -1)
Conclusion
This is a well-architected mini-game with:
- ✅ Clear lives-based economy
- ✅ Persistent progress tracking
- ✅ Strategic hint system
- ✅ Reliable API integration
- ✅ Good error handling
- ✅ WeChat platform integration
The point system is intentionally forgiving - players who solve puzzles smartly gain lives indefinitely, while those using hints maintain stability. This encourages skill development without hard progress walls.
Documentation Files Generated
- GAME_ANALYSIS.md - Comprehensive 17-section analysis (13KB)
- QUICK_REFERENCE.md - Quick lookup guide (5.6KB)
- POINTS_FLOW_DIAGRAM.md - Visual flow diagrams (15KB)
- SUMMARY.md - This executive summary (8KB)
Total: 42KB of detailed documentation covering every aspect of the points/score/lives system.