Deterministic weather generation for games and simulations
Project description
weatherz
A deterministic weather generation library for games and simulations. Given a single time input (and optional location/climate parameters), it returns a complete, reproducible weather report.
Features
- Fully deterministic: Same input always yields the same output.
- Flexible Time: Supports game minutes, real-time, or current UTC.
- Geographic Context: Optional latitude, longitude, and elevation for fine-tuning.
- Climate Profiles: Built-in Köppen climate profiles (extensible).
- Comprehensive Data:
- Temperature, pressure, humidity, dew point, wind (speed/direction/cardinal).
- Precipitation probability, cloud cover, instability (CAPE-like).
- 20+ weather conditions (clear, rain, snow, thunderstorm, blizzard, etc.).
- Special atmospheric phenomena: aurora, rainbow, sun dog, halo.
- Moon phase (with year drift) and seasonal events (equinoxes/solstices).
- Flavor text and ASCII art for every condition.
- Customizable: All disasters can be enabled/disabled per profile.
- Per-trend memory isolation – pass a
trend_idto keep smoothing separate for concurrent use. - WeatherArchive – persistent SQLite storage of sparse checkpoints, ensuring smooth weather even when jumping to arbitrary times.
- Fast-forward generation – leap months or years in milliseconds instead of computing every intermediate minute.
Installation
Copy weather.py into your project and import:
from weather import weather, WeatherData, list_koppen_codes, WeatherArchive
No external dependencies — only the Python standard library.
Usage
Basic – current weather at default location
w = weather()
print(f"{w.condition} at {w.temperature}°C")
print(w.ascii_art)
print(w.flavor)
Advanced Time & Location
# Specify game minutes
w = weather(game_minutes=123456)
# Use real time (UTC)
from datetime import datetime
w = weather(real_time=datetime(2025, 6, 1, 12, 0))
# Scale time (e.g., 1 real minute = 12 game minutes)
w = weather(real_time=datetime.now(), real_time_scale=12)
# Set location (latitude affects aurora; elevation applies lapse rate)
w = weather(latitude=60.0, elevation=200, koppen="Dfd")
# Isolate smoothing per trend
w1 = weather(game_minutes=1000, trend_id="siberia")
w2 = weather(game_minutes=1000, trend_id="desert") # separate memory
WeatherArchive – Persistent, Smooth Trends
WeatherArchive stores weather checkpoints in a local SQLite database. When you request a time, it generates forward from the nearest checkpoint, ensuring smooth transitions without storing every minute.
archive = WeatherArchive("my_weather.db")
# Add a trend (location + climate)
trend_id = archive.add_trend(
name="Siberian Outpost",
latitude=60.0,
longitude=120.0,
elevation=200.0,
koppen="Dfd"
)
# Get weather at game minute 5000
w = archive.get_weather(trend_id, 5000)
# Later, get minute 6000 (resumes from checkpoint at 5000)
w2 = archive.get_weather(trend_id, 6000)
# Read-only mode (no new checkpoints saved)
w3 = archive.get_weather(trend_id, 7000, read_only=True)
Thread Safety: WeatherArchive is thread-safe. Concurrent requests for different trends run in parallel; requests for the same trend are serialized to preserve smoothing continuity.
Fast-Forward Generation
By default, get_weather uses fast-forward mode when the gap between the nearest checkpoint and the target is large (≥ one game-day / 1440 minutes). Instead of computing every intermediate minute, it leaps forward in chunks and back-fills the smoothing memory so weather at the boundary is still plausible.
# Default: fast-forward automatically kicks in for large gaps
w = archive.get_weather(trend_id, 525600) # jump a whole game-year instantly
# Exact mode: minute-by-minute, fully faithful sequence (slower)
w = archive.get_weather(trend_id, 525600, exact=True)
# Custom step: control the leap size (in game minutes)
w = archive.get_weather(trend_id, 525600, fast_forward_step=720) # leap every 12 hours
| Parameter | Type | Default | Description |
|---|---|---|---|
exact |
bool | False |
Force minute-by-minute generation (full accuracy, slower) |
fast_forward_step |
int or None | checkpoint_interval (1440) |
Leap size in game minutes when fast-forwarding |
Trade-off: Fast-forward skips subtle minute-to-minute variations inside each leap, so the weather at the target may differ slightly from a full exact run. For gameplay this is imperceptible; use exact=True only when you need a perfectly reproducible sequence (e.g. replay systems).
WeatherData Fields
| Field | Type | Description |
|---|---|---|
game_minutes |
int | Internal game minute count |
datetime_str |
str | Formatted "Year X, Day Y, HH:MM" |
temperature |
float | Air temperature (°C) |
feels_like |
float | Apparent temperature (°C) |
pressure |
float | Atmospheric pressure (hPa) |
humidity |
float | Relative humidity (%) |
dew_point |
float | Dew point (°C) |
wind_speed |
float | Wind speed (m/s) |
wind_direction |
float | Wind direction (degrees) |
wind_cardinal |
str | Cardinal direction (N, NNE, etc.) |
condition |
str | Weather condition (e.g., "light rain") |
cloud_cover |
int | Cloud cover (%) |
precipitation_prob |
float | Precipitation probability (%) |
instability |
float | CAPE-like instability (J/kg) |
moon_phase |
str | Moon phase name |
moon_emoji |
str | Moon phase emoji |
season_event |
str/None | Solstice/equinox if within ±2 days |
flavor |
str | Descriptive flavor text |
ascii_art |
str | ASCII art representing the condition |
Update Logs
0.0.1
- Added
trend_idparameter toweather()for isolated smoothing memory per concurrent caller. - Added
WeatherArchiveclass for persistent, checkpoint-based storage. - Thread-safe archive with per-trend locks.
- Added fast-forward generation to
WeatherArchive.get_weather— large time jumps now leap in day-sized chunks instead of computing every minute, with smoothing memory back-filled to prevent jarring transitions. Useexact=Trueto restore the old minute-by-minute behaviour.
0.0.1dev1
- Bro, this is 0.0.1. Why you even looking here?
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file weatherz-0.0.1.dev2.tar.gz.
File metadata
- Download URL: weatherz-0.0.1.dev2.tar.gz
- Upload date:
- Size: 22.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
55166b1c4f2b995c7fb4f7b2f37ad662c257c0936f81a977c6e7286c444b66b4
|
|
| MD5 |
e9693307326843fbe90269f39d9781eb
|
|
| BLAKE2b-256 |
0f7b0a036e9ed5598e9dee4f8b7da3f6de332600a4be14787e6b82c548ea3a55
|
File details
Details for the file weatherz-0.0.1.dev2-py3-none-any.whl.
File metadata
- Download URL: weatherz-0.0.1.dev2-py3-none-any.whl
- Upload date:
- Size: 20.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ac26f484a53524c87f2e30ada9ef9d218e72b973371530f7a81df93475cc67a1
|
|
| MD5 |
16e31b5237a4ddd81d14c9cb7062a5c6
|
|
| BLAKE2b-256 |
bd8a1857e77e31803c3f70dfd49d81f74ee2153ffff96fa91e58d0e329c0c085
|