Merge orbits-placed-at-build into gravity-subtract

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Meta Vens 2026-10-14 22:07:09 +02:00
commit 570f22083b
3 changed files with 176 additions and 26 deletions

View file

@ -161,6 +161,12 @@ public class Zone
Orbits.Add(orbit.Key, new Orbit(Settings, cache.Get(orbit)));
}
// Aetheria gravity (target invariant zone-valid-before-tick): every orbit is placed at the pack's time
// when the zone is built, so each well, light and body pose read before the first Update is where the
// body is. Velocity stays zero until the first Update differences two placed positions.
foreach (var orbit in Orbits)
GetOrbitPosition(orbit.Key);
foreach (var body in pack.Planets)
{
var planet = cache.Get(body);
@ -266,18 +272,16 @@ public class Zone
private bool IsExpired(ChunkWear wear) => wear.Damage <= 0f && (!wear.BrokenUntil.HasValue || wear.BrokenUntil.Value <= _time);
public void AddOrbit(OrbitData orbit)
{
Orbits.Add(_itemManager.ItemData.RefOf(orbit).Key, new Orbit(Settings, orbit));
}
public void Update(float deltaTime)
{
_time += deltaTime;
_updatedOrbits.Clear();
// Every previous position is taken before any orbit is placed: GetOrbitPosition places a parent as a
// side effect of placing its child, so differencing inside one loop would depend on dictionary order.
foreach (var orbit in Orbits)
orbit.Value.PreviousPosition = orbit.Value.Position;
foreach (var orbit in Orbits)
{
orbit.Value.PreviousPosition = orbit.Value.Position;
orbit.Value.Position = GetOrbitPosition(orbit.Key);
orbit.Value.Velocity = (orbit.Value.Position - orbit.Value.PreviousPosition) / deltaTime;
}
@ -591,26 +595,6 @@ public class Zone
into[i] = beltInstance.Pose(i, _time, parentPosition, Settings, ChunkRadius(new ChunkId(belt, i)));
}
public OrbitData CreateOrbit(CultRecordKey parent, float2 position)
{
var parentPosition = GetOrbitPosition(parent);
var delta = position - parentPosition;
var distance = length(delta);
var period = Settings.OrbitPeriod.Evaluate(distance);
var phase = atan2(delta.y, delta.x) / (PI * 2);
var currentPhase = frac(_time / period);
var storedPhase = (float) frac(phase - currentPhase);
var orbit = new OrbitData
{
Distance = distance,
Parent = new CultRecordRef<OrbitData>(parent),
Phase = storedPhase
};
Orbits.Add(_itemManager.ItemData.Upsert(orbit).Key, new Orbit(Settings, orbit));
return orbit;
}
public SecurityLevel GetSecurityLevel(float2 pos)
{
if (GalaxyZone.Owner==null) return SecurityLevel.Open;