Map presenter: ShowAsteroidsInMinimap stays (head's belt cost misses 0.1 ms); belt upload via SubUpdates; settings key restored

The setting gates belts on the minimap again, through MapPresenter.BeltsOnMinimap; the map screen always draws them.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Meta Vens 2026-10-16 23:54:45 +02:00
commit 4694366d98
8 changed files with 35 additions and 10 deletions

View file

@ -63,6 +63,7 @@ public static class MapBeltPerf
var transforms = new float4[count];
// BEGIN MEASURED SETUP
var presenter = new MapPresenter(new Material[0], AssetDatabase.LoadAssetAtPath<Material>("Assets/Materials/UI/MapAsteroid.mat"), 4, 4, 3f);
presenter.BeltsOnMinimap = true;
presenter.RegisterBelt(beltKey, transforms);
// END MEASURED SETUP
var stopwatch = new Stopwatch();

View file

@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 2bf3d3dcd7e3dd940add2640db93e3fe

View file

@ -141,6 +141,7 @@ public static class MapPresenterSmoke
var belt = new float4[Asteroids];
map.RegisterBelt(beltKey, belt);
zone.EvaluateBelt(beltKey, belt, DrawAhead.Time(zone, 0));
map.BeltsOnMinimap = true;
map.SetFade(ship, 1f);
map.SetFade(other, 1f);
map.SetMinimapScale(2f);
@ -177,6 +178,16 @@ public static class MapPresenterSmoke
for (var i = 0; i < belt.Length; i++)
Require(read[i].x == belt[i].x && read[i].y == belt[i].y && read[i].z == belt[i].z && read[i].w == belt[i].w, $"Belt buffer differs from the frame's floats at {i}.");
// The setting still gates belts on the minimap, and the map screen always shows them.
map.BeltsOnMinimap = false;
map.Draw(zone, 0);
Require(map.BeltDraws == 0, "A belt drew on the minimap with the setting off.");
map.OpenMapScreen(true);
map.Draw(zone, 0);
Require(map.BeltDraws == 1, "The map screen did not draw the belt with the setting off.");
map.OpenMapScreen(false);
map.BeltsOnMinimap = true;
// Fade: half faded reaches the icon's colour alpha on the next draw; faded out draws nothing.
map.SetFade(ship, .5f);
map.Draw(zone, 0);

View file

@ -297,6 +297,7 @@ public class ActionGameManager : MonoBehaviour
ItemManager = new ItemManager(CultCache, PendingScenario != null ? new ProvenanceLedger() : RunSave.Lots(CultCache),
Settings.GameplaySettings, Debug.Log);
ZoneRenderer.ItemManager = ItemManager;
ZoneRenderer.Map.BeltsOnMinimap = PlayerSettings.GraphicsSettings.ShowAsteroidsInMinimap;
// TODO: Process Stories

View file

@ -63,7 +63,7 @@ public class PlayerGameplaySettings
public class PlayerGraphicsSettings
{
[Key(0)] public Quality NebulaQuality = Quality.Normal;
// Key 1 is retired; an older player.cc that still carries it loads, and it is dropped.
[Key(1)] public bool ShowAsteroidsInMinimap;
// How hard the camera shakes when the player's ship takes an impact: 0 off, 1 full (Feedback.Cue).
[Key(2)] public float ScreenShake = 1f;
}

View file

@ -296,6 +296,9 @@ public class MainMenu : MonoBehaviour
CloudRenderer.quality = ActionGameManager.PlayerSettings.GraphicsSettings.NebulaQuality;
},
Enum.GetNames(typeof(Quality)));
_nextMenu.panel.AddField("Show Asteroids in Minimap",
() => ActionGameManager.PlayerSettings.GraphicsSettings.ShowAsteroidsInMinimap,
b => ActionGameManager.PlayerSettings.GraphicsSettings.ShowAsteroidsInMinimap = b);
_nextMenu.panel.AddField("Screen Shake",
() => ActionGameManager.PlayerSettings.GraphicsSettings.ScreenShake,
f => ActionGameManager.PlayerSettings.GraphicsSettings.ScreenShake = f,

View file

@ -67,6 +67,9 @@ public class MapPresenter
public float IconSize => _mapScreenOpen ? _mapScreenScale : _minimapScale;
public void SetMinimapScale(float scale) => _minimapScale = scale;
public void OpenMapScreen(bool open) => _mapScreenOpen = open;
// PlayerGraphicsSettings.ShowAsteroidsInMinimap: belt sprites on the minimap; the map screen always shows them.
public bool BeltsOnMinimap { get; set; }
public void SetMapScreenScale(float scale) => _mapScreenScale = scale;
// Destroy in play mode, DestroyImmediate where the editor smokes run without one.
@ -160,12 +163,18 @@ public class MapPresenter
// A belt's map sprites: the 3D belt's per-frame float4s (x, y planar, z spin, w size), uploaded as they are.
public void RegisterBelt(CultRecordKey key, float4[] source) =>
_belts[key] = new Belt { Source = source, Buffer = new ComputeBuffer(source.Length, 16) };
_belts[key] = new Belt
{
Source = source,
Buffer = new ComputeBuffer(source.Length, 16, ComputeBufferType.Structured, ComputeBufferMode.SubUpdates)
};
// One instanced draw per belt: six vertices per asteroid, expanded to a quad on the map plane by the shader.
private void DrawBelt(Belt belt)
{
belt.Buffer.SetData(belt.Source);
var upload = belt.Buffer.BeginWrite<float4>(0, belt.Source.Length);
upload.CopyFrom(belt.Source);
belt.Buffer.EndWrite<float4>(belt.Source.Length);
belt.Block.SetBuffer(BeltProperty, belt.Buffer);
belt.Block.SetVector(SheetProperty, _spriteSheet);
belt.Block.SetFloat(PlaneProperty, PlaneY + BeltOffset);
@ -222,7 +231,8 @@ public class MapPresenter
material.SetFloat("_DepthRange", depthRange);
}
foreach (var belt in _belts.Values) DrawBelt(belt);
if (BeltsOnMinimap || _mapScreenOpen)
foreach (var belt in _belts.Values) DrawBelt(belt);
}
public void Clear()

