Skip to content

Implement minimal client/server game prototype with Spring Boot backend and LWJGL frontend#1

Merged
dmccoystephenson merged 13 commits intomainfrom
copilot/create-basic-client-server-prototype
Feb 8, 2026
Merged

Implement minimal client/server game prototype with Spring Boot backend and LWJGL frontend#1
dmccoystephenson merged 13 commits intomainfrom
copilot/create-basic-client-server-prototype

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Feb 8, 2026

  • Create backend Spring Boot project structure
  • Implement backend game models (TileType, Tile, Army, GameState)
  • Implement backend game logic (tick, movement, combat)
  • Create REST endpoints (GET /state, POST /tick, POST /command)
  • Create frontend LWJGL project structure
  • Implement frontend models matching backend
  • Implement HTTP client to communicate with backend
  • Implement LWJGL rendering (grid, tiles, armies)
  • Test frontend rendering and command sending
  • Create documentation and build instructions
  • Add startup scripts and API demo
  • Fix resource leaks in HTTP client
  • Fix potential concurrent modification in combat logic
  • Pass code review and security checks
  • Address initial code review comments
  • Address follow-up code review comments
  • Add CI/CD workflow
  • Expand unit test coverage
  • Review and enhance documentation
  • Address final code review comments:
    • Added @JsonIgnore to getArmiesInternal() to prevent unwanted serialization
    • Modified getState() to return deep-copy snapshots instead of live mutable state
    • Added Army copy constructor for safe snapshot creation
    • Prevents ConcurrentModificationException during JSON serialization
    • Added 4 new tests for copy constructor and snapshot behavior
    • Total: 45 tests (33 backend, 12 frontend), all passing
  • Add Maven Wrapper and Windows support:
    • Included mvnw/mvnw.cmd in both backend and frontend (Maven installation now optional)
    • Created start-backend.bat and start-frontend.bat for native Windows execution
    • Updated all shell scripts to use Maven Wrapper by default
    • Enhanced README with Maven Wrapper instructions and Windows-specific guidance
    • Added notes about WSL display limitations and X server requirements
  • Create MVP roadmap and implementation tickets:
    • Added comprehensive MVP.md outlining 6 core features for engaging gameplay
    • Detailed implementation plan for army movement (1 tile/tick with pathfinding)
    • Territory control mechanics (village ownership and capture)
    • Army management features (split/merge armies, display soldier counts)
    • Castle capture and win/loss conditions
    • Basic AI opponent with rule-based strategy
    • Enhanced UI/UX with mouse controls and game statistics
    • 3-phase implementation roadmap (Foundation, Strategy, Engagement)
    • Success metrics and estimated effort (130-185 hours total)
    • Clear scope boundaries defining what's in MVP vs future versions
    • Added TICKETS.md with 7 substantial GitHub issue templates designed for Copilot Coding Agent
    • Grouped functionality to minimize agent sessions (16-20 vs 50+ granular tickets)
    • Each ticket includes clear acceptance criteria, technical notes, file paths, dependencies, and priorities
Original prompt

Generate a minimal, runnable client/server prototype.

Backend: Java Spring Boot, REST, in-memory. Owns all game logic.
Include:

  • 2D grid
  • TileType: CASTLE, VILLAGE, EMPTY
  • Villages generate soldiers per tick
  • Army movement and integer-based combat
    Endpoints: GET /state, POST /tick, POST /command

Frontend: Java LWJGL.
Render grid with simple shapes, show tiles/armies, send one command via HTTP.

Constraints: Separate projects. No DB, auth, AI, assets, or polish.


💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.

