How the climbability score is computed
An hourly weather series and the crag's own attributes go in. Five 0–1 sub-scores come out, get weighted into one 0–100 number per hour, and are then aggregated into the daily score and the day's best window. It's a transparent, deterministic heuristic — no machine learning — and the “why this score” breakdown on a crag page names the same factors as the steps below.
1.The inputs
Weather comes from Open-Meteo — hourly, free, no key — cached for 1 h per location so a busy page can't hammer it. Each hour supplies air temperature, dew point, relative humidity, precipitation, the chance that precipitation actually falls, wind speed and cloud cover.
The series spans 5 past days plus 6 forecast days. Past hours are never scored or shown: they are there to warm up the wetness store and the rock temperature, so the first hour you see starts from a settled state instead of a guess.
From the crag itself: aspect, sun exposure, dry-time class, tree cover and rock type. Every attribute left unset falls back to a neutral default — which is why a crag page with gaps asks you to fill them in.
2.Sun and aspect (0–1)
One score for how hard the sun is working on this rock this hour. It is a transparent lookup, not a solar simulation, and it feeds three later steps: the rock temperature, the evaporation rate, and the hourly score itself.
effective sun = exposure window × aspect sunniness × (1 − 0.7 × cloud fraction)
sun score = clamp01(0.4 + 0.6 × effective sun × tree damping)Between the crag's own sunrise and sunset there is solar drying to score; outside them there is none, and the score sits flat at 0.45. Those two times are computed for this crag on this date with the standard NOAA solar formula, from its latitude, longitude and timezone — so a December afternoon window closes when the sun actually sets, not at a fixed evening hour.
Everything below is anchored to solar noon rather than to 12:00 or 13:00, because the two are rarely the same: with summer time a Spanish crag sees the sun highest after 14:00. The exposure windows are also measured as fractions of the half-day (solar noon to sunset), so they widen through the summer and tighten in winter along with the daylight itself.
| Aspect | Sunniness |
|---|---|
| North | 0.35 |
| North-East | 0.50 |
| East | 0.70 |
| South-East | 0.90 |
| South | 1.00 |
| South-West | 0.90 |
| West | 0.70 |
| North-West | 0.50 |
| Sheltered / varied | 0.65 |
| Sun exposure | Sun window across the day |
|---|---|
| Full sun | Bell peaking at solar noon, width 6 h on a 12 h day |
| Morning sun | Bell peaking 3 h before solar noon, width 3.5 h on a 12 h day |
| Afternoon sun | Bell peaking 3 h after solar noon, width 3.5 h on a 12 h day |
| Shaded | Flat 0.15 |
| Unset / unknown | 0.5 × the full-sun bell, plus 0.15 |
bell(hour) = exp(−½ × ((hour − peak) / width)²)Tree cover multiplies the solar term by 0.85 (shade, plus moisture held in the ground), and the 0.4 floor stops a shaded or night hour being crushed to nothing: shade doesn't make a crag unclimbable, it just offers no help drying.
3.Rock temperature
Skin grips rock, and dew forms on rock — neither happens in the air the forecast reports. A wall in the sun runs well above air temperature, one that radiated to a clear sky all night runs below it, and either way the surface takes hours to follow a change in the air.
So every hour gets an equilibrium target: where the surface would settle if this hour's conditions held forever. The solar part reuses the sun score from step 2, which already blends aspect, exposure, cloud and trees.
solar load = clamp01((sun score − 0.45) / (1 − 0.45))
target = air temp + lerp(−2 °C × clear-sky fraction, +12 °C, solar load)The surface then chases that target with a first-order lag, closing the same fraction of the remaining gap every hour:
α = 1 − e^(−1/τ)
rock(h) = rock(h−1) + (target(h) − rock(h−1)) × ατ is the thermal time constant, in hours. Thermal mass is really a property of the formation, but rock type is the proxy we can collect:
| Rock type | τ (hours) |
|---|---|
| Granite | 5.0 |
| Gritstone | 4.0 |
| Limestone | 4.0 |
| Sandstone | 3.0 |
| Quartzite | 5.0 |
| Conglomerate | 4.0 |
| Slate | 2.5 |
| Other | 3.5 |
| Unset / unknown | 3.5 |
A first-order lag delays the daily peak by atan(ωτ)/ω with ω = 2π/24, and damps its swing by 1/√(1+(ωτ)²): τ = 3–5 h puts the rock's warmest moment 2.5–3.5 h after the air's, at about 0.7 of the air's amplitude — granite still cold mid-morning, still warm at dusk. The walk starts at equilibrium, since with no earlier weather there is nothing to lag behind.
4.Dryness (0–1) — a wetness store
Drying isn't a clock. The model carries a store of water held by the rock, in millimetres, and walks it hour by hour across the whole series: each hour soaks its rain in with diminishing returns, then drains a little back out.
soak store += (cap − store) × (1 − e^(−precip / k)) cap = 1.8 mm, k = 1.23 mm
drain store = max(0, store − 1 / horizon × evaporation)
read dryness = clamp01(1 − store / 1 mm)An actively-raining hour (≥ 0.1 mm) scores 0 for dryness outright, whatever the store says — the surface is wet this instant, and the store is read at the hour's start so it holds none of that rain yet. For a forecast hour, that override is applied in proportion to how sure the rain is; see the next step. Otherwise dryness is read off the level: empty is bone dry, 1 mm reads soaked. 1 mm of rain on dry rock brings the store to exactly that level, i.e. one full drying horizon's worth, and the horizon comes from the crag's dry-time class:
| Dry-time class | Drying horizon | Baseline drain |
|---|---|---|
| Fast (dries in hours) | 6 h | 0.167 mm/h |
| Medium (~1 day) | 24 h | 0.042 mm/h |
| Slow (~3 days) | 72 h | 0.014 mm/h |
| Seepy (a week+) | 168 h | 0.006 mm/h |
The 1.8 mm ceiling is what lets a deluge stay wet longer than a shower without implying unbounded seepage — at most 1.8 drying horizons' worth. k isn't a knob: it is derived from the three levels so that 1 mm lands exactly on soaked.
This replaced an “hours since the last ≥ 1 mm of rain” clock, which called twelve hours of 0.15 mm/h drizzle bone dry and had a cliff at exactly 1 mm.
5.How sure is the rain?
Five days out, a precipitation figure is one model run's single draw from a distribution, not a measurement. Taken at face value, a shower with a one-in-five chance soaked the store exactly like rain that fell — so a whole day read washed out for weather that most likely never arrives. Open-Meteo also reports, for every forecast hour, the share of its ensemble members that get more than 0.1 mm. That is the confidence each forecast hour's rain is weighted by:
confidence = clamp(0.2 … 1, chance / 70 %)
soak store += (cap − store) × (1 − e^(−precip / k)) × confidenceWeighting the soak makes the store an expectation rather than a single scenario: the step is exactly an interpolation between the two futures “this rain falls” and “it doesn't”, at the forecast's own odds. The three steps that react to rain falling right now blend the same way and by the same weight — dryness toward 0, the hourly score toward its ×0.3 gate, and the air toward saturated in the evaporation term. So a one-in-five shower reads damp and mildly penalised instead of either washed out or bone dry. None of the four puts a threshold on the probability: a 49 % shower and a 51 % one differ by as little as the weather does, and at full confidence every step is exactly what it was before any of this existed.
The weight only ever discounts rain a model already predicts — a high chance with no precipitation figure (common in the dry hours between showers) never invents water. Observed past hours, which is all the antecedent-rainfall warm-up uses, carry full confidence, as does any hour whose forecast comes with no probability at all. The breakdown is the one place that does need a cut-point, because a sentence has to pick a verb: from 50 % up it says rain is forecast, below it that a shower is possible. Either way it quotes the chance, so a discounted shower is visible rather than a quietly softened score.
70 % counts as certain rather than 100 % because an hourly probability is limited by how precisely the ensemble can place an event in time: wide stratiform rain does reach 99–100 %, but a solid band of frontal rain can sit at 70–85 % for hours it is certainly raining through. Rescaling there keeps confident rain at full strength instead of quietly shaving a fifth off every wet day — which would trade a false-wet signal for a systematic dry bias, the worse of the two. The 0.2 floor is the other end of the same argument: the deterministic run is usually the finer-resolution model of the pair, so it resolves small convective showers the ensemble behind the probability misses entirely, and a predicted shower with no ensemble support is unlikely rather than impossible.
6.The evaporation factor
The drain above is multiplied by how much faster than reference conditions this hour pulls water out of the rock. Reference — shade, a light breeze, moderately dry air, rock at air temperature — is exactly 1.0, which is what keeps a dry-time class meaningful as a number of hours. Four terms multiply:
| Term | Reference (= 1.0) | Range |
|---|---|---|
| Sun | sun score 0.45 (shade or night) | up to ×1.7 in full sun |
| Wind | 10 km/h | ×0.75 dead calm → ×1.4 at 35 km/h |
| Air dryness | 70 % RH | ×0.5 at 100 % RH → ×1.4 at 20 % RH |
| Rock vs. air | surface at air temperature | ×0.7 at 6 °C below → ×1.35 at 10 °C above |
evaporation = clamp(0.3 … 2.5, sun × wind × air × surface)The rock-vs-air term is a different signal from the sun term, not a second helping of it: the evaporating film sits at the surface's temperature, so a wall baked all afternoon keeps drying at dusk with the sun term already back at its night floor, and a cold morning wall dries slowly with the sun term already high.
Two edge cases override the arithmetic. While it rains, humidity is floored at 95 % — the air right at the rock is saturated whatever the station reports. And a surface at or below the dew point has no net evaporation at all (water is condensing onto it), so the factor drops to its 0.3 floor however much sun and wind are on it.
7.Condensation (0–1)
Water condenses on any surface below the dew point, so the margin that matters is measured from the rock temperature, not the air's:
condensation = clamp01((rock temp − dew point) / 8 °C) 0 when the gap ≤ 0Measuring it on the rock catches the classic morning trap the air-temperature version misses: warm damp air over a wall still cold from the night sweats on the holds while the air's own dew-point margin looks perfectly comfortable.
8.Friction (0–1)
A piecewise comfort curve on the rock temperature — flat at 1 through the prime band, falling to zero at either end:
5 … 12 °C → 1
colder → (rock + 8) / (5 + 8)
warmer → (30 − rock) / (30 − 12)Zero at −8 °C (numb fingers, possible ice) and at 30 °C (sweat, greasy holds). Because the input is the rock and not the air, a sunbaked wall reads greasy on a cool day and a shaded one crisp on a warm one.
9.Wind (0–1)
A light to moderate breeze dries rock and cools skin; a gale makes climbing unpleasant and, on a rope, dangerous.
5 … 25 km/h → 1
calmer → 0.5 + 0.5 × wind / 5
windier → ramps down to 0.3 at 50 km/h and stays thereDead calm still scores 0.5 rather than 0 — it is perfectly climbable, it just offers no drying help.
10.The hourly score
The five sub-scores are combined into a weighted average and scaled to 0–100:
| Factor | Weight |
|---|---|
| Dryness | 0.35 |
| No condensation | 0.25 |
| Friction (temp) | 0.20 |
| Wind | 0.10 |
| Sun / aspect | 0.10 |
| Total | 1.00 |
hourly climbability = 100 × Σ (sub-score × weight) × gateThe gate is the one hard, non-linear step. A weighted average lets a strong factor mask a disqualifying one: a raining hour scores 0 for dryness and can still reach 65 on perfect friction and wind. So when the rock is actively wet (≥ 0.1 mm this hour, weighted by how sure that rain is) or at/below the dew point, the whole score is multiplied by 0.3 — enough to drop it into the poor band whatever else is going on. The breakdown still names the reason, so the gate stays honest.
11.From hours to a day
Only hours from 8:00 to 19:00 that are also between sunrise and sunset go into the daily numbers. Both bounds earn their place: a great score at 03:00 isn't a climbing day even in a Nordic June, and 19:00 in December is long dark. The daily score is the rounded mean of that pool, and the band follows from it:
| Band | Score |
|---|---|
| Prime conditions | ≥ 80 |
| Good | 55 – 79 |
| Marginal / mixed | 35 – 54 |
| Poor — likely wet / no friction | 0 – 34 |
A mean hides a prime half-day: a dry morning before an afternoon storm averages out to “marginal” when the useful answer is “go before noon”. So each day also reports its best window — the strongest run of 3 clock-consecutive hours within the same pool, shortened only when the day has fewer. Ties go to the earliest window, since at equal score “go this morning” beats “go at dusk”, and the crag page only surfaces it when it beats the daily mean by 8 points or more.
The factor breakdown shown for a day is the one belonging to its hour closest to 14:00.
12.What it can't know
The forecast models a grid cell, not your crag. A seepage line, a roof that stays dry in the rain, a pocket of cold air at the base of the wall, spring snowmelt, a stream running under the boulders, the wind actually funnelling down the valley — all invisible to it. Crag attributes are crowd-sourced, and an unset one quietly becomes a neutral default, so a score can be wrong for a reason the page could have known. If you spot one, edit the crag.