In Bordure, a race’s weather used to be a constant: a wind speed, a direction, “it’s raining” or “it isn’t”, fixed at the start. It is now a whole day: a timeline that the engine reads tick by tick, drawn from a climate that depends on the place and the month, and announced to the player in an hour-by-hour forecast. Every team gets the same forecast, and it is wrong the way a real forecast is wrong.
This post follows the weather in the order it is made: why it matters, how the engine reads it, where the days come from, how the forecast is built, what the director does with it in time trials and then in road races, and what we measured. The race itself is in the post on the race engine, the season programme in the post on season planning.
real-2026, grouped into six climate regions.Why the weather has to move
The trigger was a time trial. When 176 riders start 60 seconds apart, the first and the last ride about three hours apart. With frozen weather the start order means nothing: everyone rides under the same sky. The work also fixed an older flaw: every race drew a spring climate, July included, and 30% of flat stages started with wind of 5 m/s or more.
Before touching the engine, we measured what a gust is worth, with a 72 kg specialist riding alone on the flat.
| Course | 10 km | 30 km | 45 km |
|---|---|---|---|
| Out and back, 4 m/s wind along the axis | + 5 s | + 13 s | + 19 s |
| Out and back, 8 m/s wind along the axis | + 17 s | + 49 s | + 74 s |
| Straight line, 2 m/s headwind | + 31 s | + 95 s | + 142 s |
| Straight line, 4 m/s headwind | + 64 s | + 196 s | + 294 s |
| Straight line, 8 m/s crosswind | 0 | 0 | 0 |
| Rain, on the flat | 0 | 0 | 0 |
Three lessons: a headwind is enough to give the start order a meaning; a crosswind costs a lone rider nothing (it only makes echelons, in a bunch); rain costs nothing on the flat, it only slows descents.
The consequence is clear. On a straight road, a few extra metres per second cost minutes, and that is what makes starting early or late interesting. On an out-and-back, the wind cancels out and the effect is small. Rain will matter more once wet corners enter the engine (a separate ticket, right after this one).
A day inside the engine
The engine now accepts a timeline instead of a single weather: increasing points, the first at time 0, at most 64, each giving the wind and the state of the road at a race hour. On each tick the engine sets the conditions of the moment, and everything else reads them as before: aerodynamics, the descent speed cap, incidents, echelons and their placement draw.
The numbers are made up for the diagram. The rules are the engine’s.
How conditions are read between two points
The wind picks up or drops
Speed is interpolated linearly between two points. Outside the bounds, conditions are those of the first or last point.
The wind backs or veers
Direction is interpolated along the shortest arc: from 350° to 10°, the wind passes through 0° and does not swing all the way round.
The road gets wet all at once
The state of the road changes in steps: it takes the value of the last point passed. A road is not “a bit wet”.
One sky over the whole course
At a given hour the weather is the same everywhere. In a time trial, a late starter therefore rides under the later sky.
Constant weather changes nothing. A race with constant weather, or with a one-point timeline, stays byte-identical, and the engine’s test references did not move. We wanted to compare, seed by seed, the race before and the race after: that is what let us measure the evolution alone before touching the climate.
The echelon AI now reads the conditions of the moment rather than those at the start. A crosswind that picks up in the second hour only splits the bunch then, and the AI only reacts then. Once the wind drops to zero, it forgets the placement drawn in the previous echelon: without that, the placement from a first gust would have been reused for the next. Tests cover each case, including a wind that picks up during a time trial (two identical riders starting two hours apart: 739.6 s against 897.2 s, what the physics gives) and resuming a saved race in the middle of a time trial.
Where the days come from
The engine reads a day, but someone has to draw it. So that Flanders in March does not feel like Andalusia in August, we started from real data: the hourly ERA5 reanalysis from Copernicus, served by the Open-Meteo archive API. The game is not commercial, which allows this source. Only statistics go into the repository; the raw data stays outside, like the GPX traces.
Each race day of real-2026 has a location: the first point of its route where we had it (153 cases), otherwise the geocoded start town (380 cases), and 64 locations corrected by hand with a written reason for each. That makes 596 locations, which we grouped into six regions.
| Region | Locations | Median wind | Wet road |
|---|---|---|---|
| Western Europe | 166 | 3.6 m/s | 21% |
| Central Europe | 164 | 2.0 m/s | 21% |
| Mediterranean | 181 | 2.7 m/s | 13% |
| Desert | 20 | 2.9 m/s | 3% |
| Tropics and Asia | 50 | 2.1 m/s | 22% |
| Southern Hemisphere | 15 | 3.8 m/s | 10% |
Only six regions is the price of simplicity: Central Europe mixes the Alps, very calm (1.4 to 1.6 m/s), with the eastern plain, windier (3.0 to 3.6 m/s). A road counts as wet at hour h if at least 0.2 mm of rain fell in the hour ending at h or in the one before.
A climate that sets the tendency, not the day
One instruction framed the whole calibration: the weather can stay approximate to reality, but the game must stay alive, and the weather must not be the same every time. Region and month therefore shift the averages (more wind in March on the Flemish coast, less rain in August in Spain), but the spread from one day to the next stays wide. We set variety floors: even in the calmest region, at least 5% of starts on a wet road (2% in the desert, the only truly dry climate), and a share of days at 5.5 m/s or more. Over ten seasons of the same race you will see calm days, windy days and, almost everywhere, wet days.
Once the start is drawn, the day evolves in 15-minute steps. The wind follows a random walk that returns to its mean, around a daily cycle: it picks up in the early afternoon. Direction moves more widely when the wind is light. The road follows a two-state chain whose transitions depend on local time, and rain peaks between 14:00 and 18:00 in every region. A frontal passage, which turns the wind by 45 to 90° and brings rain, stays rare (0 to 2% of days in the data): we keep a few for variety.
A forecast gives wind at 10 m, and that is what the draw keeps. Wind at rider height is about 0.60 to 0.67 of that in open country, and 0.50 to 0.59 with hedges. The engine already multiplies the race wind by each section’s exposure (0.5 by default): that does the conversion. We later checked on real time trials that there was no reason to change it (section 06).
The forecast, which can be wrong
The player never sees the real day. They see a forecast published at the first start: for each race hour, the wind speed (median and a 10% to 90% range), its direction and the chance that the road is wet. Every team receives the same one (pillar 3), and the real timeline appears in no data contract, on no screen and in nothing the AI reads (pillar 4): a test checks it.
For a forecast to be right without knowing the future, we build it as an ensemble. The game draws a situation of the day, then the real day and 100 possible days around it, independent of one another. The gap to the situation of the day grows with lead time; it is zero at the start, since you can see the sky. For each hour the forecast gives the share of possible days where the road is wet, rounded to 5%. Since the real day is one more draw from the same law, when the forecast says 30%, the road is wet about 30% of the time. Decisions taken on the forecast are good on average, never certain.
20 members, then 50: too few
A day’s rain is most often certain one way or the other, and a share of k members out of 20 reads towards the extremes. With 50 members, 30 to 40% announced gave 26.7% observed.
100 members, rounded to 5%
Each 10% band is within about 3 points of the observed frequency, over 20,000 drawn days (10 bands out of 10). Cost: about 1 ms per day.
Tuning sharpness on real forecasts
A forecast that is too good is a false forecast. We compared the ECMWF model’s 06:00 and 12:00 UTC runs with ERA5 over 460 race days of 2026 (11,528 hours). The result: wind is forecast to within 0.9 to 1.0 m/s, with no measurable growth in the error before 12 hours. For rain, when the model clearly announces water, it rains 55% of the time; when it announces dry, 7%.
We tuned the predictable share of the forecast on these values: 0.35 for wind and its direction, 0.40 for rain. The announced wind then differs from the real wind by 0.72, 0.97 and 1.11 m/s at + 2, + 4 and + 6 hours. With a predictable share of 0.75, the forecast gave rain in 82% of the hours announced at 50% or more: far sharper than a real forecast. At 0.40 it gives 75%, still a little sharper than the real model (55%), without losing its reliability. We kept it there.
The forecast is not updated during the race. An hourly “race radio” weather report, with its age, is an idea for later.
Time trials: choosing your slot
This is where the weather gets its meaning. Before a time trial where slots are a choice (a prologue, the opening time trial of a stage race, a one-day race), the screen shows what each slot should cost or gain according to the forecast, with its range, the published start of the other teams’ favourites and the order the staff proposes. The director can keep the proposal, go back to the public order, or build their own. Their order is validated as before: an exact permutation of their starters.
- For each slot, the staff estimates the time lost or gained by a reference rider, the same for every team, under each of the forecast’s 100 days. It takes a mean cost and a range from them.
- It first places the leader from its plan, then its all-out riders by known time-trial aptitude, in the team’s slots with the lowest expected cost.
- If the expected gap between its slots is under 5 seconds, it keeps the public order: it isn’t worth the trouble.
- Rival teams apply this same function. For the player’s team, it only produces the proposal.
The rivals’ rule does not read the other teams’ order. Publishing their order at the briefing therefore gives nobody an advantage: the player sees it before choosing theirs, as a real sporting director would on the start list.
When the order is imposed (a stage that follows the reverse of the general classification, a team time trial), nothing changes: the luck of the weather falls on whoever it falls on, as in real life, and the briefing shows it. The calculation lives in the engine package, not in the screen, which only displays it.
Road races: echelons, rain, feed
In road races, the effects go through mechanisms that already existed. A crosswind above 3 m/s makes echelons. Rain lowers the descent speed cap by 15%, doubles crashes and multiplies punctures by one and a half. The AI changes in only one place: it reads the conditions of the moment.
The briefing adds a staff reading: the exposed sections of the route where an echelon is possible, with a chance expressed as “7 days out of 10” (the share of the forecast’s 100 days where the crosswind exceeds the threshold, for a head of the race at 42 km/h) rather than an adjective. Neighbouring sections are merged at 5 km, with a minimum length of 3 km: without that, a windy day counted up to 34 sections, against at most 9 now. A wet road is announced for the finale only if it lasts to the finish: a morning shower does not appear. In a time trial, a lone rider makes no echelon, and the reading is absent.
During the race
The bar shows the conditions of the moment, with their age (“seen · km” in a road race, “seen · time” in a time trial).
The feed tells the story
A line when rain arrives or stops, when the wind picks up by 2 m/s, when it turns by 45° or more above 3 m/s. Nothing with constant weather.
Speed changes nothing
These announcements are presentation: they create no engine event and change none (pillar 6). They exist in French and in English.
Collapsible panels
Hourly forecast, exposed sections, team plan, opponents: every briefing panel folds away, to keep the screen readable.
What the measurements said
No engine constant changed during the recalibration: the measurements confirmed the settings, or explained their gaps. Here is what they showed, in the order they came in.
Real wind does not explain how slow our long time trials are
Our long flat time trials are simulated 3 to 5% too slow. We hoped the real wind of those days would explain the gap. We pulled the weather of 15 real time trials, at the start time and at three points of their route, from the 0.8 m/s of the UAE Tour (which picks up to 4.3 m/s in three hours) to the 8.9 m/s of the Tour Down Under prologue, with 7.5 m/s due west at Valencia. Then we replayed the bench.
| Measure | No wind | With real wind |
|---|---|---|
| Winner’s bias | − 0.2% | − 0.2% |
| Mean absolute gap | 3.2% | 3.1% |
| Rank correlation (ρ) | — | 0.56 |
| Vuelta, stage 18 (the closest) | − 5.3% | − 3.6% |
The default wind exposure does not change either: tried at 0.35 and at 0.65 instead of 0.5, it gives the same bias. The cause lies elsewhere, and the hunt is still open.
Start order matters, about as much as in reality
Over 600 time-trial days of real-2026, we measured the weather gap between a team’s best and worst slot, for the reference rider. Then we compared it with the same measurement on the real weather (ERA5) of the same places and dates, over the years extracted.
The same tendency, a little more gap in the game, because of the wind’s quarter-hour walk. Last slot against first: from − 19 to + 17 s in the game, from − 19 to + 15 s in reality (10th and 90th percentiles).
The staff’s rule is good on average, never certain
Races hardly drift
In a grand tour, riders eliminated outside the time limit average 18.9 with the old weather, 18.3 with an evolving day and 18.2 with the climate. Mountain breaks of more than ten minutes go from 95 to 104, then 96. The five career seasons of the reference run pass. Nearly one race in two sees its weather change, without the averages moving.
One gap remains, and the weather is not its cause: in the mountains and on cobbles, favourites win 85% and 87% of the lab’s races, above the 80% target. With the old weather it was 83% and 85%. The evolving day adds 0.6 to 2.6 points, within the noise. The gap comes from the content’s hierarchy, where a clear number one often wins. We raised the ceiling to 85% for those two terrains.
What is not right yet
- Rain costs nothing on the flat. It only slows descents and raises crashes. Wet corners come with the next ticket, and a slot’s cost ignores them until then.
- No local showers. At a given hour the weather is the same over the whole course. No gusts, heat or fog.
- The forecast does not move during the race, and each stage of a stage race draws its own day, with no memory of the day before.
- The AI reacts to wind once it blows. It does not position itself before an announced exposed section, and has no wet-descent caution order.
- A slot’s cost ignores the value of starting late. Seeing the sky before the others has an information value that neither the staff’s rule nor the screen counts.
- The echelon reading assumes a head of the race at 42 km/h over the whole route, whatever the relief. A time trial’s wet road only looks as far as the last start.
- The real wind of a time trial comes from a single 0.25° ERA5 cell at the midpoint. The wind of a valley, a pass or a seafront is not in it, and light rain is too frequent. To finish the extraction in a day, 213 cells cover 10 years (2016 to 2025) and the rest only 5 (2021 to 2025): the statistics of the northern regions, the most affected, have wider intervals.
- Riders eliminated outside the time limit on the first stage remain more numerous than aimed for (median of 15 to 17 against a target of 0 to 6), before and after the weather: a drift that comes from elsewhere, to be picked up with the time limits.
- Old races do not load. A race saved before version 10 is refused, with no migration.
The climate statistics come from Copernicus’s ERA5 reanalysis, obtained through the Open-Meteo archive API, which also supplies the archived forecasts we used to tune the forecast’s sharpness. Both are credited in the game.