feat(spike): implement save/load hook feasibility#3
Conversation
There was a problem hiding this comment.
Code Review
This pull request introduces the Product Requirements Document and initial feasibility spikes for Claude Kingdoms, featuring Python scripts for save injection and a Java-based observability manager. The review identified critical bugs, including malformed XML in the Maven configuration, an incorrectly formatted ZIP save file, and a character-vs-byte length error in the HTTP server implementation. Further improvements were suggested regarding file encoding consistency, the removal of hardcoded absolute paths for better portability, and alignment with Java naming conventions for boolean getters.
| { | ||
| "version": 1, | ||
| "name": "Spike Test Save", | ||
| "date": "400-01-01", | ||
| "player": 0, | ||
| "civilizations": [ | ||
| { | ||
| "id": 0, | ||
| "name": "Test Civ", | ||
| "player": true, | ||
| "cities": [] | ||
| } | ||
| ], | ||
| "cities": [ | ||
| { | ||
| "id": 0, | ||
| "name": "Capital", | ||
| "civilization": 0, | ||
| "x": 0, | ||
| "y": 0, | ||
| "resources": { | ||
| "food": 100, | ||
| "production": 150, | ||
| "science": 200, | ||
| "gold": 50, | ||
| "culture": 25, | ||
| "faith": 10 | ||
| } | ||
| } | ||
| ], | ||
| "units": [], | ||
| "map": { | ||
| "width": 1, | ||
| "height": 1, | ||
| "tiles": [ | ||
| {"x": 0, "y": 0, "type": "plains", "resources": []} | ||
| ] | ||
| } | ||
| } No newline at end of file |
| <groupId>com.claudekingdoms</groupId> | ||
| <artifactId>observability-spike</artifactId> | ||
| <version>1.0.0-SNAPSHOT</version> | ||
| <name>Observability Hook Feasibility Spike</modelVersion> |
| <version>1.0.0-SNAPSHOT</version> | ||
| <name>Observability Hook Feasibility Spike</modelVersion> | ||
|
|
||
| <parameter= |
|
|
||
| def main(): | ||
| # Create a log directory if it doesn't exist | ||
| log_dir = Path("/mnt/c/Users/caleb/projects/ClaudeKingdoms/spikes/hook_logs") |
There was a problem hiding this comment.
The log directory path is hardcoded to a specific absolute path on your local machine. This makes the script non-portable. Consider using a relative path or making it configurable via an environment variable.
| log_dir = Path("/mnt/c/Users/caleb/projects/ClaudeKingdoms/spikes/hook_logs") | |
| log_dir = Path(__file__).parent.parent / "spikes" / "hook_logs" |
| private void sendResponse(HttpExchange exchange, int statusCode, String response) throws IOException { | ||
| exchange.sendResponseHeaders(statusCode, response.length()); | ||
| try (OutputStream os = exchange.getResponseBody()) { | ||
| os.write(response.getBytes()); | ||
| } | ||
| } |
There was a problem hiding this comment.
response.length() returns the number of characters, but sendResponseHeaders requires the length in bytes. This can cause issues with multi-byte characters (e.g., UTF-8). It's safer to convert the string to bytes first and use the byte array's length.
private void sendResponse(HttpExchange exchange, int statusCode, String response) throws IOException {
byte[] responseBytes = response.getBytes(java.nio.charset.StandardCharsets.UTF_8);
exchange.sendResponseHeaders(statusCode, responseBytes.length);
try (OutputStream os = exchange.getResponseBody()) {
os.write(responseBytes);
}
}| try (FileWriter writer = new FileWriter(saveFile)) { | ||
| writer.write(json); | ||
| } |
There was a problem hiding this comment.
FileWriter uses the default system encoding, which can lead to issues when moving save files between different operating systems. It is better to explicitly specify StandardCharsets.UTF_8.
| try (FileWriter writer = new FileWriter(saveFile)) { | |
| writer.write(json); | |
| } | |
| try (java.io.Writer writer = new java.io.OutputStreamWriter(new java.io.FileOutputStream(saveFile), java.nio.charset.StandardCharsets.UTF_8)) { | |
| writer.write(json); | |
| } |
| */ | ||
| public GameState loadGame(String saveName) throws IOException { | ||
| File saveFile = new File(savesDirectory, saveName + ".json"); | ||
| String json = new String(Files.readAllBytes(Paths.get(saveFile.getAbsolutePath()))); |
There was a problem hiding this comment.
When reading the save file, the default encoding is used. To ensure consistency with the writer, explicitly use StandardCharsets.UTF_8.
| String json = new String(Files.readAllBytes(Paths.get(saveFile.getAbsolutePath()))); | |
| String json = new String(Files.readAllBytes(Paths.get(saveFile.getAbsolutePath())), java.nio.charset.StandardCharsets.UTF_8); |
| public int getMoves() { return moves; } | ||
| public void setMoves(int moves) { this.moves = moves; } | ||
|
|
||
| public boolean isHasActed() { return hasActed; } |
There was a problem hiding this comment.
Implements save/load hook feasibility spike with complete test suite.