View file

@ -555,7 +555,7 @@ public sealed partial class RunStartTests
Assert.False(main.IsTutorial);
}
// PlayerSettings Key 2, the never-written tutorial flag, and PlayerGraphicsSettings Key 1, ShowAsteroidsInMinimap, are retired: a player.cc written with it still loads, every other field intact.
// PlayerSettings Key 2, the never-written tutorial flag, is retired: a player.cc written with it still loads, every other field intact.
[Fact]
public void OldPlayerSettingsLoad()
{
@ -569,10 +569,7 @@ public sealed partial class RunStartTests
MessagePackSerializer.Serialize(ref writer, new Dictionary<string, string> { ["story"] = "hash" }, options);
MessagePackSerializer.Serialize(ref writer, new PlayerGameplaySettings { TemperatureUnit = TemperatureUnit.Kelvin, SignificantDigits = 5 }, options);
MessagePackSerializer.Serialize(ref writer, new PlayerInputSettings { ActionBarInputs = { "<Keyboard>/1" } }, options);
writer.WriteArrayHeader(3); // PlayerGraphicsSettings with its retired Key 1 (ShowAsteroidsInMinimap)
MessagePackSerializer.Serialize(ref writer, Quality.High, options);
writer.Write(true);
writer.Write(.4f);
MessagePackSerializer.Serialize(ref writer, new PlayerGraphicsSettings { NebulaQuality = Quality.High, ShowAsteroidsInMinimap = true }, options);
writer.Flush();
var settings = MessagePackSerializer.Deserialize<PlayerSettings>(buffer.WrittenMemory, options);
@ -581,7 +578,7 @@ public sealed partial class RunStartTests
Assert.Equal("hash", settings.HashedStoryFiles["story"]);
Assert.Equal((TemperatureUnit.Kelvin, 5), (settings.GameplaySettings.TemperatureUnit, settings.GameplaySettings.SignificantDigits));
Assert.Equal("<Keyboard>/1", Assert.Single(settings.InputSettings.ActionBarInputs));
Assert.Equal((Quality.High, .4f), (settings.GraphicsSettings.NebulaQuality, settings.GraphicsSettings.ScreenShake));
Assert.Equal((Quality.High, true), (settings.GraphicsSettings.NebulaQuality, settings.GraphicsSettings.ShowAsteroidsInMinimap));
}
// A scenario's Brief is player text (the menu shows it): it names gear by what the catalog sells today. A name a rename retired,