# ASETQU Game SDK Documentation

## Overview
Panduan untuk developer game agar bisa terintegrasi dengan platform ASETQU dan mengirim score secara otomatis.

## Why SDK Integration is Required

### The Canvas Rendering Problem
Most modern game engines (Construct 3, Unity WebGL, Phaser, etc.) render everything inside a `<canvas>` element, including score displays. This creates a technical limitation:

- **Canvas is bitmap-based**: All text, numbers, and graphics are rendered as pixels
- **No HTML text nodes**: The score you see on screen (e.g., "Score: 150") is NOT accessible as HTML text
- **DOM scanning fails**: JavaScript cannot "read" text that's drawn on canvas

**Example:**
```html
<!-- What we CAN'T detect automatically -->
<canvas id="game-canvas">
  <!-- Score "150" is drawn here as pixels, not text -->
</canvas>

<!-- What we CAN detect automatically -->
<div id="score">150</div>
```

### Auto-Detection Limitations
The ASETQU platform automatically injects a bridge script that attempts to detect scores by:
1. ✅ Scanning HTML text nodes for patterns like "Score: 100"
2. ✅ Looking for `data-score` attributes on elements
3. ❌ **Cannot** read text rendered inside canvas
4. ❌ **Cannot** access game runtime in Worker mode (Construct 3)

**Result**: If your game renders score on canvas, **manual SDK integration is REQUIRED** for auto-score tracking.

---

## Auto Score Integration

### Integration Requirements Checklist

Before uploading your game to ASETQU, ensure you meet these requirements for auto-score tracking:

#### ✅ Mandatory Requirements
1. **Score Communication**: Game must call `window.updateParentScore(score)` or send postMessage
2. **Timing**: Send score at least once when game ends (Game Over / Level Complete)
3. **Integer Values**: Score must be a whole number (0-999999)
4. **Iframe Compatible**: Game must work inside an iframe (no `X-Frame-Options` restrictions)

#### ⚠️ Optional but Recommended
1. **Real-time Updates**: Send score every time it changes (with 500ms throttle)
2. **Error Handling**: Wrap SDK calls in try-catch to prevent game crashes
3. **Multiple Platforms**: Support both direct postMessage and SDK helper function

#### ❌ What Doesn't Work
1. **Canvas-only score display** without SDK integration
2. **Worker-mode Construct 3** without JavaScript Execute action
3. **Cross-origin iframes** without proper CORS headers
4. **Games that don't expose score** in runtime/global variables

### Quick Start: 3 Steps to Integrate

#### Step 1: Identify Your Score Variable
Find where your game stores the current score:
- **Construct 3**: `runtime.globalVars.Score` or instance variable
- **Unity**: Your C# score variable
- **JavaScript**: `this.score`, `gameState.score`, etc.

#### Step 2: Call Update Function
Add this code when score changes:
```javascript
// Option A: Use helper (recommended)
if (typeof window.updateParentScore === 'function') {
    window.updateParentScore(yourScore);
}

// Option B: Direct postMessage (universal)
window.parent.postMessage({
    type: 'SCORE_UPDATE',
    payload: { score: yourScore }
}, '*');
```

#### Step 3: Test Before Upload
1. Open browser console (F12)
2. Play your game
3. Check for message: `[ASQ Bridge] Score from game: X`
4. Verify score updates in parent UI

---

### For Game that Already Uploaded
Setiap game yang di-upload ke ASETQU akan otomatis mendapatkan bridge script yang ter-inject. Bridge script ini akan mencoba mendeteksi score secara otomatis.

### Cara Memanggil SDK dari Game

Untuk game yang dibuat dengan **Construct 3**, **Unity WebGL**, atau **HTML5 custom**, tambahkan kode berikut untuk mengirim score ke parent window:

#### Method 1: Direct postMessage (Universal)
```javascript
// Kirim score ke parent window
window.parent.postMessage({
    type: 'SCORE_UPDATE',
    payload: { score: yourScoreValue }
}, '*');
```

#### Method 2: Using SDK Helper (Recommended)
```javascript
// Panggil function yang sudah disediakan oleh bridge script
if (typeof window.updateParentScore === 'function') {
    window.updateParentScore(yourScoreValue);
}
```

### Construct 3 Integration (Detailed)

Construct 3 games have unique challenges due to Worker mode isolation. Follow this guide carefully.

#### Problem: Worker Mode Isolation
When Construct 3 exports with Worker mode enabled (default):
- Game runtime runs in a Web Worker (separate thread)
- External JavaScript cannot access `runtime.globalVars` directly
- Bridge script injection alone is NOT sufficient

#### Solution 1: Add JavaScript Action (Recommended)

**When to call**: Every time score changes, or at minimum on Game Over

