World & rooms

Weather and seasons

The daily weather, the seasons and the temperature, set by each city's climate in .ulweather files, and how scenes and actions read them.

Every morning the game draws the day's weather from the current city's climate and the season. The map shows it (cloud cover, fog, rain and snow over the city, the sky icon and temperature next to the clock), the player feels it (its mood and energy, once that morning), and scenes and actions can read it or force it.

The season is the meteorological one for the calendar month (December to February is winter), swapped for a city in the southern hemisphere. The calendar is real: a game starts on today's date (see Game:GetDate).

Reading it from Lua

lualocal w = Game:getWeather()
-- { id = "rain", name = "Rain", icon = "rain", mood = -2, energy = 0, outdoor = false,
--   temperature = 9.5, season = "autumn", forced = false, cloud = 1, fog = 0.35, rain = 0.6, snow = 0, wind = 0.3 }

if w.id == "snow" and Game:getSeason() == "winter" then
	Game:Narrate("The whole street is out with sledges.")
end

local d = Game:GetDate()   -- now also d.dayOfYear (1-366) and d.season
local c = Game:getTemperature()   -- Celsius

Weather types are open-ended: test for the ids you care about, and treat anything else as ordinary weather. The ones ul_Base ships are clear, partly_cloudy, overcast, fog, rain, storm, snow, heatwave and windy.

Forcing it

A scene can set the weather for a while, for a storm in a story or snow on a Christmas scene:

luaGame:setWeather("storm", 3)    -- three game hours, then the day's own weather comes back
Game:setWeather("snow")        -- until midnight
Game:setWeather(nil)           -- lift it now

The day's weather is not redrawn when a forced one ends. setWeather returns false for an id no .ulweather declares, and logs the known ids.

Outdoor actions

Two optional fields of an action check the weather:

luaOUTDOOR = true,                                     -- refused when the weather says outdoor = false (rain, storm)
WEATHER = { "clear", "partly_cloudy", "heatwave" }, -- only in these
WEATHER = { "-fog", "-snow" },                      -- never in these

A refused action shows "Not in this weather (Rain)." ul_Base marks camping, climbing, barbecues, bonfires, picnics and hiking OUTDOOR, and sunbathing and the nudist beach also want sun.

Reacting to a change

luaEvents:on(M, "weatherChanged", function(newId, oldId)
	-- the morning's draw, a scene's setWeather, or a forced weather running out
end)

The .ulweather file

Weather/*.ulweather is JSON with two maps, types and climates. Every mod's files are read in load order, and a later mod replaces a type or a climate with the same id, or adds new ones. To add a weather, declare its type and give it a weight in the climates and seasons where it can happen.

json{
	"types": {
		"drizzle": { "name": "Drizzle", "icon": "rain", "night_icon": "rain", "mood": -1, "energy": 0,
		             "outdoor": true, "temp": -1, "cloud": 0.9, "fog": 0.3, "rain": 0.25, "snow": 0, "wind": 0.1 }
	},
	"climates": {
		"oceanic": {
			"persistence": 0.45,
			"winter": { "temp": [2, 8], "weights": { "overcast": 30, "drizzle": 20, "rain": 15, "clear": 10 } },
			"spring": { "temp": [6, 15], "weights": { "clear": 20, "partly_cloudy": 30, "drizzle": 20 } },
			"summer": { "temp": [13, 23], "weights": { "clear": 35, "partly_cloudy": 30, "rain": 15 } },
			"autumn": { "temp": [7, 15], "weights": { "overcast": 25, "fog": 15, "drizzle": 20 } }
		}
	}
}

Replacing a climate replaces it whole, so copy all four seasons from ul_Base/Weather/weather.ulweather and change what you need.

Type fields

Field Meaning
name Shown as the sky icon's tooltip and returned to scenes
icon, night_icon A picture in Map/Icons/Weather/ (without .png), by day and after dark
mood, energy Given to the player once, the morning this weather is drawn (not when a scene forces it)
outdoor false: actions with OUTDOOR = true are refused. Default true
temp Degrees added to the season's temperature
cloud 0–1. Dims the sun and its shadows, greys the sky and haze
fog 0–1. Thickens the haze until far blocks disappear
rain, snow 0–1. How much falls over the map (streaks or flakes)
wind 0–1. Slants the rain and drifts the snow

A storm (rain and wind both 0.9 or more) also flashes lightning now and then. Any type with snow above 0 keeps the temperature at 1°C or below.

Climate fields

Field Meaning
persistence 0–1. The chance a day keeps yesterday's weather, when the season has it: weather comes in spells
winter, spring, summer, autumn Each with temp: [coldest, warmest] in Celsius (coldest around 4:00, warmest around 16:00, a cloudy day spreads less) and weights: { type: weight }. A type missing from a season never happens in it

ul_Base ships eight climates: oceanic, continental, subarctic, mediterranean, humid_subtropical, desert, tropical and highland. A city picks one in its .ulcity with Climate:, and Hemisphere: south swaps its seasons.