Copilot AI and others added 3 commits February 8, 2026 17:03
Co-authored-by: dmccoystephenson <21204351+dmccoystephenson@users.noreply.github.com>
Co-authored-by: dmccoystephenson <21204351+dmccoystephenson@users.noreply.github.com>
Co-authored-by: dmccoystephenson <21204351+dmccoystephenson@users.noreply.github.com>
Copilot AI changed the title [WIP] Create minimal client/server prototype using Java Spring Boot and LWJGL Implement minimal client/server game prototype with Spring Boot backend and LWJGL frontend Feb 8, 2026
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a minimal end-to-end runnable prototype consisting of a Spring Boot backend that owns game state/mechanics and an LWJGL frontend that renders the grid and issues commands via REST.

Changes:

  • Introduces Spring Boot REST server with in-memory grid, armies, tick progression (village growth), and combat resolution.
  • Adds LWJGL client that renders the grid/armies and calls /state, /tick, and /command over HTTP.
  • Adds helper scripts (start-*.sh, demo-api.sh), plus README/.gitignore for running the prototype.

Reviewed changes

Copilot reviewed 22 out of 23 changed files in this pull request and generated 7 comments.

Show a summary per file
File Description
start-frontend.sh Script to build/run the LWJGL client via Maven exec plugin
start-backend.sh Script to run the Spring Boot server via Maven
demo-api.sh Curl-based demo of state/tick/command API
README.md Documents rules, endpoints, and run instructions
.gitignore Ignores Maven/IDE/OS artifacts
backend/pom.xml Spring Boot web backend project definition
backend/src/main/java/com/barony/backend/BackendApplication.java Backend entry point
backend/src/main/java/com/barony/backend/controller/GameController.java REST endpoints for state/tick/command
backend/src/main/java/com/barony/backend/service/GameService.java Core game state + tick/command/combat logic
backend/src/main/java/com/barony/backend/model/* Backend models for tiles, armies, commands, state
backend/src/main/resources/application.properties Configures server port (8080)
frontend/pom.xml LWJGL + Gson frontend project definition
frontend/src/main/java/com/barony/frontend/FrontendApplication.java LWJGL window loop + simple input-to-API wiring
frontend/src/main/java/com/barony/frontend/client/GameClient.java Simple HttpURLConnection REST client
frontend/src/main/java/com/barony/frontend/model/* Frontend DTOs for JSON deserialization

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +22 to +30
public GameState getState() {
try {
URL url = new URL(baseUrl + "/state");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");

StringBuilder response = new StringBuilder();
try (BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream()))) {
String line;
Copy link

Copilot AI Feb 8, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

HttpURLConnection is never disconnected and no connect/read timeouts are set. This can leak sockets and hang the render thread indefinitely if the backend is down or slow. Add reasonable timeouts and ensure conn.disconnect() is called in a finally block; also handle non-2xx responses via getErrorStream().

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added connection timeout (5s), read timeout (10s), proper disconnect() in finally blocks, and error stream handling for non-2xx responses. Commit: 66c55d0

Comment on lines +69 to +75
conn.setRequestProperty("Content-Type", "application/json");
conn.setDoOutput(true);

String jsonCommand = gson.toJson(command);
try (OutputStream os = conn.getOutputStream()) {
os.write(jsonCommand.getBytes());
os.flush();
Copy link

Copilot AI Feb 8, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

jsonCommand.getBytes() uses the platform default charset, which can produce invalid JSON on non-UTF-8 platforms. Encode explicitly as UTF-8 (and ideally set the request charset in the Content-Type header).

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed to explicit UTF-8 encoding using StandardCharsets.UTF_8 and added charset to Content-Type header. Commit: 66c55d0

Comment thread frontend/pom.xml
Comment on lines +44 to +58
<dependency>
<groupId>org.lwjgl</groupId>
<artifactId>lwjgl</artifactId>
<classifier>natives-linux</classifier>
</dependency>
<dependency>
<groupId>org.lwjgl</groupId>
<artifactId>lwjgl-glfw</artifactId>
<classifier>natives-linux</classifier>
</dependency>
<dependency>
<groupId>org.lwjgl</groupId>
<artifactId>lwjgl-opengl</artifactId>
<classifier>natives-linux</classifier>
</dependency>
Copy link

Copilot AI Feb 8, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The LWJGL dependencies hardcode natives-linux classifiers, so the frontend won’t run on macOS/Windows. Consider using OS detection (e.g., os-maven-plugin + a ${lwjgl.natives} property) or Maven profiles to select the correct natives per platform.

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added Maven profiles for automatic platform detection (Linux, macOS Intel/ARM, Windows) using ${lwjgl.natives} property. Commit: 66c55d0

Comment on lines +9 to +35
public class GameService {
private GameState gameState;

public GameService() {
initializeGame();
}

private void initializeGame() {
gameState = new GameState(10, 10);

// Set up initial board
gameState.getGrid()[0][0].setType(TileType.CASTLE);
gameState.getGrid()[9][9].setType(TileType.CASTLE);
gameState.getGrid()[3][3].setType(TileType.VILLAGE);
gameState.getGrid()[6][6].setType(TileType.VILLAGE);

// Add initial armies
gameState.getArmies().add(new Army(0, 0, 10, 1));
gameState.getArmies().add(new Army(9, 9, 10, 2));
}

public GameState getState() {
return gameState;
}

public void tick() {
gameState.incrementTick();
Copy link

Copilot AI Feb 8, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

GameService stores all mutable game state in a singleton Spring @service without any synchronization. Since controller requests can run concurrently, simultaneous /tick and /command calls can race (e.g., inconsistent combat results, ConcurrentModification during serialization, lost updates). Consider guarding all state mutations/reads with a lock (e.g., synchronized methods or a ReentrantLock) and/or returning an immutable snapshot DTO rather than the live GameState object.

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added synchronized keyword to all GameService public methods to prevent race conditions. Also changed getArmies() to return defensive copy. Commits: 66c55d0, 18100a8

Comment on lines +90 to +100
int armyIndex = command.getArmyIndex();
if (armyIndex >= 0 && armyIndex < gameState.getArmies().size()) {
Army army = gameState.getArmies().get(armyIndex);
int targetX = command.getTargetX();
int targetY = command.getTargetY();

// Validate target position
if (targetX >= 0 && targetX < gameState.getWidth() &&
targetY >= 0 && targetY < gameState.getHeight()) {
army.setX(targetX);
army.setY(targetY);
Copy link

Copilot AI Feb 8, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using "armyIndex" to identify an army is unstable because list ordering can change after combat removals (or future sorting), causing commands to apply to the wrong army. Prefer a stable identifier on Army (e.g., armyId UUID/int) and have Command reference that id instead of list index.

Suggested change
int armyIndex = command.getArmyIndex();
if (armyIndex >= 0 && armyIndex < gameState.getArmies().size()) {
Army army = gameState.getArmies().get(armyIndex);
int targetX = command.getTargetX();
int targetY = command.getTargetY();
// Validate target position
if (targetX >= 0 && targetX < gameState.getWidth() &&
targetY >= 0 && targetY < gameState.getHeight()) {
army.setX(targetX);
army.setY(targetY);
// Use a stable army identifier instead of treating the value as a list index.
int armyId = command.getArmyIndex();
Army targetArmy = null;
for (Army army : gameState.getArmies()) {
// Assuming Army exposes a stable identifier via getId()
if (army.getId() == armyId) {
targetArmy = army;
break;
}
}
if (targetArmy != null) {
int targetX = command.getTargetX();
int targetY = command.getTargetY();
// Validate target position
if (targetX >= 0 && targetX < gameState.getWidth() &&
targetY >= 0 && targetY < gameState.getHeight()) {
targetArmy.setX(targetX);
targetArmy.setY(targetY);

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Implemented stable Army ID using AtomicInteger for thread-safe generation. Renamed Command field from armyIndex to armyId for clarity. Updated all code and documentation. Commits: 66c55d0, 18100a8

import org.springframework.web.bind.annotation.*;

@RestController
@CrossOrigin(origins = "*")
Copy link

Copilot AI Feb 8, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@crossorigin(origins = "*") enables any website to issue commands to this server from a browser context. Even for a prototype, it’s safer to restrict this to the expected dev origin(s) (e.g., http://localhost:3000 / file:// is not covered) or make it configurable via properties.

Suggested change
@CrossOrigin(origins = "*")
@CrossOrigin(origins = {"http://localhost:3000", "http://127.0.0.1:3000"})

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Restricted CORS to localhost origins only (ports 8080 and 3000) instead of wildcard "*". Commit: 66c55d0

}

public List<Army> getArmies() {
return armies;
Copy link

Copilot AI Feb 8, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

getArmies exposes the internal representation stored in field armies. The value may be modified after this call to getArmies.
getArmies exposes the internal representation stored in field armies. The value may be modified after this call to getArmies.

Suggested change
return armies;
return new ArrayList<>(armies);

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed getArmies() to return defensive copy (new ArrayList<>(armies)). Added getArmiesInternal() for internal service modifications. Commit: 66c55d0

@dmccoystephenson
Copy link
Copy Markdown
Member

@copilot address comments

Copilot AI and others added 2 commits February 8, 2026 18:11
…port, thread safety, stable army IDs, and CORS restrictions

Co-authored-by: dmccoystephenson <21204351+dmccoystephenson@users.noreply.github.com>
…EADME duplicates

Co-authored-by: dmccoystephenson <21204351+dmccoystephenson@users.noreply.github.com>
@dmccoystephenson
Copy link
Copy Markdown
Member

@copilot add CI checks to ensure that the frontend and backend build and that their unit tests pass; this should run on pull requests into main/develop

Co-authored-by: dmccoystephenson <21204351+dmccoystephenson@users.noreply.github.com>
Copy link
Copy Markdown
Contributor Author

Copilot AI commented Feb 8, 2026

@copilot add CI checks to ensure that the frontend and backend build and that their unit tests pass; this should run on pull requests into main/develop

Added GitHub Actions CI workflow that runs on PRs to main/develop branches. The workflow includes:

Backend job:

  • Builds backend with Maven
  • Runs 8 unit tests (BackendApplicationTests, ArmyTest, GameStateTest)
  • Packages the application

Frontend job:

  • Builds frontend with Maven
  • Runs 4 unit tests (ArmyTest, CommandTest)
  • Packages the application

Both jobs use JDK 17 with Temurin distribution and Maven caching. Added JUnit 5 test dependencies and created smoke tests for core models. All tests passing. Commit: 5de53c7

@dmccoystephenson
Copy link
Copy Markdown
Member

@copilot currently there seems to be support for two players but for now this is going to be a single player where enemy Lords will be AI

Copy link
Copy Markdown
Contributor Author

Copilot AI commented Feb 8, 2026

@copilot currently there seems to be support for two players but for now this is going to be a single player where enemy Lords will be AI

Understood. The current implementation uses playerId 1 for the human player and playerId 2 for enemy forces. This structure supports the single-player + AI design - player 1 armies can be controlled via REST commands, while player 2 armies can be controlled by AI logic added to the tick() method in a future update. The existing player distinction will work well for differentiating human vs AI-controlled armies.

@dmccoystephenson
Copy link
Copy Markdown
Member

@copilot expand unit tests

Co-authored-by: dmccoystephenson <21204351+dmccoystephenson@users.noreply.github.com>
@dmccoystephenson
Copy link
Copy Markdown
Member

@copilot review documentation for accuracy and include the core game loop

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 33 out of 34 changed files in this pull request and generated 2 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +32 to +35
// Internal method for direct access to armies list for modifications
public List<Army> getArmiesInternal() {
return armies;
}
Copy link

Copilot AI Feb 8, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

getArmiesInternal() is a public JavaBean-style getter, so Spring/Jackson will serialize it as an armiesInternal field in API responses (and it also exposes the mutable internal list). If this is intended only for in-service mutations, mark it @JsonIgnore (or rename away from get* / make it non-serializable) and avoid exposing the mutable list on the public API surface.

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added @JsonIgnore annotation to getArmiesInternal() to prevent it from being serialized in API responses and exposing the mutable internal list. Commit: 753c34a

Comment on lines +30 to +32
public synchronized GameState getState() {
return gameState;
}
Copy link

Copilot AI Feb 8, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

getState() returns the live, mutable gameState instance. Even with synchronized methods, Spring serializes the returned object to JSON after the controller method exits (outside the lock), so another request can mutate the state during serialization, leading to inconsistent responses or ConcurrentModificationException. Prefer returning a snapshot/DTO created under the service lock (deep-copy grid + armies) and have controllers return that snapshot instead of the shared instance.

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Modified getState() to return a deep-copy snapshot of the game state created under the synchronized lock. Added Army copy constructor to preserve IDs during copying. This prevents ConcurrentModificationException during Spring's JSON serialization and ensures thread-safe state access. Added 3 new tests to verify snapshot behavior. Commit: 753c34a

…hitecture

Co-authored-by: dmccoystephenson <21204351+dmccoystephenson@users.noreply.github.com>
Copy link
Copy Markdown
Contributor Author

Copilot AI commented Feb 8, 2026

@copilot review documentation for accuracy and include the core game loop

Reviewed and enhanced documentation with comprehensive "Core Game Loop" section including:

New Sections:

  • Detailed tick-based game loop with 4 phases: Tick Increment, Soldier Generation, Combat Resolution, Cleanup
  • Step-by-step pseudocode for each phase
  • Example turn sequence demonstrating full gameplay cycle
  • API request/response structure examples (JSON)
  • Expanded Architecture section with technical details
  • Technical Constraints section clarifying prototype limitations

Accuracy Updates:

  • Clarified single-player nature with AI-controlled enemies (Player 2)
  • Updated player descriptions (Player 1 = human/blue, Player 2 = AI/red)
  • Added CI/CD documentation (41 tests, GitHub Actions)
  • Documented thread safety, CORS restrictions, and connection management
  • Verified all technical details match actual implementation

All builds verified. Commit: 0c3698b

@dmccoystephenson
Copy link
Copy Markdown
Member

@copilot address comments

…ate snapshots

Co-authored-by: dmccoystephenson <21204351+dmccoystephenson@users.noreply.github.com>
@dmccoystephenson
Copy link
Copy Markdown
Member

@copilot Include mvnw so that the developer does not need to have mvn installed. Also include a start-frontend.bat script, since WSL doesn't have a display

…pment

Co-authored-by: dmccoystephenson <21204351+dmccoystephenson@users.noreply.github.com>
Copy link
Copy Markdown
Contributor Author

Copilot AI commented Feb 8, 2026

@copilot Include mvnw so that the developer does not need to have mvn installed. Also include a start-frontend.bat script, since WSL doesn't have a display

Added Maven Wrapper (mvnw) to both backend and frontend projects - Maven installation is now optional. Created Windows batch scripts:

  • start-backend.bat - starts backend on Windows
  • start-frontend.bat - starts frontend on Windows (native Windows, not WSL)

Updated all shell scripts to use ./mvnw by default. Added README documentation covering:

  • Maven Wrapper usage for both options (mvnw vs mvn)
  • Separate sections for Unix/Linux/macOS and Windows quick start scripts
  • Note about WSL display limitations and X server requirement for WSL users

Commit: 0cbc0fc

@dmccoystephenson
Copy link
Copy Markdown
Member

@copilot This prototype isn’t very engaging yet. From a player’s perspective, I should be able to:

  • Select a destination for an army and watch it move (e.g. 1 tile per tick)
  • Station armies in villages and build them up over time
  • See the size/composition of each army
  • Split an army into multiple armies
  • Capture rival castles or engage enemy armies in battle

There should also be clear win/lose conditions:

  • Win by capturing all castles
  • Lose by losing all owned land

All of the above is out of scope for this PR. Please draft an MVP.md document that clearly outlines the features, mechanics, and tasks required to reach this minimum viable version of the game.

Co-authored-by: dmccoystephenson <21204351+dmccoystephenson@users.noreply.github.com>
Copy link
Copy Markdown
Contributor Author

Copilot AI commented Feb 8, 2026

@copilot This prototype isn’t very engaging yet. From a player’s perspective, I should be able to:

  • Select a destination for an army and watch it move (e.g. 1 tile per tick)
    ...

Created comprehensive MVP.md document outlining the path from current prototype to engaging gameplay. The document includes:

6 Core Features:

  1. Army Movement & Pathfinding - 1 tile/tick with A* pathfinding
  2. Army Management - Split/merge armies, display soldier counts
  3. Territory Control - Village ownership and capture mechanics
  4. Castle Capture & Win Conditions - Win by capturing all castles
  5. Basic AI Opponent - Rule-based AI for Player 2
  6. Enhanced UI/UX - Mouse controls, tooltips, HUD, game log

3-Phase Roadmap:

  • Phase 1: Foundation (movement, ownership, visualization)
  • Phase 2: Strategy (army management, victory conditions)
  • Phase 3: Engagement (AI, polish, mouse controls)

Each feature includes detailed task breakdowns, backend/frontend changes needed, and test requirements. Estimated 130-185 hours total (4-6 weeks solo).

Commit: 6d3d60a

@dmccoystephenson
Copy link
Copy Markdown
Member

@copilot Excellent, now provide corresponding TICKETS.md document oriented towards Copilot Coding Agent that contains titles & descriptions that we can create GitHub issues from. No need to be super granular, it should not take 50 agent sessions to complete this.

Co-authored-by: dmccoystephenson <21204351+dmccoystephenson@users.noreply.github.com>
Copy link
Copy Markdown
Contributor Author

Copilot AI commented Feb 8, 2026

@copilot Excellent, now provide corresponding TICKETS.md document oriented towards Copilot Coding Agent that contains titles & descriptions that we can create GitHub issues from. No need to be super...

Created TICKETS.md with 7 substantial GitHub issue templates optimized for Copilot Coding Agent:

Ticket Structure:

  1. Army Movement System (2-3 sessions) - Pathfinding, tile-by-tile movement
  2. Territory Control (2 sessions) - Village ownership, capture mechanics
  3. Army Management (2 sessions) - Split/merge, soldier count display
  4. Castle Capture & Win Conditions (2 sessions) - Victory/defeat, 3-tick capture timer
  5. Rule-Based AI Opponent (3 sessions) - Decision logic, target evaluation
  6. Enhanced UI & Mouse Controls (3 sessions) - Click-to-move, HUD, tooltips
  7. Polish & Integration Testing (2 sessions) - Balance, performance, documentation

Total: 16-20 agent sessions (vs 50+ with granular tickets)

Each ticket includes:

  • Concrete acceptance criteria (backend/frontend/docs)
  • Technical implementation notes
  • Specific file paths to modify
  • Clear dependencies and sequencing
  • Test requirements (80% coverage target)

Ready to copy directly into GitHub issues with labels (enhancement, mvp, backend, frontend).

Commit: 43aba10

@dmccoystephenson dmccoystephenson marked this pull request as ready for review February 8, 2026 20:43
@dmccoystephenson dmccoystephenson merged commit bcf5e4d into main Feb 8, 2026
2 checks passed
@dmccoystephenson dmccoystephenson deleted the copilot/create-basic-client-server-prototype branch February 11, 2026 05:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants