added rules
This commit is contained in:
166
.copilot-rules.md
Normal file
166
.copilot-rules.md
Normal file
@ -0,0 +1,166 @@
|
|||||||
|
# Copilot Rules — Spacetris (SDL3 / C++20)
|
||||||
|
|
||||||
|
These rules define **non-negotiable constraints** for all AI-assisted changes.
|
||||||
|
They exist to preserve determinism, performance, and architecture.
|
||||||
|
|
||||||
|
If these rules conflict with `.github/copilot-instructions.md`,
|
||||||
|
**follow `.github/copilot-instructions.md`.**
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Project Constraints (Non-Negotiable)
|
||||||
|
|
||||||
|
- Language: **C++20**
|
||||||
|
- Runtime: **SDL3** + **SDL3_ttf**
|
||||||
|
- Build system: **CMake**
|
||||||
|
- Dependencies via **vcpkg**
|
||||||
|
- Assets must use **relative paths only**
|
||||||
|
- Deterministic gameplay logic is mandatory
|
||||||
|
|
||||||
|
Do not rewrite or refactor working systems unless explicitly requested.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Repo Layout & Responsibilities
|
||||||
|
|
||||||
|
- Core gameplay loop/state: `src/Game.*`
|
||||||
|
- Entry point: `src/main.cpp`
|
||||||
|
- Text/TTF: `src/Font.*`
|
||||||
|
- Audio: `src/Audio.*`, `src/SoundEffect.*`
|
||||||
|
- Effects: `src/LineEffect.*`, `src/Starfield*.cpp`
|
||||||
|
- High scores: `src/Scores.*`
|
||||||
|
- Packaging: `build-production.ps1`
|
||||||
|
|
||||||
|
When adding a module:
|
||||||
|
- Place it under `src/` (or an established subfolder)
|
||||||
|
- Register it in `CMakeLists.txt`
|
||||||
|
- Avoid circular includes
|
||||||
|
- Keep headers minimal
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Build & Verification
|
||||||
|
|
||||||
|
Prefer existing scripts:
|
||||||
|
|
||||||
|
- Debug: `cmake --build build-msvc --config Debug`
|
||||||
|
- Release:
|
||||||
|
- Configure: `cmake -S . -B build-release -DCMAKE_BUILD_TYPE=Release`
|
||||||
|
- Build: `cmake --build build-release --config Release`
|
||||||
|
- Packaging (Windows): `./build-production.ps1`
|
||||||
|
|
||||||
|
Before finalizing changes:
|
||||||
|
- Debug build must succeed
|
||||||
|
- Packaging must succeed if assets or DLLs are touched
|
||||||
|
|
||||||
|
Do not introduce new build steps unless required.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Coding & Architecture Rules
|
||||||
|
|
||||||
|
- Match local file style (naming, braces, spacing)
|
||||||
|
- Avoid large refactors
|
||||||
|
- Prefer small, testable helpers
|
||||||
|
- Avoid floating-point math in core gameplay state
|
||||||
|
- Game logic must be deterministic
|
||||||
|
- Rendering code must not mutate game state
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Rendering & Performance Rules
|
||||||
|
|
||||||
|
- Do not allocate memory per frame
|
||||||
|
- Do not load assets during rendering
|
||||||
|
- No blocking calls in render loop
|
||||||
|
- Visual effects must be time-based (`deltaTime`)
|
||||||
|
- Rendering must not contain gameplay logic
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Threading Rules
|
||||||
|
|
||||||
|
- SDL main thread:
|
||||||
|
- Rendering
|
||||||
|
- Input
|
||||||
|
- Game simulation
|
||||||
|
- Networking must run in a **separate thread**
|
||||||
|
- SDL main loop must **never block** on networking
|
||||||
|
- Cross-thread communication via queues or buffers only
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Assets, Fonts, and Paths
|
||||||
|
|
||||||
|
- Runtime expects adjacent `assets/` directory
|
||||||
|
- `FreeSans.ttf` must remain at repo root
|
||||||
|
- New assets:
|
||||||
|
- Go under `assets/`
|
||||||
|
- Must be included in `build-production.ps1`
|
||||||
|
|
||||||
|
Never hardcode machine-specific paths.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## AI Partner (COOPERATE Mode)
|
||||||
|
|
||||||
|
- AI is **supportive**, not competitive
|
||||||
|
- AI must respect sync timing and shared grid logic
|
||||||
|
- AI must not “cheat” or see hidden future pieces
|
||||||
|
- AI behavior must be deterministic per seed/difficulty
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Networking (COOPERATE Network Mode)
|
||||||
|
|
||||||
|
Follow `network_cooperate_multiplayer.md`.
|
||||||
|
|
||||||
|
Mandatory model:
|
||||||
|
- **Input lockstep**
|
||||||
|
- Transmit inputs only (no board state replication)
|
||||||
|
|
||||||
|
Determinism requirements:
|
||||||
|
- Fixed tick (e.g. 60 Hz)
|
||||||
|
- Shared RNG seed
|
||||||
|
- Deterministic gravity, rotation, locking, scoring
|
||||||
|
|
||||||
|
Technology:
|
||||||
|
- Use **ENet**
|
||||||
|
- Do NOT use SDL_net or TCP-only networking
|
||||||
|
|
||||||
|
Architecture:
|
||||||
|
- Networking must be isolated (e.g. `src/network/NetSession.*`)
|
||||||
|
- Game logic must not care if partner is local, AI, or network
|
||||||
|
|
||||||
|
Robustness:
|
||||||
|
- Input delay buffer (4–6 ticks)
|
||||||
|
- Periodic desync hashing
|
||||||
|
- Graceful disconnect handling
|
||||||
|
|
||||||
|
Do NOT implement:
|
||||||
|
- Rollback
|
||||||
|
- Full state sync
|
||||||
|
- Server-authoritative sim
|
||||||
|
- Matchmaking SDKs
|
||||||
|
- Versus mechanics
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Agent Behavior Rules (IMPORTANT)
|
||||||
|
|
||||||
|
- Always read relevant markdown specs **before coding**
|
||||||
|
- Treat markdown specs as authoritative
|
||||||
|
- Do not invent APIs
|
||||||
|
- Do not assume external libraries exist
|
||||||
|
- Generate code **file by file**, not everything at once
|
||||||
|
- Ask before changing architecture or ownership boundaries
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## When to Ask Before Proceeding
|
||||||
|
|
||||||
|
Ask the maintainer if unclear:
|
||||||
|
- UX or menu flow decisions
|
||||||
|
- Adding dependencies
|
||||||
|
- Refactors vs local patches
|
||||||
|
- Platform-specific behavior
|
||||||
271
docs/ai/cooperate_network.md
Normal file
271
docs/ai/cooperate_network.md
Normal file
@ -0,0 +1,271 @@
|
|||||||
|
# Spacetris — COOPERATE Mode
|
||||||
|
## Network Multiplayer (2 PLAYER – NETWORK)
|
||||||
|
### VS Code Copilot AI Agent Prompt
|
||||||
|
|
||||||
|
You are integrating **online cooperative multiplayer** into an existing **C++ / SDL3 game** called **Spacetris**.
|
||||||
|
|
||||||
|
This feature extends the existing **COOPERATE mode** to support:
|
||||||
|
- Local 2 players
|
||||||
|
- Human + AI
|
||||||
|
- **Human + Human over network (NEW)**
|
||||||
|
|
||||||
|
The networking solution must be **deterministic, lightweight, and stable**.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 1. High-Level Goal
|
||||||
|
|
||||||
|
Add **COOPERATE 2 PLAYER (NETWORK)** mode where:
|
||||||
|
- Two players play together over the internet
|
||||||
|
- Each player controls one half of the shared grid
|
||||||
|
- A line clears only when both halves are filled
|
||||||
|
- Gameplay remains identical to local COOPERATE mode
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 2. Technology Constraints
|
||||||
|
|
||||||
|
- Language: **C++**
|
||||||
|
- Engine: **SDL3**
|
||||||
|
- Networking: **ENet (UDP with reliability)**
|
||||||
|
- No engine rewrite
|
||||||
|
- No authoritative server logic required (co-op only)
|
||||||
|
|
||||||
|
SDL3 is used ONLY for:
|
||||||
|
- Rendering
|
||||||
|
- Input
|
||||||
|
- Timing
|
||||||
|
|
||||||
|
Networking is a **separate layer**.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 3. Network Model (MANDATORY)
|
||||||
|
|
||||||
|
### Use **Input Lockstep Networking**
|
||||||
|
|
||||||
|
#### Core idea:
|
||||||
|
- Both clients run the same deterministic simulation
|
||||||
|
- Only **player inputs** are sent over the network
|
||||||
|
- No board state is transmitted
|
||||||
|
- Both simulations must remain identical
|
||||||
|
|
||||||
|
This model is ideal for Tetris-like games.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 4. Determinism Requirements (CRITICAL)
|
||||||
|
|
||||||
|
To ensure lockstep works:
|
||||||
|
|
||||||
|
- Fixed simulation tick (e.g. 60 Hz)
|
||||||
|
- Identical RNG seed for both clients
|
||||||
|
- Deterministic piece generation (bag system)
|
||||||
|
- No floating-point math in core gameplay
|
||||||
|
- Same gravity, rotation, lock-delay logic
|
||||||
|
- Identical line clear and scoring rules
|
||||||
|
|
||||||
|
Before networking:
|
||||||
|
- Input recording + replay must produce identical results
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 5. Network Topology
|
||||||
|
|
||||||
|
### Host / Client Model (Initial Implementation)
|
||||||
|
|
||||||
|
- One player hosts the game
|
||||||
|
- One player joins
|
||||||
|
- Host is authoritative for:
|
||||||
|
- RNG seed
|
||||||
|
- start tick
|
||||||
|
- game settings
|
||||||
|
|
||||||
|
This is sufficient and fair for cooperative gameplay.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 6. Network Library
|
||||||
|
|
||||||
|
Use **ENet** for:
|
||||||
|
- Reliable, ordered UDP packets
|
||||||
|
- Low latency
|
||||||
|
- Simple integration with C++
|
||||||
|
|
||||||
|
Do NOT use:
|
||||||
|
- SDL_net
|
||||||
|
- TCP-only networking
|
||||||
|
- High-level matchmaking SDKs
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 7. Network Packet Design
|
||||||
|
|
||||||
|
### Input Packet (Minimal)
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
struct InputPacket {
|
||||||
|
uint32_t tick;
|
||||||
|
uint8_t buttons; // bitmask
|
||||||
|
};
|
||||||
|
````
|
||||||
|
|
||||||
|
Button bitmask example:
|
||||||
|
|
||||||
|
* bit 0 → move left
|
||||||
|
* bit 1 → move right
|
||||||
|
* bit 2 → rotate
|
||||||
|
* bit 3 → soft drop
|
||||||
|
* bit 4 → hard drop
|
||||||
|
* bit 5 → hold
|
||||||
|
|
||||||
|
Packets must be:
|
||||||
|
|
||||||
|
* Reliable
|
||||||
|
* Ordered
|
||||||
|
* Small
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 8. Tick & Latency Handling
|
||||||
|
|
||||||
|
### Input Delay Buffer (RECOMMENDED)
|
||||||
|
|
||||||
|
* Add fixed delay: **4–6 ticks**
|
||||||
|
* Simulate tick `T` using inputs for `T + delay`
|
||||||
|
* Prevents stalls due to latency spikes
|
||||||
|
|
||||||
|
Strict lockstep without buffering is NOT recommended.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 9. Desync Detection (IMPORTANT)
|
||||||
|
|
||||||
|
Every N ticks (e.g. once per second):
|
||||||
|
|
||||||
|
* Compute a hash of:
|
||||||
|
|
||||||
|
* Both grid halves
|
||||||
|
* Active pieces
|
||||||
|
* RNG index
|
||||||
|
* Score / lines / level
|
||||||
|
* Exchange hashes
|
||||||
|
* If mismatch:
|
||||||
|
|
||||||
|
* Log desync
|
||||||
|
* Stop game or mark session invalid
|
||||||
|
|
||||||
|
This is required for debugging and stability.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 10. Network Session Architecture
|
||||||
|
|
||||||
|
Create a dedicated networking module:
|
||||||
|
|
||||||
|
```
|
||||||
|
/network
|
||||||
|
NetSession.h
|
||||||
|
NetSession.cpp
|
||||||
|
```
|
||||||
|
|
||||||
|
Responsibilities:
|
||||||
|
|
||||||
|
* ENet host/client setup
|
||||||
|
* Input packet send/receive
|
||||||
|
* Tick synchronization
|
||||||
|
* Latency buffering
|
||||||
|
* Disconnect handling
|
||||||
|
|
||||||
|
SDL main loop must NOT block on networking.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 11. Integration with Existing COOPERATE Logic
|
||||||
|
|
||||||
|
* COOPERATE grid logic stays unchanged
|
||||||
|
* SyncLineRenderer remains unchanged
|
||||||
|
* Scoring logic remains unchanged
|
||||||
|
* Network layer only injects **remote inputs**
|
||||||
|
|
||||||
|
Game logic should not know whether partner is:
|
||||||
|
|
||||||
|
* Local human
|
||||||
|
* AI
|
||||||
|
* Network player
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 12. UI Integration (Menu Changes)
|
||||||
|
|
||||||
|
In COOPERATE selection screen, add a new button:
|
||||||
|
|
||||||
|
```
|
||||||
|
[ LOCAL CO-OP ] [ AI PARTNER ] [ 2 PLAYER (NETWORK) ]
|
||||||
|
```
|
||||||
|
|
||||||
|
### On selecting 2 PLAYER (NETWORK):
|
||||||
|
|
||||||
|
* Show:
|
||||||
|
|
||||||
|
* Host Game
|
||||||
|
* Join Game
|
||||||
|
* Display join code or IP
|
||||||
|
* Confirm connection before starting
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 13. Start Game Flow (Network)
|
||||||
|
|
||||||
|
1. Host creates session
|
||||||
|
2. Client connects
|
||||||
|
3. Host sends:
|
||||||
|
|
||||||
|
* RNG seed
|
||||||
|
* start tick
|
||||||
|
* game settings
|
||||||
|
4. Both wait until agreed start tick
|
||||||
|
5. Simulation begins simultaneously
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 14. Disconnect & Error Handling
|
||||||
|
|
||||||
|
* If connection drops:
|
||||||
|
|
||||||
|
* Pause game
|
||||||
|
* Show “Reconnecting…”
|
||||||
|
* After timeout:
|
||||||
|
|
||||||
|
* End match or switch to AI (optional)
|
||||||
|
* Never crash
|
||||||
|
* Never corrupt game state
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 15. What NOT to Implement
|
||||||
|
|
||||||
|
* ❌ Full state synchronization
|
||||||
|
* ❌ Prediction / rollback
|
||||||
|
* ❌ Server-authoritative gameplay
|
||||||
|
* ❌ Complex matchmaking
|
||||||
|
* ❌ Versus mechanics
|
||||||
|
|
||||||
|
This is cooperative, not competitive.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 16. Acceptance Criteria
|
||||||
|
|
||||||
|
* Two players can complete COOPERATE mode over network
|
||||||
|
* Gameplay matches local COOPERATE exactly
|
||||||
|
* No noticeable input lag under normal latency
|
||||||
|
* Desync detection works
|
||||||
|
* Offline / disconnect handled gracefully
|
||||||
|
* SDL3 render loop remains smooth
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 17. Summary for Copilot
|
||||||
|
|
||||||
|
Integrate networked cooperative multiplayer into Spacetris using SDL3 + C++ with ENet. Implement input lockstep networking with deterministic simulation, fixed tick rate, input buffering, and desync detection. Add a new COOPERATE menu option “2 PLAYER (NETWORK)” that allows host/join flow. Networking must be modular, non-blocking, and transparent to existing gameplay logic.
|
||||||
Reference in New Issue
Block a user