experimental: remove Tekton Doors entirely

- Delete portal_mode_manager.gd, portal_door.gd, portal_door.tscn
- Strip all Tekton Doors logic from main.gd, player.gd, lobby.gd,
  lobby_room.gd, lobby_manager.gd, camera_context_manager.gd,
  music_manager.gd, tekton.gd, enhanced_gridmap.gd,
  playerboard_manager.gd, special_tiles_manager.gd
- Remove TK enum (TEKTON_DOORS=2), mode_config schema, arena area
- Update tests: 3 modes instead of 4
- Strip HowToPlay tab from main.tscn
This commit is contained in:
god
2026-07-06 00:18:59 +08:00
parent 0ab00afd37
commit 114748a54f
31 changed files with 4493 additions and 1535 deletions
+159 -376
View File
@@ -1,422 +1,205 @@
# Steamworks Setup Guide for Tekton Armageddon
This guide explains how to set up Steamworks for Windows, Mac, and Linux builds while using Nakama for mobile platforms (Android/iOS) for leaderboards, achievements, and shop functionality.
> **Current status: Steam builds are not active.** All platforms (Windows, Linux, macOS, Android) use Nakama as their sole backend. GodotSteam GDExtension exists in `addons/godotsteam/` but is **not enabled** in the project. This doc explains the current Nakama-only architecture and how to re-enable Steam if needed in the future.
## Overview
---
- **Desktop (Windows/Mac/Linux)**: Single build that detects Steam at runtime
- If launched through Steam: Steam login available for Nakama registration; all features use Nakama
- If launched standalone: Uses Nakama for all features
- **Mobile (Android/iOS)**: Uses Nakama for all backend services
- **Unified Backend**: All platforms use Nakama for achievements, leaderboards, and shop
- **Steam Integration**: Steam is only used for authentication (auth session ticket for Nakama login)
## Current Architecture (Nakama-Only)
## Prerequisites
### Steamworks Setup
1. **Steam Partner Account**
- You need a Steam Partner account to access Steamworks
- Apply at: https://partner.steamgames.com/
2. **Steam App ID**
- Create a new app in Steamworks
- Note your App ID (e.g., 480)
- Update `steam_app_id` in `scripts/services/steamworks_manager.gd`
3. **Steamworks SDK**
- Download the Steamworks SDK from Steamworks
- The GodotSteam plugin includes the SDK, but you may need it for reference
## Installation Steps
### 1. Install GodotSteam GDExtension
**Option A: Via Godot Asset Library (Recommended)**
1. Open Godot Editor
2. Go to `Project > Asset Library`
3. Search for "GodotSteam GDExtension 4.4+"
4. Download and install the plugin
5. Restart Godot Editor
**Option B: Manual Installation**
1. Download from: https://codeberg.org/godotsteam/godotsteam/releases
2. Download version 4.18.1 (compatible with Godot 4.6.2)
3. Extract to `addons/godotsteam/` in your project
4. Enable the plugin in `Project > Project Settings > Plugins`
### 2. Configure Steamworks in Project
1. **Enable the Plugin**
- Go to `Project > Project Settings > Plugins`
- Enable "GodotSteam"
2. **Set Steam App ID**
- Edit `scripts/services/steamworks_manager.gd`
- Change `steam_app_id` to your Steam App ID:
```gdscript
var steam_app_id: int = YOUR_APP_ID_HERE
```
3. **Add BackendService as Autoload**
- Go to `Project > Project Settings > Autoload`
- Add `BackendService` with path: `res://scripts/services/backend_service.gd`
- Enable it as a singleton
### 3. Configure Steamworks Features
#### Achievements
1. **Define Achievements in Steamworks**
- Go to Steamworks > Your App > Achievements
- Create achievements with API names (e.g., "first_win", "level_10")
- Set display names, descriptions, and icons
2. **Use in Code**
```gdscript
# Unlock an achievement
BackendService.unlock_achievement("first_win")
# Set progress (for progress-based achievements)
BackendService.set_achievement_progress("kill_100_enemies", current_kills, 100)
# Check achievement status
var progress = BackendService.get_achievement_progress("first_win")
```
#### Leaderboards
1. **Define Leaderboards in Steamworks**
- Go to Steamworks > Your App > Leaderboards
- Create leaderboards with API names (e.g., "high_score", "fastest_time")
- Set sort order (ascending/descending) and display type
2. **Use in Code**
```gdscript
# Submit a score
BackendService.submit_leaderboard_score("high_score", 1000)
# Get leaderboard entries
BackendService.leaderboard_entries_loaded.connect(_on_leaderboard_loaded)
BackendService.get_leaderboard_entries("high_score", 1, 10)
func _on_leaderboard_loaded(leaderboard_id: String, entries: Array):
for entry in entries:
print("Player: %s, Score: %d" % [entry.player_name, entry.score])
```
#### Shop (Steam Inventory)
**Note**: Steam shop functionality requires additional setup with Steam Inventory Service or Steam Microtransactions. This is a complex feature that requires:
1. **Steam Inventory Service Setup**
- Define items in Steamworks > Your App > Inventory
- Set item types, prices, and properties
- Implement purchase callbacks in `steamworks_manager.gd`
2. **Alternative**: Use external payment processor for desktop and sync with Nakama
### 4. Export Presets
The project includes export presets for all platforms:
#### Desktop Builds (single build for Steam and standalone)
- **Windows Desktop** (preset.0) → `build/tekton_armageddon_v2.1.7.exe`
- **macOS** (preset.2) → `build/tekton_armageddon_v2.1.7.zip`
- **Linux/X11** (preset.3) → `build/tekton_armageddon_v2.1.7.x86_64`
#### Mobile Builds
- **Android** (preset.1) → `build/tekton-dash-armageddon-v.2.1.5.apk`
**Note**: Desktop builds are universal - the same executable works on both Steam and standalone. The game detects whether it's running through Steam at runtime and switches backends accordingly.
#### Configure macOS Export
1. **Code Signing** (for distribution)
- Get an Apple Developer certificate
- Update `codesign/identity` in export preset
- Set `codesign/enable` to `true`
2. **Architecture**
- Currently set to "universal" (Intel + Apple Silicon)
- Can be changed to "x86_64" or "arm64" if needed
#### Configure Linux Export
1. **Architecture**
- Currently set to "x86_64"
- Add ARM64 preset if needed for Linux ARM devices
### 5. Platform Detection
The `BackendService` automatically detects the platform and backend:
```gdscript
# Detection logic in BackendService
if OS.has_feature("android") or OS.has_feature("ios"):
# Mobile → Nakama
elif OS.has_feature("steam"):
# Desktop → Steamworks
else:
# Desktop → Local storage (non-Steam builds)
```
┌──────────────────────────────────────────────────┐
│ Game Client │
│ ┌──────────────────────────────────────────┐ │
│ │ BackendService (autoload) │ │
│ │ ┌─────────────┐ ┌──────────────────┐ │ │
│ │ │ NakamaManager│ │steamworks_manager│ │ │
│ │ │ (active) │ │ (dormant) │ │ │
│ │ └─────────────┘ └──────────────────┘ │ │
│ └──────────────────────────────────────────┘ │
└──────────────────────┬───────────────────────────┘
┌────────▼────────┐
│ Nakama Server │
│ (RPC backend) │
│ achievements │
│ leaderboards │
│ shop/economy │
│ auth │
│ multiplayer │
└─────────────────┘
```
You can check the current platform:
- **All backends use Nakama** — achievements, leaderboards, shop, authentication, multiplayer.
- **Platform detection** (`BackendService._detect_platform()`) distinguishes:
- `MOBILE_NAKAMA` — Android/iOS (`OS.has_feature("android")` or `OS.has_feature("ios")`)
- `DESKTOP_NAKAMA` — Windows/Linux/macOS (default when GodotSteam not loaded)
- `DESKTOP_STEAM` — only activated if `ClassDB.class_exists("Steam")` at runtime
- **GodotSteam GDExtension** is present in `addons/godotsteam/` but **not enabled** in Project Settings > Plugins. It is shipped in the CI export (Windows only, `|| true` on copy failure) but does not execute.
- **No Steam App ID configured.** The `steam_app_id` in `steamworks_manager.gd` defaults to `480` (generic test ID) via `ProjectSettings.get_setting("steam/initialization/app_id", 480)`.
- **No Steam Partner account, no Steamworks app, no Steam build pipelines** are active.
---
## Export Presets
The project has 4 export presets in `export_presets.cfg`:
| Preset | Name | Platform | Export Path |
|--------|------|----------|-------------|
| preset.0 | Windows Desktop | Windows | `build/windows/tekton_armageddon_v2.4.3.exe` |
| preset.1 | Android | Android | `build/tekton-dash-armageddon-v.2.4.3.apk` |
| preset.2 | macOS | macOS | `build/tekton_armageddon_v2.4.3.zip` |
| preset.3 | Linux/X11 | Linux | `build/linux/tekton_armageddon_v2.4.3.x86_64` |
No separate Steam vs. Non-Steam presets. All presets produce the same Nakama-only build.
### CI Export Flow (`.gitea/workflows/ci.yml`)
On tag push (`v*`), the CI pipeline:
1. **Checkout** code at tag
2. **Setup Godot 4.7** (cached)
3. **Export Windows**`build/windows/tekton_armageddon_windows.exe` (copies `libgodotsteam*` DLLs if present, failure ignored with `|| true`)
4. **Export Linux**`build/linux/tekton_armageddon_linux.x86_64`
5. **Export macOS**`build/macos/tekton_armageddon_macos.zip`
6. **Extract changelog** from `CHANGELOG_DRAFT.md`
7. **Create Gitea release** and upload all 3 platform zips
8. **Publish** release (draft → published)
The CI does **not** upload to Steam. All builds are distributed via Gitea releases (https://git.klud.top/danchie/tekton/releases).
---
## Platform Detection
The `BackendService` autoload (`scripts/services/backend_service.gd`) detects platform at startup:
```gdscript
func _detect_platform() -> void:
if OS.has_feature("android") or OS.has_feature("ios"):
current_platform = Platform.MOBILE_NAKAMA
else:
if ClassDB.class_exists("Steam"):
current_platform = Platform.DESKTOP_STEAM
else:
current_platform = Platform.DESKTOP_NAKAMA
```
Since GodotSteam is not enabled, desktop builds always hit `DESKTOP_NAKAMA`. The `steamworks_manager.gd` is only loaded when `DESKTOP_STEAM` is selected.
Check current platform at runtime:
```gdscript
print("Platform: %s" % BackendService.get_platform_name())
print("Initialized: %s" % BackendService.is_initialized())
```
#### Platform Types
### Platform Types
- **DESKTOP_STEAM**: Running through Steam client (Steam login available, all features use Nakama)
- **DESKTOP_NAKAMA**: Desktop build not running through Steam (uses Nakama)
- **MOBILE_NAKAMA**: Android/iOS (uses Nakama)
| Value | Trigger | Backend |
|-------|---------|---------|
| `DESKTOP_NAKAMA` | Desktop build, GodotSteam not loaded | Nakama only |
| `DESKTOP_STEAM` | Desktop build, GodotSteam loaded + Steam running | Nakama + Steam auth |
| `MOBILE_NAKAMA` | Android/iOS feature detected | Nakama only |
#### Runtime Detection
---
The game automatically detects the launch method:
- If `OS.has_feature("steam")` is true → Steam login available, all features use Nakama
- Otherwise → All features use Nakama
## Local Testing
This means the same desktop build can be:
- Uploaded to Steam (Steam login enabled, all data stored in Nakama)
- Distributed standalone (all data stored in Nakama)
### Nakama Backend (All Platforms)
### Steam Login for Nakama
1. Ensure Nakama server is running locally (see `server/docker-compose.yaml`)
2. Launch the game from Godot Editor (press F5)
3. Log in with email/password or device ID
4. Test achievements, leaderboards, shop via game UI
5. Check console for `"BackendService: Initialized Nakama backend"`
When running through Steam, players can use their Steam account to register or log in to Nakama. This is the **only** Steam integration - all game features (achievements, leaderboards, shop) use Nakama.
**How it works:**
1. Player clicks "Sign in with Steam" button on login screen
2. Game retrieves Steam auth session ticket via Steamworks
3. Auth ticket is sent to Nakama for authentication
4. Nakama validates the ticket with Steam backend
5. If valid, player is logged in/registered to Nakama
6. Player's Steam account is linked to their Nakama account
**Benefits:**
- No password needed for Steam users
- Automatic account creation on first login
- Seamless cross-platform progression (all data in Nakama)
- Steam username is used as display name
- Unified backend across all platforms
**Requirements:**
- Nakama server must be configured with Steam API key
- Steamworks must be initialized (game launched through Steam)
- GodotSteam plugin must support `getAuthSessionTicket()`
**Configuration:**
Set your Steam API key in Nakama server configuration:
```yaml
nakama:
social:
steam:
api_key: "your_steam_api_key"
```
## Nakama Integration for Mobile
### Current Setup
Your project already has Nakama integrated via `addons/com.heroiclabs.nakama/` and `NakamaManager` autoload.
### Connecting to BackendService
The `BackendService` will automatically use Nakama on mobile. You need to implement Nakama-specific methods in `NakamaManager`:
### Force-Specific Platform for Testing
Temporarily override platform in `BackendService._detect_platform()`:
```gdscript
# In NakamaManager.gd, add these signals:
signal achievement_unlocked(achievement_id: String)
signal leaderboard_score_submitted(leaderboard_id: String, score: int, success: bool)
# Implement achievement methods
func unlock_achievement(achievement_id: String):
# Use Nakama's achievement system
var achievement = await client.write_storage_object_async(
session,
NakamaWriteStorageObject.new(
"achievements",
achievement_id,
{"unlocked": true, "timestamp": Time.get_unix_time_from_system()}
)
)
achievement_unlocked.emit(achievement_id)
# Implement leaderboard methods
func submit_leaderboard_score(leaderboard_id: String, score: int):
# Use Nakama's leaderboard system
var result = await client.write_leaderboard_record_async(
session,
leaderboard_id,
score
)
leaderboard_score_submitted.emit(leaderboard_id, score, result != null)
func _detect_platform() -> void:
current_platform = Platform.DESKTOP_NAKAMA # Force desktop Nakama mode
# ... or ...
current_platform = Platform.MOBILE_NAKAMA # Force mobile mode
```
## Testing
### Export and Run Standalone
### Testing Steam Builds
```bash
# Windows
godot --headless --export-release "Windows Desktop" build/windows/standalone.exe
./build/windows/standalone.exe
1. **Export Steam Build**
- Use the "Windows Desktop (Steam)" preset (preset.0)
- Export to `build/steam/tekton_armageddon_v2.1.7.exe`
# Linux
godot --headless --export-release "Linux/X11" build/linux/standalone.x86_64
./build/linux/standalone.x86_64
2. **Upload to Steam**
- Upload the exported build to Steamworks
- Set as the default build for your app
# macOS
godot --headless --export-release "macOS" build/macos/standalone.zip
```
3. **Run through Steam**
- Launch the game via Steam (not directly)
- Steam must be running
- Check console for "SteamworksManager: Steam initialized successfully"
---
4. **Test Achievements**
- Call `BackendService.unlock_achievement("test_achievement")`
- Check Steam overlay (Shift+Tab) to see achievement unlock
## Activating Steam Support (Future)
5. **Test Leaderboards**
- Submit scores via `BackendService.submit_leaderboard_score()`
- View in Steamworks backend or Steam overlay
If Steam distribution is needed later, these are the steps:
### Testing Non-Steam Builds
1. **Get a Steam Partner account** at https://partner.steamgames.com/
2. **Create Steam app** and get an App ID
3. **Enable GodotSteam plugin** in Project > Project Settings > Plugins
4. **Set App ID** in Project Settings > steam > initialization > app_id (or in `steamworks_manager.gd`)
5. **Configure Nakama** to accept Steam auth tickets (set Steam API key in Nakama config)
6. **Add a Steam-specific export preset** or modify existing presets to include Steam SDK redistributables
7. **Update CI pipeline** to upload builds to Steamworks SDK pipelines
8. **Test Steam auth flow**: launch through Steam, verify `"SteamworksManager: Steam initialized"`, verify Steam login → Nakama registration
1. **Export Non-Steam Build**
- Use the "Windows Desktop (Non-Steam)" preset (preset.1)
- Export to `build/standalone/tekton_armageddon_v2.1.7.exe`
### What the Dormant Steam Code Does
2. **Run Directly**
- Run the executable directly (not through Steam)
- Check console for "BackendService: Initialized Nakama backend"
The existing `steamworks_manager.gd` provides:
3. **Test Leaderboards**
- Ensure Nakama server is accessible
- Open the leaderboard panel to fetch rankings
- Submit scores via `UserProfileManager.submit_to_leaderboard()`
- Leaderboards are global (same as mobile)
- `get_auth_session_ticket()` — retrieves Steam auth session ticket for Nakama login
- `get_steam_user_name()` — returns Steam persona name
- `get_steam_user_id()` — returns Steam ID
4. **Test Shop**
- Ensure Nakama server is accessible
- Open the shop panel to fetch catalog
- Purchase items via `UserProfileManager.purchase_item()`
- Shop functionality works the same as mobile
All game features (achievements, leaderboards, shop) are already implemented purely via Nakama RPCs in `BackendService.api_rpc_async()`. Steam would only be used for **authentication** — the rest stays on Nakama.
### Testing Nakama (Mobile)
1. **Run on Mobile Device**
- Export to Android/iOS using the Android preset (preset.2)
- The game will automatically use Nakama backend
- Check logs for "BackendService: Initialized Nakama backend"
2. **Test in Editor**
- To test Nakama in editor, temporarily modify `_detect_platform()`:
```gdscript
func _detect_platform() -> void:
current_platform = Platform.MOBILE_NAKAMA # Force Nakama
```
## Troubleshooting
### Steamworks Not Initializing
**Problem**: "SteamworksManager: Failed to initialize Steam"
**Solutions**:
1. Ensure game is launched through Steam (not directly)
2. Check Steam is running
3. Verify `steam_app_id` is correct
4. Check GodotSteam plugin is enabled in Project Settings
5. Restart Godot Editor after installing plugin
### Achievements Not Unlocking
**Problem**: Achievements don't appear in Steam overlay
**Solutions**:
1. Ensure achievement API names match Steamworks configuration
2. Check `steam.storeStats()` is called after setting achievements
3. Verify achievement is published in Steamworks (not in draft)
4. Test with Steam overlay open (Shift+Tab)
### Leaderboards Not Working
**Problem**: Leaderboard scores not submitting
**Solutions**:
1. Ensure leaderboard exists in Steamworks
2. Check leaderboard API name matches
3. Verify leaderboard is published
4. Check console for error messages
### Platform Detection Issues
**Problem**: Wrong backend being used
**Solutions**:
1. Check OS features: `print(OS.get_supported_features())`
2. Manually override platform in `_detect_platform()` for testing
3. Ensure `BackendService` is added as autoload
---
## File Structure
```
scripts/services/
├── backend_service.gd # Unified interface (autoload)
── steamworks_manager.gd # Steamworks implementation
scripts/
├── backend_service.gd # Unified interface (autoload) — Nakama-only default
── steamworks_manager.gd # Steamworks implementation (dormant, loads only if GodotSteam present)
└── nakama_manager.gd # NakamaManager autoload (active)
export_presets.cfg # Export presets for all platforms
addons/godotsteam/ # GodotSteam GDExtension (installed but not enabled)
addons/com.heroiclabs.nakama/ # Nakama GDSDK (active)
export_presets.cfg # Export presets — all Nakama-only, no Steam presets
.gitea/workflows/ci.yml # CI pipeline — exports Win/Linux/macOS to Gitea releases
docs/STEAMWORKS_SETUP.md # This documentation
```
---
## Key Differences from Previous State
| Aspect | Before | Now |
|--------|--------|-----|
| Steam builds | Active, separate Steam/Non-Steam presets | Dormant, not shipped |
| Backend | Nakama + Steam | Nakama only |
| Export presets | 6+ (Steam + Non-Steam variants) | 4 (all Nakama-only) |
| Desktop platform detection | Steam if `OS.has_feature("steam")` | Nakama unless GodotSteam loaded |
| CI | Uploaded to Steamworks | Gitea releases only |
| Steam App ID | Configured | Default 480 (test), not set |
---
## Additional Resources
- **GodotSteam Documentation**: https://godotsteam.com/
- **Nakama Documentation**: https://heroiclabs.com/docs/nakama/
- **GodotSteam Documentation**: https://godotsteam.com/ (for future reference)
- **GodotSteam GitHub**: https://codeberg.org/godotsteam/godotsteam
- **Steamworks Documentation**: https://partner.steamgames.com/doc/home
- **Nakama Documentation**: https://heroiclabs.com/docs/nakama/
## Next Steps
1. Complete Steam Partner account setup
2. Create Steam app and get App ID
3. Install GodotSteam plugin
4. Configure achievements and leaderboards in Steamworks
5. Implement Nakama methods in `NakamaManager` for mobile
6. Test on all target platforms
7. Set up code signing for macOS distribution
8. Configure Steam Inventory Service if using in-game shop
## Notes
- **Steam builds** only work when launched through Steam client
- **Non-Steam builds** use Nakama for leaderboards and shop (same as mobile)
- **Shop functionality** is available on both Steam (via Steam Inventory) and non-Steam (via Nakama)
- **Non-Steam builds** sync to Nakama server, not Steam
- **Nakama** is already integrated for multiplayer, leaderboards, and shop
- Export presets are organized in separate folders: `build/steam/` and `build/standalone/`
## Build Workflow
### For Steam Distribution
1. Export using Steam presets (preset.0, preset.3, preset.5)
2. Upload builds to Steamworks
3. Configure achievements and leaderboards in Steamworks backend
4. Set build as default in Steamworks
5. Shop uses Steam Inventory Service (requires additional setup)
### For Standalone Distribution (itch.io, GOG, etc.)
1. Export using Non-Steam presets (preset.1, preset.4, preset.6)
2. Distribute the standalone executables
3. Ensure Nakama server is accessible to players
4. Players get global leaderboards and shop via Nakama
5. No Steam integration required
### For Mobile Stores
1. Export using Android preset (preset.2)
2. Upload to Google Play / App Store
3. Ensure Nakama server is configured and accessible
4. Leaderboards and shop work the same as non-Steam desktop
- **CI Workflow**: `.gitea/workflows/ci.yml`