Skip to content

Commit 90a5484

Browse files
committed
a few more rounds
1 parent dc3bfcf commit 90a5484

115 files changed

Lines changed: 6001 additions & 2411 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.dockerignore

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
**/.git
2+
**/.vs
3+
**/.vscode
4+
**/bin
5+
**/obj
6+
**/out
7+
**/*.user
8+
**/*.suo
9+
**/*.sln.docstates
10+
**/*.log
11+
.dockerignore
12+
Dockerfile
13+
docker-compose.yml
14+
docker-compose.override.yml
15+
README.md
16+
CONTRIBUTING.md
17+
LICENSE
18+
.gitignore
19+
.editorconfig
20+
.gemini/
21+
.claude/
22+
.specify/
23+
specs/
24+
docs/
25+
tests/
26+
node_modules/
27+
npm-debug.log
28+
yarn-error.log
29+
.env
30+
.env.*
31+
appsettings.Development.json
32+
appsettings.Local.json
33+
secrets.json

.github/dependabot.yml

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
version: 2
2+
updates:
3+
- package-ecosystem: "nuget"
4+
directory: "/"
5+
schedule:
6+
interval: "weekly"
7+
open-pull-requests-limit: 10
8+
9+
- package-ecosystem: "docker"
10+
directory: "/"
11+
schedule:
12+
interval: "weekly"
13+
open-pull-requests-limit: 10
14+
15+
- package-ecosystem: "github-actions"
16+
directory: "/"
17+
schedule:
18+
interval: "weekly"
19+
open-pull-requests-limit: 10

.github/workflows/ci.yaml

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
name: CI
2+
3+
on:
4+
push:
5+
branches: [ main ]
6+
pull_request:
7+
branches: [ main ]
8+
9+
jobs:
10+
build:
11+
runs-on: ubuntu-latest
12+
13+
steps:
14+
- uses: actions/checkout@v4
15+
16+
- name: Setup .NET
17+
uses: actions/setup-dotnet@v4
18+
with:
19+
dotnet-version: 10.0.x
20+
21+
- name: Restore dependencies
22+
run: dotnet restore
23+
24+
- name: Build
25+
run: dotnet build --no-restore --configuration Release
26+
27+
- name: Test
28+
run: dotnet test --no-build --configuration Release --collect:"XPlat Code Coverage"
29+
30+
- name: Upload coverage reports to Codecov
31+
uses: codecov/codecov-action@v5
32+
with:
33+
token: ${{ secrets.CODECOV_TOKEN }}

.gitignore

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,6 @@ BenchmarkDotNet.Artifacts/
157157
.aspire/
158158

159159
# Docker
160-
.dockerignore
161160
docker-compose.override.yml
162161

163162
# Temporary files

CONTRIBUTING.md

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
# Contributing to NetRTS
2+
3+
Thank you for your interest in contributing to NetRTS! This project follows strict architectural and testing guidelines.
4+
5+
## Development Workflow
6+
7+
We follow a **Test-First Development (TDD)** approach.
8+
9+
1. **Define Requirements**: Understand the feature or bug you are working on.
10+
2. **Write Tests**: Write BDD scenarios (Gherkin) in `tests/NetRts.ContractTests` and unit tests in `tests/NetRts.UnitTests`.
11+
3. **Ensure Failure**: Run the tests and ensure they fail.
12+
4. **Implement**: Write the minimum amount of code required to make the tests pass.
13+
5. **Refactor**: Clean up the code while ensuring tests remain green.
14+
15+
## Architecture
16+
17+
We use **Clean Architecture** with the following layers:
18+
19+
- **Domain**: Core entities, value objects, and business rules. No dependencies.
20+
- **Application**: CQRS handlers (MediatR), interfaces, and application services.
21+
- **Infrastructure**: Persistence (EF Core), background services, and external integrations.
22+
- **Api**: Minimal APIs, SignalR hubs, and middleware.
23+
- **Client**: Blazor WebAssembly frontend.
24+
- **Contracts**: Shared DTOs and event models.
25+
26+
## Coding Standards
27+
28+
- Use C# 12 features (primary constructors, collection expressions, etc.).
29+
- Adhere to the `.editorconfig` rules.
30+
- Add XML documentation to all public members.
31+
- Use structured logging with Serilog.
32+
33+
## Pull Request Process
34+
35+
1. Create a new branch for your feature or fix.
36+
2. Ensure all tests pass locally (`dotnet test`).
37+
3. Submit a PR with a clear description of the changes.
38+
4. Maintain high test coverage (minimum 80%).