**Steps**:
1. In Construct 3 event sheet, find where score changes
2. Add action: **Browser** → **Execute JavaScript**
3. Use one of these code snippets:

**Option A: With error handling (safest)**
```javascript
try {
    if (window.parent && window.parent !== window) {
        const score = runtime.globalVars.Score; // Replace 'Score' with your variable name
        
        // Method 1: Use SDK helper
        if (typeof window.updateParentScore === 'function') {
            window.updateParentScore(score);
        } else {
            // Method 2: Direct postMessage fallback
            window.parent.postMessage({
                type: 'SCORE_UPDATE',
                payload: { score: score }
            }, '*');
        }
    }
} catch (e) {
    console.error('Failed to send score:', e);
}
```

**Option B: Simple version**
```javascript
if (window.parent && window.parent !== window) {
    window.parent.postMessage({
        type: 'SCORE_UPDATE',
        payload: { score: runtime.globalVars.Score }
    }, '*');
}
```

**Option C: Using instance variable**
```javascript
// If score is stored in an object instance variable
const player = runtime.objects.Player.getFirstInstance();
if (player && window.parent !== window) {
    window.parent.postMessage({
        type: 'SCORE_UPDATE',
        payload: { score: player.instVars.score }
    }, '*');
}
```

#### Solution 2: Disable Worker Mode (Not Recommended)

**Only if you can't modify event sheet**:
1. Project Properties → Advanced
2. Set **Use worker** to **No**
3. Re-export your game

**Drawbacks**:
- Reduced performance
- Possible lag on complex games
- Not recommended for production

#### Best Practices for Construct 3

1. **Send on Multiple Events**:
```
✅ On Game Over → Execute JavaScript (send score)
✅ On Level Complete → Execute JavaScript (send score)
✅ Every X seconds → Execute JavaScript (send score) [optional]
```

2. **Use Global Variable for Score**:
```
✅ Create global variable "Score"
❌ Don't use local variables or text objects
```

3. **Test in Preview**:
   - Use Remote Preview (not localhost)
   - Check browser console for ASETQU logs
   - Verify score updates in parent UI

#### Common Construct 3 Issues

| Issue | Solution |
|-------|----------|
| `runtime is not defined` | You're calling outside event sheet. Must use Browser action. |
| `globalVars.Score is undefined` | Variable name mismatch. Check exact spelling/capitalization. |
| Score not updating | Worker mode enabled + no JavaScript action added |
| `updateParentScore is not a function` | Use direct postMessage instead |

---

### Unity WebGL Integration
```csharp
using System.Runtime.InteropServices;

public class ScoreManager : MonoBehaviour
{
    [DllImport("__Internal")]
    private static extern void UpdateParentScore(int score);

    public void SendScore(int score)
    {
        #if UNITY_WEBGL && !UNITY_EDITOR
        UpdateParentScore(score);
        #endif
    }
}
```

Tambahkan di `index.html` atau plugin:
```javascript
mergeInto(LibraryManager.library, {
    UpdateParentScore: function(score) {
        if (window.parent && window.parent !== window) {
            window.parent.postMessage({
                type: 'SCORE_UPDATE',
                payload: { score: score }
            }, '*');
        }
    }
});
```

### HTML5/JavaScript Custom Games
```javascript
class GameScoreManager {
    constructor() {
        this.currentScore = 0;
    }
    
    addScore(points) {
        this.currentScore += points;
        this.sendToParent();
    }
    
    setScore(score) {
        this.currentScore = score;
        this.sendToParent();
    }
    
    sendToParent() {
        // Check if running in iframe
        if (window.parent && window.parent !== window) {
            window.parent.postMessage({
                type: 'SCORE_UPDATE',
                payload: { score: this.currentScore }
            }, '*');
        }
    }
}

// Usage
const scoreManager = new GameScoreManager();
scoreManager.addScore(10); // Add 10 points
```

## Message Protocol

### Outgoing Messages (Game → Parent)

#### Score Update
```javascript
{
    type: 'SCORE_UPDATE',
    payload: {
        score: number // Score value (integer)
    }
}
```

#### Game Ready
```javascript
{
    type: 'GAME_READY',
    payload: {}
}
```

### Incoming Messages (Parent → Game)

#### Get Game State
```javascript
{
    type: 'GET_GAME_STATE'
}
```

Response: Send current score via SCORE_UPDATE message

## Testing & Validation

### Pre-Upload Testing

**Test locally before uploading to ASETQU:**

1. **Create Test HTML**:
```html
<!DOCTYPE html>
<html>
<body>
    <h1>Score: <span id="score">0</span></h1>
    <iframe src="your-game/index.html" width="800" height="600"></iframe>
    
    <script>
        window.addEventListener('message', (event) => {
            if (event.data.type === 'SCORE_UPDATE') {
                document.getElementById('score').textContent = event.data.payload.score;
                console.log('✅ Score received:', event.data.payload.score);
            }
        });
    </script>
</body>
</html>
```

