-
Notifications
You must be signed in to change notification settings - Fork 0
Optimize network performance for remote server deployment #299
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Co-authored-by: dmccoystephenson <21204351+dmccoystephenson@users.noreply.github.com>
Co-authored-by: dmccoystephenson <21204351+dmccoystephenson@users.noreply.github.com>
- Add PlayerControllerTest with tests for food consumption incrementing foodEaten stat - Update PersistenceIntegrationTest to verify player stats persistence - Fix copyPlayerData method to include stats fields when loading player data - All tests pass successfully Co-authored-by: dmccoystephenson <21204351+dmccoystephenson@users.noreply.github.com>
- Add visitedRooms Set to Player to track unique rooms visited - Automatically increment roomsExplored when player enters new room - Add visited_rooms column to players table for persistence - Update PlayerService to call visitRoom() on room transitions - Update PersistenceService to save/load visited rooms as semicolon-separated string - Initialize new players with starting room (0,0) already visited - All tests passing Co-authored-by: dmccoystephenson <21204351+dmccoystephenson@users.noreply.github.com>
- Remove score and number of deaths from stats screen display - Keep only implemented stats: rooms explored and food eaten - Update fetchStatsFromServer to only fetch implemented stats - Simplify stats screen to show only working features Co-authored-by: dmccoystephenson <21204351+dmccoystephenson@users.noreply.github.com>
- Update comments to say 'semicolon-separated' instead of 'comma-separated' - Code was already using semicolons correctly, only comments needed fixing Co-authored-by: dmccoystephenson <21204351+dmccoystephenson@users.noreply.github.com>
- Reduced tick update frequency from 20/sec to 4/sec (5x improvement) - Eliminated redundant player data request by reusing tick response data - Implemented smart room reloading (only on room change, not every tick) - Added debounced room refresh after gather/place actions (500ms cooldown) - Added HTTP connection pooling with persistent connections - Added 5-second request timeout for faster failure detection - Added comprehensive performance documentation Co-authored-by: dmccoystephenson <21204351+dmccoystephenson@users.noreply.github.com>
Co-authored-by: dmccoystephenson <21204351+dmccoystephenson@users.noreply.github.com>
- Fixed misleading comment about retry logic - Removed unnecessary hasattr check in close() method Co-authored-by: dmccoystephenson <21204351+dmccoystephenson@users.noreply.github.com>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
This pull request implements significant network performance optimizations for remote server deployment scenarios. The game was experiencing severe lag when the server ran on a VM and clients connected over a network, primarily due to excessive HTTP requests (~60/sec during normal gameplay).
Changes:
- Reduced tick update frequency from every 3 frames to every 15 frames, decreasing requests from ~20/sec to ~4/sec
- Eliminated redundant player data requests by extracting player state from tick response instead of separate GET calls
- Implemented smart room reloading that only fetches room data on room transitions rather than every tick
- Added debounced room refresh mechanism with 500ms cooldown for gather/place actions to prevent request spam
- Introduced HTTP connection pooling with persistent connections and 5-second request timeouts
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 5 comments.
| File | Description |
|---|---|
| src/screen/serverBackedWorldScreen.py | Implements reduced tick frequency (15 frames), player data extraction from tick response, conditional room loading on transitions, and debounced room refresh with tracking variables for optimization |
| src/client/api_client.py | Adds HTTP session with connection pooling (HTTPAdapter), configurable request timeout (5s default), and close() method for resource cleanup |
| docs/PERFORMANCE.md | Comprehensive documentation of optimization strategies, impact measurements, configuration options, and future improvement opportunities |
| docs/OPTIMIZATION_SUMMARY.md | User-friendly summary of optimizations with before/after comparisons, performance metrics, and testing recommendations |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
docs/OPTIMIZATION_SUMMARY.md
Outdated
| Tunable parameters in `serverBackedWorldScreen.py`: | ||
|
|
||
| ```python | ||
| tick_update_frequency = 15 # Lower = fewer updates, higher = more responsive |
Copilot
AI
Feb 1, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The comment states "Lower = fewer updates, higher = more responsive" but this is backwards. Lower values (e.g., 5) mean the tick updates MORE frequently (every 5 frames), making it more responsive but using more network. Higher values (e.g., 30) mean the tick updates LESS frequently (every 30 frames), using less network but being less responsive. The comment should be: "Lower = more frequent updates (more responsive, higher network usage), higher = less frequent updates (less responsive, lower network usage)".
| tick_update_frequency = 15 # Lower = fewer updates, higher = more responsive | |
| tick_update_frequency = 15 # Lower = more frequent updates (more responsive, higher network usage), higher = less frequent updates (less responsive, lower network usage) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed in ae554b7. Comment now correctly states: "Lower = more frequent updates (more responsive, higher network usage), higher = less frequent updates (less responsive, lower network usage)".
| # OPTIMIZATION: Only reload room if player changed rooms or on demand | ||
| # Check if player moved to a different room since last tick | ||
| if self.player_data: | ||
| player_room_x = self.player_data.get('roomX', 0) | ||
| player_room_y = self.player_data.get('roomY', 0) | ||
| # Reload room every tick to show entity movements | ||
| self.load_room(player_room_x, player_room_y) | ||
|
|
||
| # Only reload if we're in a different room than currently displayed | ||
| if player_room_x != self.current_room_x or player_room_y != self.current_room_y: | ||
| logger.info(f"Player changed rooms from ({self.current_room_x}, {self.current_room_y}) to ({player_room_x}, {player_room_y})") | ||
| self.load_room(player_room_x, player_room_y) |
Copilot
AI
Feb 1, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The optimization to only reload rooms on room transitions means that entity movements within the same room will no longer be visible in real-time. The previous implementation reloaded the room every tick specifically to show entity movements. This tradeoff significantly impacts gameplay visibility and should be clearly documented in the PR description and performance documentation. Consider adding a note about this limitation and potentially implementing a separate mechanism for entity position updates if real-time entity tracking is important for gameplay.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Documented in ae554b7. Added clear warnings about this tradeoff in both PERFORMANCE.md and OPTIMIZATION_SUMMARY.md. The docs now explain that entity movements within the same room are not visible in real-time and recommend WebSocket integration for real-time entity tracking if needed.
docs/PERFORMANCE.md
Outdated
|
|
||
| ```python | ||
| # Client: serverBackedWorldScreen.py | ||
| tick_update_frequency = 15 # Increase for less network usage, decrease for more responsive feel |
Copilot
AI
Feb 1, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The comment suggests to "Increase for less network usage, decrease for more responsive feel" but the relationship is inverted. Increasing tick_update_frequency (e.g., from 15 to 30) means updating LESS frequently (every 30 frames instead of 15), which reduces network usage. Decreasing it (e.g., from 15 to 5) means updating MORE frequently, which increases responsiveness but also network usage. The comment should be: "Increase for less frequent updates (lower network usage), decrease for more frequent updates (more responsive)".
| tick_update_frequency = 15 # Increase for less network usage, decrease for more responsive feel | |
| tick_update_frequency = 15 # Increase for less frequent updates (lower network usage), decrease for more frequent updates (more responsive) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed in ae554b7. Comment now correctly states: "Increase for less frequent updates (lower network usage), decrease for more frequent updates (more responsive)".
|
@copilot address comments |
- Fixed backwards comments about tick_update_frequency in both docs - Added api_client.close() call in quitApplication() for proper cleanup - Documented entity movement visibility tradeoff in both PERFORMANCE.md and OPTIMIZATION_SUMMARY.md - Added comprehensive tests for updateTick optimization (player data extraction from tick response) - Added test for fallback behavior when player data not in tick response Co-authored-by: dmccoystephenson <21204351+dmccoystephenson@users.noreply.github.com>
|
@copilot Create sub PR for this PR for the following: |
I cannot directly create pull requests, but I can help implement the WebSocket integration work on a new branch that you can then use to create a PR. Would you like me to:
Please confirm and I'll proceed with the implementation. |
|
@copilot no, just provide a detailed ticket title/description for the future in a comment |
WebSocket Integration for Real-Time Game State UpdatesPriorityHigh - This would provide an additional 30-50% reduction in network overhead on top of current optimizations SummaryImplement WebSocket-based real-time communication for server-to-client state updates, eliminating the need for periodic tick polling while maintaining REST API for client-initiated actions. BackgroundCurrent implementation uses REST API polling every 15 frames (~4 requests/sec) to fetch game state updates. The server already has full WebSocket support via
Technical ApproachClient-Side Implementation:
Configuration:
Error Handling:
Implementation Tasks
Expected Impact
Testing Strategy
Documentation Updates
Dependencies
Risks & Mitigation
Success Criteria
|
…/roam-prototype into copilot/sub-pr-266 # Conflicts: # server/src/main/java/com/preponderous/roam/persistence/service/PersistenceService.java # server/src/main/java/com/preponderous/roam/service/PlayerService.java # src/roam.py # src/screen/statsScreen.py
|
@copilot fix failing unit test: |
- Added saving of player stats (score, roomsExplored, foodEaten, numberOfDeaths, visitedRooms) in savePlayer method - Added loading of player stats in convertToPlayer method - Added copying of player stats in copyPlayerData method - Fixes failing test PersistenceIntegrationTest.testSaveAndLoadGameState Co-authored-by: dmccoystephenson <21204351+dmccoystephenson@users.noreply.github.com>
Fixed in 18535bf. The test was failing because player stats (score, roomsExplored, foodEaten, numberOfDeaths, visitedRooms) were not being persisted to the database. Root cause: The
All player stats are now correctly persisted and restored. The test now passes with all 4 tests successful. |
💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.