Skip to content

Commit a9f4d5d

Browse files
committed
Implemented rain puddles as a concept
1 parent 765ddf8 commit a9f4d5d

27 files changed

+5572
-3
lines changed
Lines changed: 294 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,294 @@
1+
# Design Document: Rain Water Puddles
2+
3+
## Overview
4+
5+
This feature adds visual water puddles that appear on the ground during rain events. Puddles accumulate after 5 seconds of continuous rain and evaporate over 5 seconds after rain stops. The system integrates with the existing `DynamicRainManager` and uses similar rendering patterns to the `RainRenderer` for consistency.
6+
7+
The puddle system follows the same architectural patterns as the existing rain system:
8+
- Object pooling for performance
9+
- Configuration-driven parameters
10+
- Integration with the game's render loop
11+
- Clean separation of concerns (manager, renderer, particle/puddle objects)
12+
13+
## Architecture
14+
15+
The puddle system consists of three main components:
16+
17+
1. **PuddleManager**: Manages puddle lifecycle, timing, and state transitions
18+
2. **PuddleRenderer**: Handles rendering of puddles using ShapeRenderer
19+
3. **WaterPuddle**: Represents individual puddle instances (pooled objects)
20+
4. **PuddleConfig**: Centralized configuration for all puddle parameters
21+
22+
### Component Interaction
23+
24+
```
25+
RainSystem
26+
└─> DynamicRainManager (existing)
27+
└─> provides rain state
28+
29+
PuddleManager
30+
├─> manages puddle lifecycle
31+
├─> tracks accumulation/evaporation timing
32+
└─> PuddleRenderer
33+
└─> renders WaterPuddle instances
34+
```
35+
36+
### Integration Points
37+
38+
- **DynamicRainManager**: Provides rain state (isRaining, duration)
39+
- **RainSystem**: Coordinates updates and rendering
40+
- **ShapeRenderer**: Shared rendering resource
41+
- **OrthographicCamera**: Provides viewport information for puddle placement
42+
43+
## Components and Interfaces
44+
45+
### PuddleManager
46+
47+
**Responsibilities:**
48+
- Track rain duration to determine when to spawn puddles
49+
- Manage puddle accumulation (5-second threshold)
50+
- Manage puddle evaporation (5-second fade-out)
51+
- Coordinate with PuddleRenderer for rendering
52+
- Handle state transitions (no rain → accumulating → active → evaporating → no puddles)
53+
54+
**Key Methods:**
55+
```java
56+
public void update(float deltaTime, boolean isRaining, float rainDuration, OrthographicCamera camera)
57+
public void render(OrthographicCamera camera)
58+
public void dispose()
59+
public PuddleState getCurrentState()
60+
public float getAccumulationProgress() // 0.0 to 1.0
61+
public float getEvaporationProgress() // 0.0 to 1.0
62+
```
63+
64+
**State Machine:**
65+
- `NONE`: No puddles, rain not active
66+
- `ACCUMULATING`: Rain active but < 5 seconds
67+
- `ACTIVE`: Puddles visible, rain active
68+
- `EVAPORATING`: Rain stopped, puddles fading
69+
70+
### PuddleRenderer
71+
72+
**Responsibilities:**
73+
- Maintain pool of WaterPuddle objects
74+
- Spawn puddles within camera viewport
75+
- Update puddle alpha during evaporation
76+
- Render puddles using ShapeRenderer
77+
- Manage puddle density based on rain intensity
78+
79+
**Key Methods:**
80+
```java
81+
public void initialize()
82+
public void spawnPuddles(OrthographicCamera camera, int count)
83+
public void updatePuddles(float deltaTime, float alphaMultiplier)
84+
public void render(OrthographicCamera camera)
85+
public void clearAllPuddles()
86+
public void dispose()
87+
public int getActivePuddleCount()
88+
```
89+
90+
### WaterPuddle
91+
92+
**Responsibilities:**
93+
- Store puddle position, size, and visual properties
94+
- Support object pooling (reset/reuse)
95+
- Track active state
96+
97+
**Properties:**
98+
```java
99+
private float x, y // Position
100+
private float width, height // Size (ellipse dimensions)
101+
private float baseAlpha // Base transparency
102+
private float rotation // Slight rotation for variety
103+
private boolean active // Pool management
104+
```
105+
106+
**Key Methods:**
107+
```java
108+
public void reset(float x, float y, float width, float height, float rotation)
109+
public void setActive(boolean active)
110+
public boolean isActive()
111+
public boolean isInViewport(OrthographicCamera camera)
112+
```
113+
114+
### PuddleConfig
115+
116+
**Configuration Parameters:**
117+
```java
118+
// Timing
119+
public static final float ACCUMULATION_THRESHOLD = 5.0f; // Seconds before puddles appear
120+
public static final float EVAPORATION_DURATION = 5.0f; // Seconds to fade out
121+
122+
// Density
123+
public static final int MAX_PUDDLES = 30; // Maximum puddles on screen
124+
public static final int MIN_PUDDLES = 15; // Minimum puddles at low intensity
125+
126+
// Visual Properties
127+
public static final float MIN_PUDDLE_WIDTH = 20.0f; // Pixels
128+
public static final float MAX_PUDDLE_WIDTH = 50.0f; // Pixels
129+
public static final float MIN_PUDDLE_HEIGHT = 15.0f; // Pixels
130+
public static final float MAX_PUDDLE_HEIGHT = 35.0f; // Pixels
131+
public static final float PUDDLE_ASPECT_RATIO = 1.5f; // Width/height ratio
132+
133+
// Color (blue-gray water)
134+
public static final float PUDDLE_COLOR_RED = 0.4f;
135+
public static final float PUDDLE_COLOR_GREEN = 0.5f;
136+
public static final float PUDDLE_COLOR_BLUE = 0.7f;
137+
public static final float PUDDLE_BASE_ALPHA = 0.4f; // Base transparency
138+
public static final float PUDDLE_MAX_ALPHA = 0.6f; // Maximum transparency
139+
140+
// Spacing
141+
public static final float MIN_PUDDLE_SPACING = 80.0f; // Minimum distance between puddles
142+
```
143+
144+
## Data Models
145+
146+
### PuddleState Enum
147+
```java
148+
public enum PuddleState {
149+
NONE, // No puddles, no rain
150+
ACCUMULATING, // Rain active, waiting for threshold
151+
ACTIVE, // Puddles visible, rain active
152+
EVAPORATING // Rain stopped, puddles fading
153+
}
154+
```
155+
156+
### WaterPuddle Class
157+
```java
158+
public class WaterPuddle {
159+
private float x;
160+
private float y;
161+
private float width;
162+
private float height;
163+
private float baseAlpha;
164+
private float rotation;
165+
private boolean active;
166+
167+
// Pooling and rendering methods
168+
}
169+
```
170+
171+
## Correctness Properties
172+
173+
*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.*
174+
175+
### Property 1: Accumulation threshold timing
176+
*For any* rain event, puddles should only become visible after rain has been continuously active for at least 5 seconds.
177+
**Validates: Requirements 1.1**
178+
179+
### Property 2: Puddle stability during rain
180+
*For any* active rain period after accumulation, the set of puddle positions should remain stable (puddles don't randomly disappear or teleport).
181+
**Validates: Requirements 1.2**
182+
183+
### Property 3: Intensity affects visibility
184+
*For any* two rain intensity values A and B where A > B, the puddle visibility (alpha or count) at intensity A should be greater than or equal to that at intensity B.
185+
**Validates: Requirements 1.3**
186+
187+
### Property 4: Viewport containment
188+
*For any* camera position, all rendered puddles should have positions within the camera's viewport bounds.
189+
**Validates: Requirements 1.4**
190+
191+
### Property 5: Evaporation timing
192+
*For any* rain stop event, puddles should take approximately 5 seconds (±0.5s) to completely fade out.
193+
**Validates: Requirements 2.1**
194+
195+
### Property 6: Monotonic alpha decrease
196+
*For any* evaporation sequence, puddle alpha values sampled at times t1 < t2 < t3 should satisfy alpha(t1) ≥ alpha(t2) ≥ alpha(t3).
197+
**Validates: Requirements 2.2**
198+
199+
### Property 7: Complete cleanup after evaporation
200+
*For any* evaporation cycle, after the evaporation duration completes, the active puddle count should be zero.
201+
**Validates: Requirements 2.3**
202+
203+
### Property 8: Puddle count correlates with intensity
204+
*For any* stable rain intensity value, the active puddle count should remain within a consistent range over time.
205+
**Validates: Requirements 3.3**
206+
207+
### Property 9: Camera movement updates puddles
208+
*For any* camera movement, after the update cycle, all visible puddles should be within the new viewport bounds.
209+
**Validates: Requirements 3.4**
210+
211+
### Property 10: Configuration affects new puddles
212+
*For any* configuration change to puddle size, newly spawned puddles should reflect the new size values.
213+
**Validates: Requirements 5.2**
214+
215+
## Error Handling
216+
217+
### Invalid State Transitions
218+
- If rain stops during accumulation (before 5 seconds), transition directly to NONE state without spawning puddles
219+
- If rain restarts during evaporation, transition back to ACTIVE state and restore full alpha
220+
221+
### Resource Exhaustion
222+
- If puddle pool is exhausted, log warning but continue operation
223+
- Implement pool size monitoring to detect if MAX_PUDDLES is too low
224+
225+
### Camera Edge Cases
226+
- Handle camera zoom changes by recalculating viewport bounds
227+
- Handle very small viewports (< 100px) by reducing puddle count proportionally
228+
229+
### Performance Degradation
230+
- If frame rate drops below threshold, reduce MAX_PUDDLES dynamically
231+
- Provide configuration option to disable puddles entirely
232+
233+
## Testing Strategy
234+
235+
### Unit Testing
236+
The unit tests will verify specific examples and edge cases:
237+
238+
- **State transitions**: Test transitions between NONE → ACCUMULATING → ACTIVE → EVAPORATING
239+
- **Edge case**: Rain stops before 5-second threshold (no puddles spawn)
240+
- **Edge case**: Rain restarts during evaporation (puddles restore)
241+
- **Configuration loading**: Verify PuddleConfig values are accessible
242+
- **Resource cleanup**: Verify dispose() clears all puddles
243+
244+
### Property-Based Testing
245+
Property-based tests will verify universal properties across many random inputs using **QuickCheck for Java** (or similar library like **jqwik**). Each test will run a minimum of 100 iterations.
246+
247+
Each property-based test will be tagged with a comment explicitly referencing the correctness property:
248+
- Format: `// Feature: rain-water-puddles, Property {number}: {property_text}`
249+
250+
Property tests to implement:
251+
1. **Accumulation threshold timing** - Generate random rain durations, verify puddles only appear after 5s
252+
2. **Puddle stability** - Track puddle positions over time during rain, verify no unexpected changes
253+
3. **Intensity affects visibility** - Generate random intensity pairs, verify monotonic relationship
254+
4. **Viewport containment** - Generate random camera positions, verify all puddles in bounds
255+
5. **Evaporation timing** - Measure actual evaporation duration across random scenarios
256+
6. **Monotonic alpha decrease** - Sample alpha at multiple times, verify decreasing sequence
257+
7. **Complete cleanup** - Verify zero active puddles after evaporation completes
258+
8. **Puddle count stability** - Verify consistent count for stable intensity over time
259+
9. **Camera movement** - Generate random camera movements, verify puddle updates
260+
10. **Configuration effects** - Change config values, verify new puddles use new values
261+
262+
### Integration Testing
263+
- Test puddle system with actual DynamicRainManager
264+
- Verify rendering order (puddles above ground, below player)
265+
- Test performance with MAX_PUDDLES active
266+
- Verify multiplayer synchronization (if needed)
267+
268+
## Implementation Notes
269+
270+
### Rendering Order
271+
Puddles should be rendered in this sequence within the game loop:
272+
1. Ground/terrain rendering
273+
2. **Puddle rendering** ← Insert here
274+
3. Player and object rendering
275+
4. UI rendering
276+
277+
### Performance Considerations
278+
- Use object pooling (similar to RainParticle)
279+
- Limit puddle count based on viewport size
280+
- Consider spatial hashing if puddle count increases significantly
281+
- Render puddles as simple ellipses (ShapeRenderer.ellipse) for performance
282+
283+
### Visual Design
284+
- Puddles should be subtle (low alpha) to avoid visual clutter
285+
- Use slight rotation variation for natural appearance
286+
- Consider adding a darker outline for better visibility
287+
- Puddles should be elliptical (wider than tall) for realistic water pooling
288+
289+
### Future Enhancements
290+
- Add ripple effects when rain hits puddles
291+
- Implement puddle merging (nearby puddles combine)
292+
- Add reflection effects for nearby objects
293+
- Support different ground types (puddles only on certain terrain)
294+
- Add sound effects (splashing when puddles form)
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
# Requirements Document
2+
3+
## Introduction
4+
5+
This feature adds visual water puddles that appear on the ground during rain events and persist briefly after rain stops. Water puddles enhance the visual feedback of the rain system by showing accumulated water on the ground, creating a more immersive weather experience. The puddles will appear after rain has been falling for 5 seconds and will disappear approximately 5 seconds after the rain stops.
6+
7+
## Glossary
8+
9+
- **Rain System**: The existing weather system that manages rain zones, particles, and rendering
10+
- **Water Puddle**: A visual ground effect representing accumulated rainwater
11+
- **Puddle Manager**: The component responsible for creating, updating, and removing water puddles
12+
- **Rain Intensity**: A value from 0.0 to 1.0 representing how heavily it is raining
13+
- **Accumulation Threshold**: The minimum duration (5 seconds) rain must fall before puddles appear
14+
- **Evaporation Duration**: The time period (5 seconds) after rain stops during which puddles fade away
15+
- **DynamicRainManager**: The existing component that manages rain events and timing
16+
17+
## Requirements
18+
19+
### Requirement 1
20+
21+
**User Story:** As a player, I want to see water puddles form on the ground during rain, so that the weather feels more realistic and immersive.
22+
23+
#### Acceptance Criteria
24+
25+
1. WHEN rain has been falling for 5 seconds, THEN the Puddle Manager SHALL spawn water puddles on visible ground tiles
26+
2. WHILE rain continues falling, THE Puddle Manager SHALL maintain visible puddles at consistent locations
27+
3. WHEN rain intensity increases, THEN the Puddle Manager SHALL increase puddle visibility or density
28+
4. WHEN the player moves through the world, THEN the Puddle Manager SHALL render puddles within the camera viewport
29+
5. WHILE puddles are visible, THE Puddle Manager SHALL render them below the player and objects but above the ground texture
30+
31+
### Requirement 2
32+
33+
**User Story:** As a player, I want puddles to disappear gradually after rain stops, so that the transition feels natural rather than abrupt.
34+
35+
#### Acceptance Criteria
36+
37+
1. WHEN rain stops, THEN the Puddle Manager SHALL begin fading out existing puddles over 5 seconds
38+
2. WHILE puddles are evaporating, THE Puddle Manager SHALL gradually reduce puddle alpha transparency
39+
3. WHEN the evaporation duration completes, THEN the Puddle Manager SHALL remove all puddle instances from memory
40+
4. WHEN new rain starts during evaporation, THEN the Puddle Manager SHALL restore puddles to full visibility
41+
42+
### Requirement 3
43+
44+
**User Story:** As a player, I want puddles to appear in appropriate locations, so that they look natural and believable.
45+
46+
#### Acceptance Criteria
47+
48+
1. WHEN spawning puddles, THE Puddle Manager SHALL place them on ground tiles within the visible camera area
49+
2. WHEN determining puddle locations, THE Puddle Manager SHALL use randomization to create natural distribution
50+
3. WHEN rain is active, THE Puddle Manager SHALL maintain a consistent number of visible puddles based on rain intensity
51+
4. WHEN the camera moves, THE Puddle Manager SHALL update puddle positions to remain within viewport bounds
52+
53+
### Requirement 4
54+
55+
**User Story:** As a developer, I want the puddle system to integrate cleanly with the existing rain system, so that it is maintainable and performant.
56+
57+
#### Acceptance Criteria
58+
59+
1. WHEN the Rain System updates, THE Puddle Manager SHALL receive rain state information from DynamicRainManager
60+
2. WHEN rendering the game world, THE Puddle Manager SHALL use the existing ShapeRenderer or SpriteBatch for drawing
61+
3. WHEN the game disposes resources, THE Puddle Manager SHALL clean up all puddle-related resources
62+
4. WHEN rain intensity is zero, THE Puddle Manager SHALL not create new puddles
63+
5. WHEN the puddle system operates, THE system SHALL maintain frame rates above 30 FPS on target hardware
64+
65+
### Requirement 5
66+
67+
**User Story:** As a developer, I want puddle appearance to be configurable, so that I can tune the visual effect without code changes.
68+
69+
#### Acceptance Criteria
70+
71+
1. WHEN initializing the puddle system, THE system SHALL load configuration values for puddle size, color, and density
72+
2. WHEN configuration values change, THE Puddle Manager SHALL apply new values to newly created puddles
73+
3. WHEN defining puddle properties, THE configuration SHALL include accumulation threshold and evaporation duration
74+
4. WHEN defining visual properties, THE configuration SHALL include puddle color, alpha range, and size range

0 commit comments

Comments
 (0)