2. **Open in Browser**: Load the test HTML file
3. **Play Game**: Trigger score changes
4. **Verify**:
   - ✅ Score display updates
   - ✅ Console shows "Score received" messages
   - ✅ No JavaScript errors

### Post-Upload Testing

After uploading to ASETQU:

1. **Play Game**: Start a game session
2. **Open DevTools** (F12):
   - Check Console tab
   - Look for `[ASQ Bridge]` messages
3. **Expected Logs**:
```
✅ [ASQ Bridge] Initializing...
✅ [ASQ Bridge] GAME_READY sent
✅ [ASQ Bridge] Score from game: 10
✅ [ASQ Bridge] Score from game: 25
✅ [Game] Score updated: 25
```

4. **Verify UI**:
   - Score display should update automatically
   - "Level Diselesaikan" input should NOT appear (hidden when auto-score works)
   - Session saves correctly on game over

### Troubleshooting Guide

| Symptom | Cause | Fix |
|---------|-------|-----|
| No console logs | Bridge script not loaded | Hard refresh (Cmd+Shift+R) |
| "Score: 0" in UI | SDK not integrated | Add JavaScript action to game |
| Score updates but wrong value | Wrong variable name | Check `runtime.globalVars.YourVariableName` |
| Manual input appears | No score received in 5s | Game must send score within 5 seconds |
| `runtime is not defined` | Called outside event sheet | Must use Browser → Execute JavaScript action |
| CORS errors | iframe restrictions | Check game export settings |

### Validation Checklist

Before considering integration complete:

- [ ] Game loads inside iframe without errors
- [ ] Console shows GAME_READY message
- [ ] Score updates appear in console when playing
- [ ] UI score display updates automatically (not stuck at 0)
- [ ] Manual level input does NOT appear
- [ ] Session saves with correct final score
- [ ] No JavaScript errors in console
- [ ] Works after hard refresh (cache cleared)

---

## Platform Requirements & Policies

### What ASETQU Needs from Game Developers

#### 1. Technical Requirements
- **Score Communication**: Implement `window.updateParentScore(score)` or postMessage
- **Minimum Call Frequency**: At least 1x on Game Over
- **Score Format**: Integer between 0-999999
- **Iframe Support**: Game must work inside `<iframe>` (no frame-busting scripts)
- **Testing**: Provide test build or demo video showing SDK integration

#### 2. Export Settings (Construct 3)
When exporting for ASETQU:
```
✅ Export as: HTML5 Web (folder)
✅ Minify: Yes (optional, for performance)
✅ Use worker: Yes (default) - but must add JavaScript action
✅ Include files: All game assets
❌ Don't include: Server-side scripts, database connections
```

#### 3. File Structure Requirements
Your game ZIP must contain:
```
game.zip/
├── index.html          ← REQUIRED: Entry point
├── scripts/           
│   └── *.js           ← Game logic
├── images/            ← Assets
├── sounds/
└── data/              ← Optional
```

**Critical**: `index.html` must be at root level, not in subfolder.

#### 4. Submission Checklist for Developers

Before submitting your game to ASETQU:

- [ ] **SDK Integrated**: Added score reporting code
- [ ] **Tested Locally**: Verified score updates in test iframe
- [ ] **Tested on ASETQU**: Uploaded and verified auto-score works
- [ ] **No Console Errors**: Clean console logs during gameplay
- [ ] **Proper ZIP Structure**: index.html at root level
- [ ] **Assets Included**: All images, sounds, fonts packed
- [ ] **Performance Tested**: Game runs smoothly in iframe
- [ ] **Mobile Compatible**: (Optional) Works on mobile devices
- [ ] **Documentation**: Provide README with controls/instructions

#### 5. What Happens Without SDK Integration

If you upload a game **without** SDK integration:

1. ✅ Game will still work and be playable
2. ⚠️ Bridge script auto-injected (attempts auto-detection)
3. ⚠️ Auto-detection will **fail** for canvas-based games
4. ⚠️ Players must manually input levels completed
5. ⚠️ Anti-cheat relies on time-based validation only
6. ❌ Not eligible for featured/premium placement
7. ❌ Lower quality score for platform algorithms

**Recommendation**: Always integrate SDK for best user experience.

---

## Developer Support & Resources

### Sample Games with SDK Integration