Directory.Build.props

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,11 @@
3030
<IsPackable>false</IsPackable>
3131
<GenerateDocumentationFile>false</GenerateDocumentationFile>
3232
<TreatWarningsAsErrors>false</TreatWarningsAsErrors>
33+
<!-- Coverage Settings -->
34+
<CollectCoverage>true</CollectCoverage>
35+
<CoverletOutputFormat>opencover,cobertura</CoverletOutputFormat>
36+
<Threshold>80</Threshold>
37+
<ExcludeByFile>**/Migrations/*.cs</ExcludeByFile>
3338
</PropertyGroup>
3439

3540
<!-- Package Metadata (for libraries) -->

README.md

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
# NetRTS - Real-Time Strategy Game Engine for Programming Competitions
2+
3+
NetRTS is a specialized RTS game engine designed for programming competitions where players control their units through a REST API.
4+
5+
## Features
6+
7+
- **Tick-Based Engine**: Consistent 1-second game ticks.
8+
- **REST API for Bots**: Complete control over units and buildings via simple JSON commands.
9+
- **Fog of War**: Real-time vision calculations using QuadTree spatial indexing.
10+
- **Resource Management**: Gather resources, build structures, and produce units.
11+
- **Upgrades**: Enhance unit and building capabilities through research.
12+
- **Real-Time UI**: Blazor-based web client for monitoring matches.
13+
- **Distributed Observability**: Built with .NET Aspire for comprehensive logging and telemetry.
14+
15+
## Getting Started
16+
17+
### Prerequisites
18+
19+
- [.NET 10.0 SDK](https://dotnet.microsoft.com/download/dotnet/10.0)
20+
- [Docker Desktop](https://www.docker.com/products/docker-desktop) (for PostgreSQL)
21+
22+
### Running the Application
23+
24+
The easiest way to run the entire system is using .NET Aspire:
25+
26+
```bash
27+
dotnet run --project src/NetRts.AppHost
28+
```
29+
30+
This will start:
31+
- **API**: The backend game engine.
32+
- **Client**: The Blazor web dashboard.
33+
- **Database**: PostgreSQL container for persistence.
34+
35+
### Accessing the Dashboard
36+
37+
Once started, the Aspire dashboard will be available at the URL shown in your console (usually `http://localhost:18888`). From there, you can access the API Swagger UI and the Web Client.
38+
39+
## Bot Development
40+
41+
Bots interact with the engine using standard HTTP requests.
42+
43+
### Basic Workflow
44+
45+
1. **Register/Login**: Get a JWT token.
46+
2. **Join Lobby**: Find or create a match.
47+
3. **Get Game State**: `GET /api/v1/matches/{matchId}/state`
48+
4. **Queue Commands**: `POST /api/v1/matches/{matchId}/commands`
49+
50+
### Example Move Command
51+
52+
```json
53+
{
54+
"commands": [
55+
{
56+
"commandType": "Move",
57+
"unitIds": [1, 2, 3],
58+
"targetPosition": { "x": 50, "y": 50 }
59+
}
60+
]
61+
}
62+
```
63+
64+
## Architecture
65+
66+
- **Domain**: Pure domain logic, entities, and business rules.
67+
- **Application**: CQRS handlers using MediatR, command validation with FluentValidation.
68+
- **Infrastructure**: EF Core persistence, background game loop, spatial indexing.
69+
- **API**: Minimal APIs for low-latency command queueing.
70+
- **Client**: Blazor WebAssembly for real-time visualization.
71+
72+
## License
73+
74+
MIT

docker-compose.yml

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
services:
2+
api:
3+
image: netrts-api
4+
build:
5+
context: .
6+
dockerfile: src/NetRts.Api/Dockerfile
7+
ports:
8+
- "5000:8080"
9+
environment:
10+
- ASPNETCORE_ENVIRONMENT=Development
11+
- ConnectionStrings__netrtsdb=Host=db;Database=netrts;Username=postgres;Password=postgres
12+
depends_on:
13+
db:
14+
condition: service_healthy
15+
16+
client:
17+
image: netrts-client
18+
build:
19+
context: .
20+
dockerfile: src/NetRts.Client/Dockerfile
21+
ports:
22+
- "5001:8080"
23+
depends_on:
24+
- api
25+
26+
db:
27+
image: postgres:16-alpine
28+
environment:
29+
- POSTGRES_DB=netrts
30+
- POSTGRES_USER=postgres
31+
- POSTGRES_PASSWORD=postgres
32+
ports:
33+
- "5432:5432"
34+
healthcheck:
35+
test: ["CMD-SHELL", "pg_isready -U postgres"]
36+
interval: 5s
37+
timeout: 5s
38+
retries: 5

docs/adr/0001-spatial-indexing.md

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
# ADR 0001: Spatial Indexing for Fog of War and Collision Detection
2+
3+
## Status
4+
Accepted
5+
6+
## Context
7+
The game engine needs to perform frequent spatial queries, such as:
8+
- Calculating visibility (Fog of War) for units and buildings.
9+
- Finding units within range for combat.
10+
- Checking for collisions during movement and building placement.
11+
12+
With up to 100 concurrent matches and hundreds of entities per match, a naive O(N^2) approach for distance checks would be too slow to maintain a 1-second tick interval.
13+
14+
## Decision
15+
We will use a **QuadTree** data structure for spatial indexing.
16+
17+
A QuadTree is a tree data structure in which each internal node has exactly four children. It is used to partition a two-dimensional space by recursively subdividing it into four quadrants or regions.
18+
19+
## Alternatives Considered
20+
1. **Naive O(N^2)**: Too slow for the required scale.
21+
2. **Grid-based Partitioning**: Simple to implement but less efficient for unevenly distributed entities.
22+
3. **R-Tree**: Good for range queries but more complex to implement and maintain than a QuadTree for point-based entities.
23+
24+
## Consequences
25+
- **Pros**:
26+
- Reduces query complexity from O(N) to O(log N) on average.
27+
- Efficiently handles clusters of units and sparse regions.
28+
- Well-suited for 2D game worlds.
29+
- **Cons**:
30+
- Requires rebuilding or updating the tree every tick as units move.
31+
- Slightly more memory overhead than a simple list or grid.

k8s/api.yaml

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
apiVersion: apps/v1
2+
kind: Deployment
3+
metadata:
4+
name: netrts-api
5+
spec:
6+
replicas: 3
7+
selector:
8+
matchLabels:
9+
app: netrts-api
10+
template:
11+
metadata:
12+
labels:
13+
app: netrts-api
14+
spec:
15+
containers:
16+
- name: api
17+
image: netrts-api:latest
18+
imagePullPolicy: IfNotPresent
19+
ports:
20+
- containerPort: 8080
21+
envFrom:
22+
- configMapRef:
23+
name: netrts-config
24+
- secretRef:
25+
name: netrts-secrets
26+
readinessProbe:
27+
httpGet:
28+
path: /health
29+
port: 8080
30+
initialDelaySeconds: 10
31+
periodSeconds: 10
32+
livenessProbe:
33+
httpGet:
34+
path: /health
35+
port: 8080
36+
initialDelaySeconds: 15
37+
periodSeconds: 20
38+
resources:
39+
requests:
40+
memory: "128Mi"
41+
cpu: "250m"
42+
limits:
43+
memory: "512Mi"
44+
cpu: "500m"
45+
---
46+
apiVersion: v1
47+
kind: Service
48+
metadata:
49+
name: netrts-api
50+
spec:
51+
selector:
52+
app: netrts-api
53+
ports:
54+
- protocol: TCP
55+
port: 80
56+
targetPort: 8080
57+
type: LoadBalancer

0 commit comments

Comments
 (0)