Climate (Core) layers a continuous seasonal-plus-daily temperature and the current season over the Calendar, registered via context.UseClimate. A new Lighting module (Graphics) adds DayNight: a daylight factor and ambient color from the calendar's time of day, pushed into the renderer's new AmbientLight (multiplied into world-space sprites only, so the scene darkens at night while screen-space overlays stay readable) and exposed as a sampleable SampleAt for the simulation. Both deterministic and GPU-free, covered by tests; docs updated. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
f39ee9e787
commit
a684c23cd9
@@ -0,0 +1,84 @@
|
||||
using MrGameEng.Core;
|
||||
using Xunit;
|
||||
|
||||
namespace MrGameEng.Core.Tests;
|
||||
|
||||
public class ClimateTests
|
||||
{
|
||||
private static (GameClock Clock, Climate Climate) Make(ClimateSettings settings)
|
||||
{
|
||||
var clock = new GameClock();
|
||||
var calendar = new Calendar(clock, secondsPerDay: 10f);
|
||||
return (clock, new Climate(calendar, settings));
|
||||
}
|
||||
|
||||
private static ClimateSettings Seasonal =>
|
||||
new()
|
||||
{
|
||||
DaysPerYear = 60,
|
||||
MeanTemperature = 10f,
|
||||
SeasonalAmplitude = 20f,
|
||||
DailyAmplitude = 0f,
|
||||
WarmestDay = 15,
|
||||
};
|
||||
|
||||
[Fact]
|
||||
public void Constructor_NonPositiveYear_Throws()
|
||||
{
|
||||
Assert.Throws<ArgumentOutOfRangeException>(() =>
|
||||
new Climate(new Calendar(new GameClock(), 10f), Seasonal with { DaysPerYear = 0 })
|
||||
);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Temperature_PeaksOnWarmestDay_AndBottomsHalfYearLater()
|
||||
{
|
||||
var (clock, climate) = Make(Seasonal);
|
||||
|
||||
clock.Advance(15 * 10f); // day 15 = warmest
|
||||
Assert.Equal(30f, climate.Temperature, 2); // mean 10 + amplitude 20
|
||||
|
||||
clock.Advance(30 * 10f); // +30 days = half a 60-day year later
|
||||
Assert.Equal(-10f, climate.Temperature, 2); // mean 10 - amplitude 20
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void DailySwing_WarmerAtNoonThanMidnight()
|
||||
{
|
||||
var settings = Seasonal with { SeasonalAmplitude = 0f, DailyAmplitude = 6f };
|
||||
var (clock, climate) = Make(settings);
|
||||
|
||||
clock.Advance(5f); // day 0, noon (DayProgress 0.5)
|
||||
Assert.Equal(16f, climate.Temperature, 2); // mean 10 + daily 6
|
||||
|
||||
clock.Advance(5f); // day 1, midnight (DayProgress 0)
|
||||
Assert.Equal(4f, climate.Temperature, 2); // mean 10 - daily 6
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Season_FollowsTheQuarterOfTheYear()
|
||||
{
|
||||
var (clock, climate) = Make(Seasonal); // 60-day year → 15 days per season
|
||||
|
||||
Assert.Equal(Season.Spring, climate.Season);
|
||||
clock.Advance(20 * 10f);
|
||||
Assert.Equal(Season.Summer, climate.Season);
|
||||
clock.Advance(15 * 10f);
|
||||
Assert.Equal(Season.Autumn, climate.Season);
|
||||
clock.Advance(15 * 10f);
|
||||
Assert.Equal(Season.Winter, climate.Season);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void YearAndDayOfYear_RollOver()
|
||||
{
|
||||
var (clock, climate) = Make(Seasonal);
|
||||
|
||||
Assert.Equal(1, climate.Year);
|
||||
Assert.Equal(0, climate.DayOfYear);
|
||||
|
||||
clock.Advance(60 * 10f); // exactly one year
|
||||
Assert.Equal(2, climate.Year);
|
||||
Assert.Equal(0, climate.DayOfYear);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user