Example Construct 3 project files:
- [Download Sample Project](https://github.com/asetqu/sample-games) *(placeholder)*
- See `examples/construct3-score-integration.c3p`

### Getting Help

**Issues with Integration?**
1. Check console logs for error messages
2. Review troubleshooting guide above
3. Contact developer support:
   - Email: dev-support@asetqu.com
   - Discord: [ASETQU Dev Community](https://discord.gg/asetqu) *(placeholder)*
   - GitHub Issues: [asetqu/game-sdk](https://github.com/asetqu/game-sdk) *(placeholder)*

**Response Time**: Within 24-48 hours on business days

---

### Worker-Mode Construct 3 Games
Game Construct 3 yang berjalan di **Worker mode** tidak bisa diakses runtime-nya dari luar. Solusi:
1. **Disable Worker mode** saat export (Project Properties → Advanced → Use worker: No)
2. **ATAU** tambahkan JavaScript action untuk kirim score manual

### Cross-Origin Issues
Jika game di-host di domain berbeda, pastikan:
- Game allows iframe embedding
- postMessage menggunakan proper origin validation

## FAQ

### Q: Is SDK integration mandatory?
**A:** No, but **highly recommended**. Without SDK:
- Auto-score detection fails for canvas-based games (most modern games)
- Players must manually input level completion
- Your game won't be featured/highlighted
- Less accurate score tracking

### Q: How often should I send score updates?
**A:** 
- **Minimum**: 1x when game ends (Game Over / Victory)
- **Recommended**: Every time score changes (with 500ms throttle to avoid spam)
- **Best Practice**: On significant events (level complete, enemy killed, combo achieved)

### Q: What if my game has multiple score types (coins, points, stars)?
**A:** 
- Send the **primary** score (usually total points)
- ASETQU currently supports single score value only
- Future versions may support multiple metrics

### Q: Can I test SDK integration before uploading?
**A:** Yes! See "Pre-Upload Testing" section above. Create a simple HTML wrapper with iframe and message listener.

### Q: My Construct 3 game uses Worker mode, will it work?
**A:**
- ✅ Yes, IF you add Browser → Execute JavaScript action
- ❌ No, if you only rely on auto-injection without JavaScript action
- See "Construct 3 Integration" section for details

### Q: What happens if I send invalid score values?
**A:**
- Non-integer values: Rounded to nearest integer
- Negative values: Ignored
- Values > 999999: Capped at 999999
- Values < 0: Set to 0

### Q: How does ASETQU prevent cheating?
**A:** Server-side validation includes:
- Minimum play time (30 seconds) before score acceptance
- Rate limiting (max 1 submit per 30 seconds)
- Score anomaly detection (sudden jumps)
- Session validation (active session required)
- Time-based progression checks

### Q: Can I send data other than score (level, time, achievements)?
**A:** 
- **Currently**: Only score (integer value)
- **Planned**: Future SDK versions will support:
  - Level/stage completed
  - Play duration
  - Achievement unlocks
  - Custom metrics

### Q: Does the platform cache my game files?
**A:**
- Yes, games are cached for performance
- If you update game, users may need to hard refresh (Cmd+Shift+R)
- Platform admin can clear cache if needed

### Q: What if my game runs on external server (not uploaded as ZIP)?
**A:** 
- Currently not supported
- ZIP upload required for security and performance
- All assets must be self-contained in ZIP

### Q: Can I update my game after uploading?
**A:**
- Contact platform admin to re-upload
- Self-service update feature: Coming soon
- Version control: Currently manual

---

## Technical Specifications

### Message Protocol Details

#### Outgoing: SCORE_UPDATE
```typescript
interface ScoreUpdateMessage {
    type: 'SCORE_UPDATE';
    payload: {
        score: number; // Integer 0-999999
    }
}
```

**Frequency**: No hard limit, but recommended < 2 updates per second

**Validation**: 
- Score must be integer
- Value between 0-999999
- Sent from game iframe origin

#### Outgoing: GAME_READY
```typescript
interface GameReadyMessage {
    type: 'GAME_READY';
    payload: {}
}
```

**When**: Sent automatically by bridge script on load
**Purpose**: Signals parent that game iframe is loaded

#### Incoming: GET_GAME_STATE (Future)
```typescript
interface GetGameStateMessage {
    type: 'GET_GAME_STATE';
}
```

**Purpose**: Request current game state
**Response**: Game should send SCORE_UPDATE with current score

---

## Support

### Contact Information
- **Email**: dev-support@asetqu.com
- **Discord**: ASETQU Developer Community *(invite link coming soon)*
- **Documentation**: [docs.asetqu.com](https://docs.asetqu.com) *(placeholder)*

### Reporting Issues
When reporting SDK integration issues, include:
1. Game engine/framework (Construct 3, Unity, custom)
2. Browser console logs (screenshot or copy-paste)
3. Network tab showing bridge script load status
4. Minimal reproducible example if possible

### Contributing
SDK is open for community contributions:
- Report bugs via GitHub Issues
- Submit feature requests
- Share sample projects
- Improve documentation

---

**Last Updated**: January 13, 2026  
**SDK Version**: 1.0  
**Platform**: ASETQU v2.0
