417 lines
11 KiB
Markdown
417 lines
11 KiB
Markdown
# 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)
|
|
1. **PageLevel.ts** (786 lines) - Main gameplay, hint system, answer validation
|
|
2. **LevelDataManager.ts** (312 lines) - API calls, level caching, image loading
|
|
3. **StorageManager.ts** (240 lines) - Lives & progress persistence
|
|
4. **PageLoading.ts** (88 lines) - App initialization, preloading
|
|
|
|
### UI/Navigation (3 files)
|
|
5. **ViewManager.ts** (320 lines) - Page stack management
|
|
6. **BaseView.ts** (132 lines) - View lifecycle
|
|
7. **PassModal.ts** (155 lines) - Victory screen with rewards
|
|
|
|
### Utilities (5 files)
|
|
8. **ToastManager.ts** (59 lines) - Toast notifications
|
|
9. **WxSDK.ts** (188 lines) - WeChat API wrapper
|
|
10. **HttpUtil.ts** (76 lines) - HTTP requests
|
|
11. **Toast.ts** (50 lines) - Toast display component
|
|
12. **LevelTypes.ts** (59 lines) - TypeScript interfaces
|
|
|
|
### Prefabs & Entry Points (3 files)
|
|
13. **PageHome.ts** (78 lines) - Home page
|
|
14. **main.ts** (59 lines) - App entry point
|
|
15. 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
|
|
```javascript
|
|
{
|
|
"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
|
|
1. **Level 1 Always Unlocked** - New players start here
|
|
2. **Sequential Unlocking** - Beat level N to unlock level N+1
|
|
3. **Non-Linear Progress** - Can replay earlier levels anytime
|
|
4. **Max Tracking** - Tracks highest level reached for achievements
|
|
|
|
### Data Structure
|
|
```typescript
|
|
{
|
|
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
|
|
```typescript
|
|
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
|
|
1. Load level image from API cache
|
|
2. Display Hint 1 (free) + two "Unlock" buttons
|
|
3. Start 60-second countdown
|
|
4. Player can:
|
|
- Unlock hints by spending lives (optional, repeatable)
|
|
- Type their answer in single text box
|
|
- Submit answer
|
|
5. 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
|
|
```typescript
|
|
{
|
|
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
|
|
1. **Sharing** - Share game to friends with level parameter
|
|
2. **Vibration** - Haptic feedback on errors
|
|
3. **Platform Detection** - Gracefully degrade on non-WeChat platforms
|
|
|
|
### Share Implementation
|
|
```typescript
|
|
// 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
|
|
1. **Detect New vs. Returning User**
|
|
- Check localStorage "game_lives" key
|
|
- New: Initialize to 10
|
|
- Returning: Restore value
|
|
|
|
2. **Load Level Metadata**
|
|
- API call to fetch all levels
|
|
- Retry up to 2 times on failure
|
|
- Cache all level data in memory
|
|
|
|
3. **Preload First Level**
|
|
- Download image for level 1
|
|
- Cache in memory for instant display
|
|
|
|
4. **Show Home Screen**
|
|
- Display "Start Game" button
|
|
- Initialize WeChat sharing
|
|
|
|
### On Subsequent Game Sessions
|
|
1. Restore lives from localStorage
|
|
2. Restore progress from localStorage
|
|
3. Resume at saved level
|
|
4. 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
|
|
```typescript
|
|
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
|
|
|
|
1. **Image Caching** - Downloaded images cached in memory
|
|
2. **Level Metadata Caching** - API data cached to avoid re-fetching
|
|
3. **Progress Caching** - localStorage data cached to reduce reads
|
|
4. **Async Preloading** - Next level preloaded silently
|
|
5. **Efficient UI** - Single EditBox (not per-character)
|
|
6. **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
|
|
|
|
1. **GAME_ANALYSIS.md** - Comprehensive 17-section analysis (13KB)
|
|
2. **QUICK_REFERENCE.md** - Quick lookup guide (5.6KB)
|
|
3. **POINTS_FLOW_DIAGRAM.md** - Visual flow diagrams (15KB)
|
|
4. **SUMMARY.md** - This executive summary (8KB)
|
|
|
|
**Total:** 42KB of detailed documentation covering every aspect of the points/score/lives system.
|
|
|