Where to find the code:
- Header:
include/controllers/world/WeatherController.hpp - Implementation:
src/controllers/world/WeatherController.cpp - Tests:
tests/controllers/WeatherControllerTests.cpp
Ownership: GameState owns the controller instance (not a singleton).
WeatherController is a lightweight controller that bridges GameTime weather checks to actual weather changes. It subscribes to WeatherCheckEvent (dispatched by GameTime) and triggers actual weather changes via EventManager::changeWeather(), which then dispatches WeatherEvent for visual effects.
GameTimeManager::checkWeatherUpdate()
→ WeatherCheckEvent (Deferred)
→ WeatherController handles it
→ EventManager::changeWeather() (Deferred)
→ WeatherEvent dispatched
→ ParticleManager handles it → Visual effects rendered
#include "controllers/world/WeatherController.hpp"
#include "managers/GameTimeManager.hpp"
// In GamePlayState.hpp - controller as member
class GamePlayState : public GameState {
private:
WeatherController m_weatherController; // Owned by state
};
// In GamePlayState::enter()
GameTimeManager::Instance().enableAutoWeather(true); // Enable weather checks
m_weatherController.subscribe();
// In GamePlayState::exit()
m_weatherController.unsubscribe();void subscribe();Subscribe to weather check events from GameTime.
Note: Called when a world state enters, NOT in GameEngine::init().
void unsubscribe();Unsubscribe from weather check events.
Note: Called when a world state exits.
WeatherType getCurrentWeather() const;Get the current weather type.
Returns: Current WeatherType enum value (defaults to Clear)
const char* getCurrentWeatherString() const;Get current weather as a string (zero allocation).
Returns: Static string pointer: "Clear", "Cloudy", "Rainy", "Stormy", "Foggy", "Snowy", or "Windy"
bool isSubscribed() const;Check if currently subscribed to weather events.
enum class WeatherType {
Clear, // No weather effects
Cloudy, // Overcast sky
Rainy, // Rain particles
Stormy, // Heavy rain + lightning
Foggy, // Fog overlay
Snowy, // Snow particles
Windy // Wind effects on particles
};// GamePlayState.hpp
#include "controllers/world/WeatherController.hpp"
class GamePlayState : public GameState {
private:
WeatherController m_weatherController; // Owned by state
};
// GamePlayState.cpp
#include "managers/GameTimeManager.hpp"
bool GamePlayState::enter() {
// Enable automatic weather in GameTime
GameTimeManager::Instance().enableAutoWeather(true);
GameTimeManager::Instance().setWeatherCheckInterval(4.0f); // Every 4 game hours
// Subscribe WeatherController to handle weather checks
m_weatherController.subscribe();
return true;
}
void GamePlayState::update(float deltaTime) {
// Display current weather
WeatherType weather = m_weatherController.getCurrentWeather();
const char* weatherStr = m_weatherController.getCurrentWeatherString();
// Use in UI or game logic
if (weather == WeatherType::Rainy || weather == WeatherType::Stormy) {
// Reduce NPC outdoor activity
m_outdoorActivityMultiplier = 0.5f;
}
}
void GamePlayState::exit() {
m_weatherController.unsubscribe();
}When WeatherController calls EventManager::changeWeather(), ParticleManager automatically:
- Receives the
WeatherEvent - Creates appropriate weather particles (rain, snow, etc.)
- Manages particle lifecycle until weather changes
You don't need to manually create weather particles - just use WeatherController.
If you want to override automatic weather:
// Disable auto weather
GameTimeManager::Instance().enableAutoWeather(false);
// Manually trigger weather change
EventManager::Instance().changeWeather(WeatherType::Stormy);- Per-frame cost: Zero (event-driven only)
- Memory: Minimal (handler tokens, current weather state)
- Allocations: Zero per-frame
- Controller Pattern:
docs/controllers/README.md - GameTime:
docs/core/GameTime.md - ParticleManager:
docs/managers/ParticleManager.md - EventManager:
docs/events/EventManager.md