|
| 1 | +# Design Document: RightFence Inventory Integration |
| 2 | + |
| 3 | +## Overview |
| 4 | + |
| 5 | +This design integrates the RightFence item into the existing inventory system by following established patterns used for other inventory items, particularly the recently implemented BackFence, FrontFence, and LeftFence. The implementation involves adding RightFence support to the ItemType enum, Inventory class, network messages, message handlers, InventoryManager, and InventoryRenderer, along with necessary network synchronization for multiplayer support. |
| 6 | + |
| 7 | +This design incorporates lessons learned from previous fence implementations, particularly around task ordering and explicit message handler updates. |
| 8 | + |
| 9 | +## Architecture |
| 10 | + |
| 11 | +The RightFence inventory integration follows the existing layered architecture: |
| 12 | + |
| 13 | +1. **Data Layer**: ItemType enum and Inventory class store RightFence state |
| 14 | +2. **Network Layer**: Inventory update and sync messages include RightFence count |
| 15 | +3. **Message Handler Layer**: GameMessageHandler and ClientConnection process RightFence data |
| 16 | +4. **Management Layer**: InventoryManager handles RightFence collection, removal, and synchronization |
| 17 | +5. **Presentation Layer**: InventoryRenderer displays the RightFence icon and count |
| 18 | + |
| 19 | +The integration is additive and follows the exact patterns established by existing items (Apple, Banana, LeftFence, FrontFence, BackFence, etc.). |
| 20 | + |
| 21 | +## Components and Interfaces |
| 22 | + |
| 23 | +### ItemType Enum Extension |
| 24 | + |
| 25 | +Add `RIGHT_FENCE` to the ItemType enum: |
| 26 | + |
| 27 | +```java |
| 28 | +public enum ItemType { |
| 29 | + // ... existing items ... |
| 30 | + LEFT_FENCE(false, 0, false), |
| 31 | + FRONT_FENCE(false, 0, false), |
| 32 | + BACK_FENCE(false, 0, false), |
| 33 | + RIGHT_FENCE(false, 0, false); // New item |
| 34 | + |
| 35 | + // ... existing methods ... |
| 36 | +} |
| 37 | +``` |
| 38 | + |
| 39 | +### Inventory Class Extension |
| 40 | + |
| 41 | +Add RightFence storage and management methods to the Inventory class: |
| 42 | + |
| 43 | +```java |
| 44 | +public class Inventory { |
| 45 | + // ... existing fields ... |
| 46 | + private int rightFenceCount; |
| 47 | + |
| 48 | + // Constructor initialization |
| 49 | + public Inventory() { |
| 50 | + // ... existing initializations ... |
| 51 | + this.rightFenceCount = 0; |
| 52 | + } |
| 53 | + |
| 54 | + // RightFence methods (following existing pattern) |
| 55 | + public int getRightFenceCount() { return rightFenceCount; } |
| 56 | + public void setRightFenceCount(int count) { this.rightFenceCount = Math.max(0, count); } |
| 57 | + public void addRightFence(int amount) { this.rightFenceCount += amount; } |
| 58 | + public boolean removeRightFence(int amount) { |
| 59 | + if (rightFenceCount >= amount) { |
| 60 | + rightFenceCount -= amount; |
| 61 | + return true; |
| 62 | + } |
| 63 | + return false; |
| 64 | + } |
| 65 | + |
| 66 | + // Update clear() method |
| 67 | + public void clear() { |
| 68 | + // ... existing clears ... |
| 69 | + this.rightFenceCount = 0; |
| 70 | + } |
| 71 | +} |
| 72 | +``` |
| 73 | + |
| 74 | +### Network Message Extension |
| 75 | + |
| 76 | +Update network messages to include RightFence count: |
| 77 | + |
| 78 | +**InventoryUpdateMessage:** |
| 79 | +```java |
| 80 | +public class InventoryUpdateMessage extends NetworkMessage { |
| 81 | + // ... existing fields ... |
| 82 | + public int rightFenceCount; |
| 83 | + |
| 84 | + public InventoryUpdateMessage(int appleCount, int bananaCount, ..., int backFenceCount, int rightFenceCount) { |
| 85 | + super(MessageType.INVENTORY_UPDATE); |
| 86 | + // ... existing assignments ... |
| 87 | + this.rightFenceCount = rightFenceCount; |
| 88 | + } |
| 89 | +} |
| 90 | +``` |
| 91 | + |
| 92 | +**InventorySyncMessage:** |
| 93 | +```java |
| 94 | +public class InventorySyncMessage extends NetworkMessage { |
| 95 | + // ... existing fields ... |
| 96 | + public int rightFenceCount; |
| 97 | + |
| 98 | + public InventorySyncMessage(int appleCount, int bananaCount, ..., int backFenceCount, int rightFenceCount) { |
| 99 | + super(MessageType.INVENTORY_SYNC); |
| 100 | + // ... existing assignments ... |
| 101 | + this.rightFenceCount = rightFenceCount; |
| 102 | + } |
| 103 | +} |
| 104 | +``` |
| 105 | + |
| 106 | +### Message Handler Updates |
| 107 | + |
| 108 | +**GameMessageHandler:** |
| 109 | +```java |
| 110 | +private void handleInventorySyncMessage(InventorySyncMessage msg) { |
| 111 | + inventoryManager.syncFromServer( |
| 112 | + msg.appleCount, |
| 113 | + msg.bananaCount, |
| 114 | + // ... existing parameters ... |
| 115 | + msg.backFenceCount, |
| 116 | + msg.rightFenceCount // New parameter |
| 117 | + ); |
| 118 | +} |
| 119 | +``` |
| 120 | + |
| 121 | +**ClientConnection:** |
| 122 | +```java |
| 123 | +// Update all call sites creating InventoryUpdateMessage |
| 124 | +new InventoryUpdateMessage( |
| 125 | + inventory.getAppleCount(), |
| 126 | + inventory.getBananaCount(), |
| 127 | + // ... existing parameters ... |
| 128 | + inventory.getBackFenceCount(), |
| 129 | + inventory.getRightFenceCount() // New parameter |
| 130 | +); |
| 131 | +``` |
| 132 | + |
| 133 | +### InventoryManager Extension |
| 134 | + |
| 135 | +Add RightFence handling to InventoryManager: |
| 136 | + |
| 137 | +1. **collectItem()**: Add RIGHT_FENCE case to the switch statement |
| 138 | +2. **addItemToInventory()**: Add RIGHT_FENCE case to call `inventory.addRightFence(amount)` |
| 139 | +3. **sendInventoryUpdate()**: Include rightFenceCount in the InventoryUpdateMessage |
| 140 | +4. **syncFromServer()**: Add rightFenceCount parameter and update inventory |
| 141 | +5. **getSelectedItemType()**: Add case 13 returning ItemType.RIGHT_FENCE |
| 142 | +6. **checkAndAutoDeselect()**: Add case 13 checking rightFenceCount |
| 143 | + |
| 144 | +### InventoryRenderer Extension |
| 145 | + |
| 146 | +Add RightFence rendering to InventoryRenderer: |
| 147 | + |
| 148 | +1. **Texture Field**: Add `private Texture rightFenceIcon;` |
| 149 | +2. **PANEL_WIDTH**: Update calculation to accommodate 14 slots instead of 13 |
| 150 | +3. **loadItemIcons()**: Extract RightFence icon from sprite sheet at (298, 192) with size 22x128, scaled to 32x32 |
| 151 | +4. **render()**: Add 14th slot rendering for RightFence after BackFence |
| 152 | +5. **dispose()**: Dispose rightFenceIcon texture |
| 153 | + |
| 154 | +## Data Models |
| 155 | + |
| 156 | +### RightFence Item Properties |
| 157 | + |
| 158 | +- **Type**: RIGHT_FENCE |
| 159 | +- **Restores Health**: false |
| 160 | +- **Health Restore Amount**: 0 |
| 161 | +- **Reduces Hunger**: false |
| 162 | +- **Sprite Coordinates**: (298, 192) with size 22x128 |
| 163 | +- **Inventory Icon Size**: 32x32 (scaled from source) |
| 164 | +- **Inventory Slot Index**: 13 (after BackFence at index 12) |
| 165 | + |
| 166 | +### Inventory Slot Layout |
| 167 | + |
| 168 | +``` |
| 169 | +Slot 0: Apple |
| 170 | +Slot 1: Banana |
| 171 | +Slot 2: BambooSapling |
| 172 | +Slot 3: BambooStack |
| 173 | +Slot 4: TreeSapling |
| 174 | +Slot 5: WoodStack |
| 175 | +Slot 6: Pebble |
| 176 | +Slot 7: PalmFiber |
| 177 | +Slot 8: AppleSapling |
| 178 | +Slot 9: BananaSapling |
| 179 | +Slot 10: LeftFence |
| 180 | +Slot 11: FrontFence |
| 181 | +Slot 12: BackFence |
| 182 | +Slot 13: RightFence (NEW) |
| 183 | +``` |
| 184 | + |
| 185 | +## Correctness Properties |
| 186 | + |
| 187 | +*A property is a characteristic or behavior that should hold true across all valid executions of a system—essentially, a formal statement about what the system should do. Properties serve as the bridge between human-readable specifications and machine-verifiable correctness guarantees.* |
| 188 | + |
| 189 | + |
| 190 | +Based on the acceptance criteria analysis, the following correctness properties must hold: |
| 191 | + |
| 192 | +**Property 1: RightFence collection increases count** |
| 193 | +*For any* initial RightFence count, when a player collects a RightFence item, the resulting count should be exactly one greater than the initial count. |
| 194 | +**Validates: Requirements 1.1** |
| 195 | + |
| 196 | +**Property 2: Displayed count matches inventory count** |
| 197 | +*For any* RightFence count value in the inventory, the rendered UI count should match the inventory's stored count. |
| 198 | +**Validates: Requirements 1.2** |
| 199 | + |
| 200 | +**Property 3: Multiplayer collection triggers sync** |
| 201 | +*For any* RightFence collection event in multiplayer mode with an active server connection, an inventory update message should be sent to the server. |
| 202 | +**Validates: Requirements 2.1** |
| 203 | + |
| 204 | +**Property 4: Server sync updates local count** |
| 205 | +*For any* server sync message containing a RightFence count, after synchronization the local inventory's RightFence count should match the server's value. |
| 206 | +**Validates: Requirements 2.2** |
| 207 | + |
| 208 | +**Property 5: Multiplayer removal triggers sync** |
| 209 | +*For any* RightFence removal event in multiplayer mode with an active server connection, an inventory update message should be sent to the server. |
| 210 | +**Validates: Requirements 2.3** |
| 211 | + |
| 212 | +**Property 6: Slot 13 selection returns RIGHT_FENCE** |
| 213 | +*For any* inventory state where slot 13 is selected, calling getSelectedItemType() should return ItemType.RIGHT_FENCE. |
| 214 | +**Validates: Requirements 3.2** |
| 215 | + |
| 216 | +**Property 7: Zero count triggers auto-deselect** |
| 217 | +*For any* sequence of operations where the RightFence count reaches zero while slot 13 is selected, the slot should be automatically deselected. |
| 218 | +**Validates: Requirements 3.4** |
| 219 | + |
| 220 | +## Error Handling |
| 221 | + |
| 222 | +The RightFence inventory integration follows existing error handling patterns: |
| 223 | + |
| 224 | +1. **Negative Count Prevention**: The `setRightFenceCount()` method uses `Math.max(0, count)` to prevent negative counts |
| 225 | +2. **Insufficient Items**: The `removeRightFence()` method returns false if attempting to remove more items than available |
| 226 | +3. **Null Safety**: All methods check for null inventory references before operations |
| 227 | +4. **Network Disconnection**: Inventory updates are only sent when `gameClient.isConnected()` returns true |
| 228 | + |
| 229 | +## Testing Strategy |
| 230 | + |
| 231 | +### Unit Tests |
| 232 | + |
| 233 | +Unit tests will verify specific behaviors and edge cases: |
| 234 | + |
| 235 | +1. **Zero Count Handling**: Verify that inventory displays 0 when no RightFence items are collected |
| 236 | +2. **Texture Extraction**: Verify that the RightFence icon is extracted from correct sprite sheet coordinates (298, 192) |
| 237 | +3. **Icon Rendering Size**: Verify that the RightFence icon is rendered at 32x32 pixels |
| 238 | +4. **Slot Position**: Verify that RightFence is positioned at slot index 13 |
| 239 | +5. **ItemType Configuration**: Verify that RIGHT_FENCE has restoresHealth=false, healthRestore=0, reducesHunger=false |
| 240 | +6. **Selection Highlight**: Verify that selecting slot 13 renders the golden highlight border |
| 241 | +7. **Deselection**: Verify that deselecting slot 13 removes the highlight |
| 242 | + |
| 243 | +### Property-Based Tests |
| 244 | + |
| 245 | +Property-based tests will verify universal properties across many inputs using a Java property-based testing library (e.g., jqwik or QuickCheck for Java). Each test will run a minimum of 100 iterations. |
| 246 | + |
| 247 | +1. **Property 1 Test**: Generate random initial counts, simulate collection, verify count increases by 1 |
| 248 | +2. **Property 2 Test**: Generate random counts, verify rendered count matches inventory count |
| 249 | +3. **Property 3 Test**: Generate random collection events in multiplayer mode, verify sync messages sent |
| 250 | +4. **Property 4 Test**: Generate random server sync messages, verify local count matches server count |
| 251 | +5. **Property 5 Test**: Generate random removal events in multiplayer mode, verify sync messages sent |
| 252 | +6. **Property 6 Test**: Generate random inventory states with slot 13 selected, verify getSelectedItemType() returns RIGHT_FENCE |
| 253 | +7. **Property 7 Test**: Generate random operation sequences leading to zero count while selected, verify auto-deselect |
| 254 | + |
| 255 | +Each property-based test will be tagged with a comment in the format: |
| 256 | +`// Feature: right-fence-inventory, Property {number}: {property_text}` |
| 257 | + |
| 258 | +### Integration Tests |
| 259 | + |
| 260 | +Integration tests will verify end-to-end workflows: |
| 261 | + |
| 262 | +1. **Collection to Display**: Collect RightFence items and verify they appear in inventory UI |
| 263 | +2. **Multiplayer Synchronization**: Collect RightFence in multiplayer, verify server receives update and other clients sync |
| 264 | +3. **Selection and Usage**: Select RightFence slot, verify targeting system activates (if applicable) |
| 265 | + |
| 266 | +## Implementation Notes |
| 267 | + |
| 268 | +### Sprite Sheet Extraction |
| 269 | + |
| 270 | +The RightFence texture is located at coordinates (298, 192) with size 22x128 in the sprite sheet. The extraction process should: |
| 271 | + |
| 272 | +1. Extract the 22x128 texture from the sprite sheet |
| 273 | +2. Scale to 32x32 for inventory display |
| 274 | +3. Maintain aspect ratio and visual clarity |
| 275 | + |
| 276 | +### Task Ordering (Lessons Learned) |
| 277 | + |
| 278 | +Based on previous fence implementations, the following task order is critical: |
| 279 | + |
| 280 | +1. **Data Model First** (ItemType, Inventory) - Foundation layer |
| 281 | +2. **Network Messages Second** (InventoryUpdateMessage, InventorySyncMessage) - Contract definition |
| 282 | +3. **Message Handlers Third** (GameMessageHandler, ClientConnection) - Message routing |
| 283 | +4. **Business Logic Fourth** (InventoryManager) - Uses all above components |
| 284 | +5. **UI Last** (InventoryRenderer) - Presentation layer |
| 285 | + |
| 286 | +This order prevents compilation errors and ensures each component has its dependencies available. |
| 287 | + |
| 288 | +### Network Message Updates |
| 289 | + |
| 290 | +Both `InventoryUpdateMessage` and `InventorySyncMessage` classes need to be updated to include the `rightFenceCount` field. This requires: |
| 291 | + |
| 292 | +1. Adding the field to the message class |
| 293 | +2. Updating the constructor to accept the new parameter |
| 294 | +3. Updating serialization/deserialization logic |
| 295 | +4. Updating ALL call sites that create these messages (critical!) |
| 296 | + |
| 297 | +### Backward Compatibility |
| 298 | + |
| 299 | +Since this adds a new field to network messages, consider: |
| 300 | + |
| 301 | +1. Version compatibility between clients with and without RightFence support |
| 302 | +2. Default value handling for missing fields in older message formats |
| 303 | +3. Server-side validation of RightFence counts |
| 304 | + |
| 305 | +## Dependencies |
| 306 | + |
| 307 | +- LibGDX graphics library for texture handling |
| 308 | +- Existing inventory system components (Inventory, InventoryManager, InventoryRenderer) |
| 309 | +- Network messaging system (GameClient, InventoryUpdateMessage, InventorySyncMessage) |
| 310 | +- Message handlers (GameMessageHandler, ClientConnection) |
| 311 | +- Sprite sheet asset (sprites/assets.png) |
| 312 | + |
| 313 | +## Performance Considerations |
| 314 | + |
| 315 | +The RightFence integration has minimal performance impact: |
| 316 | + |
| 317 | +1. **Memory**: Adds one integer field per inventory instance (~4 bytes) |
| 318 | +2. **Rendering**: Adds one additional texture and render call per frame (negligible) |
| 319 | +3. **Network**: Adds one integer field to inventory sync messages (~4 bytes per message) |
| 320 | + |
| 321 | +These additions are consistent with existing item patterns and should not cause performance degradation. |
| 322 | + |
| 323 | +## Lessons Learned from Previous Fence Implementations |
| 324 | + |
| 325 | +1. ✅ **Network messages must be updated before InventoryManager** to avoid compilation errors |
| 326 | +2. ✅ **Message handlers need explicit updates** - don't assume they'll be caught implicitly |
| 327 | +3. ✅ **Panel width changes should be grouped with UI rendering** for logical cohesion |
| 328 | +4. ✅ **Test after each major component** to catch integration issues early |
| 329 | +5. ✅ **Follow dependency order strictly**: Data → Network → Handlers → Logic → UI |
0 commit comments