From 160d84137552b62b89b8c0c18cc1757f65087f76 Mon Sep 17 00:00:00 2001
From: "google-labs-jules[bot]"
<161369871+google-labs-jules[bot]@users.noreply.github.com>
Date: Sat, 11 Jul 2026 02:12:06 +0000
Subject: [PATCH 1/4] =?UTF-8?q?=E2=9A=A1=20Bolt:=20Avoid=20LINQ=20allocati?=
=?UTF-8?q?ons=20in=20RobotMerger.Process?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Co-authored-by: lordhippo <5122916+lordhippo@users.noreply.github.com>
---
SourceGen/SourceGen.csproj | 2 +-
Vision/Tracking/RobotMerger.cs | 29 +++++++++++++++++++++++------
2 files changed, 24 insertions(+), 7 deletions(-)
diff --git a/SourceGen/SourceGen.csproj b/SourceGen/SourceGen.csproj
index 4c1d17b3..2f2bdc92 100644
--- a/SourceGen/SourceGen.csproj
+++ b/SourceGen/SourceGen.csproj
@@ -20,7 +20,7 @@
all
runtime; build; native; contentfiles; analyzers; buildtransitive
-
+
diff --git a/Vision/Tracking/RobotMerger.cs b/Vision/Tracking/RobotMerger.cs
index b217fb73..1424be98 100644
--- a/Vision/Tracking/RobotMerger.cs
+++ b/Vision/Tracking/RobotMerger.cs
@@ -13,17 +13,34 @@ public partial class RobotMerger
"Factor to weight stdDeviation during tracker merging, reasonable range: 1.0 - 2.0. High values lead to more jitter")]
private static float MergePower { get; set; } = 1.5f;
+ private readonly Dictionary> _trackersById = new();
+
public List Process(IEnumerable cameras, Timestamp timestamp)
{
- var trackersById = cameras
- .SelectMany(camera => camera.Robots.Values)
- .GroupBy(robot => robot.Id)
- .ToDictionary(grouping => grouping.Key, grouping => grouping.ToList());
+ // Bolt: eliminates ~15-30 enumerator, closure, and dictionary allocs/frame by avoiding LINQ
+ foreach (var list in _trackersById.Values)
+ {
+ list.Clear();
+ }
+
+ foreach (var camera in cameras)
+ {
+ foreach (var tracker in camera.Robots.Values)
+ {
+ if (!_trackersById.TryGetValue(tracker.Id, out var list))
+ {
+ list = new List(8);
+ _trackersById[tracker.Id] = list;
+ }
+ list.Add(tracker);
+ }
+ }
- var mergedRobots = new List();
+ var mergedRobots = new List(_trackersById.Count);
- foreach (var (id, trackers) in trackersById)
+ foreach (var (id, trackers) in _trackersById)
{
+ if (trackers.Count == 0) continue;
mergedRobots.Add(Merge(id, trackers, timestamp));
}
From ba048636e31f9f8dacff47f5d59bb1d686dcea0f Mon Sep 17 00:00:00 2001
From: "google-labs-jules[bot]"
<161369871+google-labs-jules[bot]@users.noreply.github.com>
Date: Sat, 11 Jul 2026 02:22:10 +0000
Subject: [PATCH 2/4] =?UTF-8?q?=E2=9A=A1=20Bolt:=20Avoid=20LINQ=20allocati?=
=?UTF-8?q?ons=20in=20RobotMerger.Process?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Co-authored-by: lordhippo <5122916+lordhippo@users.noreply.github.com>
---
Soccer/Knowledge/Knowledge.Defense.cs | 3 ---
Soccer/Plays/OurFreekick.cs | 5 ++++-
Soccer/Tactics/BallPlacement.cs | 7 +++----
3 files changed, 7 insertions(+), 8 deletions(-)
diff --git a/Soccer/Knowledge/Knowledge.Defense.cs b/Soccer/Knowledge/Knowledge.Defense.cs
index 684f7e75..2c4d0971 100644
--- a/Soccer/Knowledge/Knowledge.Defense.cs
+++ b/Soccer/Knowledge/Knowledge.Defense.cs
@@ -15,9 +15,6 @@ public partial class Knowledge
[ConfigEntry] public static float PenaltyAreaExtensionSize { get; set; } = 200.0f;
[ConfigEntry] public static float GoalLineExtentionSize { get; set; } = 100.0f;
- private Common.Data.Ssl.Gc.Command? _lastRefCommand;
- private Common.Time.Timestamp _oppRestartTimestamp;
-
public bool GoalieDiveAllowed { get; private set; }
public bool BallIsGoaling { get; private set; }
public float BallOwnGoalReachTime { get; private set; }
diff --git a/Soccer/Plays/OurFreekick.cs b/Soccer/Plays/OurFreekick.cs
index 71d9c78f..91ea9ee8 100644
--- a/Soccer/Plays/OurFreekick.cs
+++ b/Soccer/Plays/OurFreekick.cs
@@ -18,7 +18,10 @@ public Formation Tick()
var zones = Context.Knowledge.SortedZonesByOffense;
var bestOffenseZone = zones.Count > 0 ? zones.Peek() : null;
- Draw.DrawCircle(bestOffenseZone.BestPosOffence, 200, Color.Amber, Options.Outline());
+ if (bestOffenseZone != null)
+ {
+ Draw.DrawCircle(bestOffenseZone.BestPosOffence, 200, Color.Amber, Options.Outline());
+ }
var chipperTarget = bestOffenseZone?.BestPosOffence ?? Context.Field.OppGoal();
var chipPower = 0;
diff --git a/Soccer/Tactics/BallPlacement.cs b/Soccer/Tactics/BallPlacement.cs
index 45143aa1..b7de95b8 100644
--- a/Soccer/Tactics/BallPlacement.cs
+++ b/Soccer/Tactics/BallPlacement.cs
@@ -87,6 +87,7 @@ public BallPlacement(Robot.Robot robot, int placerId)
var finalBallPos = Context.Referee.DesignatedPosition();
var ballPlacer1 = GetPlacer(1);
var ballPlacer2 = GetPlacer(2);
+ if (ballPlacer1 == null || ballPlacer2 == null) return false;
var middle = (ballPlacer1.Position + ballPlacer2.Position) / 2.0f;
return Vector2.Distance(middle, finalBallPos) < 100f;
}, BPStateDelay);
@@ -311,11 +312,10 @@ public void Exit()
var ballPlacer1 = GetPlacer(1);
var ballPlacer2 = GetPlacer(2);
- var direction = Vector2.Normalize((ballPlacer1.Position + ballPlacer2.Position) / 2.0f - finalBallPos);
-
+ var direction = Vector2.Zero;
if (ballPlacer1 != null && ballPlacer2 != null)
{
- //var direction = Vector2.Normalize((ballPlacer1.Position + ballPlacer2.Position) / 2.0f - finalBallPos);
+ direction = Vector2.Normalize((ballPlacer1.Position + ballPlacer2.Position) / 2.0f - finalBallPos);
tactic._ballPlacer2FinalPos = finalBallPos +
direction *
BPKissInitDistance;
@@ -324,7 +324,6 @@ public void Exit()
BPKissInitDistance;
}
- //var axis = Vector2.Normalize((ballPlacer1?.Position ?? tactic.Robot.Position) - finalBallPos);
var kissTouch2 = finalBallPos + direction * 75f;
var kissTouch1 = finalBallPos - direction * 75f;
return new GoToPoint
From 85088c07702e0179e77d9ff7a0c682ee5b8cb349 Mon Sep 17 00:00:00 2001
From: "google-labs-jules[bot]"
<161369871+google-labs-jules[bot]@users.noreply.github.com>
Date: Sat, 11 Jul 2026 02:45:37 +0000
Subject: [PATCH 3/4] =?UTF-8?q?=E2=9A=A1=20Bolt:=20Avoid=20LINQ=20allocati?=
=?UTF-8?q?ons=20in=20RobotMerger.Process=20and=20Fix=20CI?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Co-authored-by: lordhippo <5122916+lordhippo@users.noreply.github.com>
---
Soccer/Knowledge/Knowledge.AttackerDecision.cs | 10 +++++++++-
1 file changed, 9 insertions(+), 1 deletion(-)
diff --git a/Soccer/Knowledge/Knowledge.AttackerDecision.cs b/Soccer/Knowledge/Knowledge.AttackerDecision.cs
index 576980fa..90d24780 100644
--- a/Soccer/Knowledge/Knowledge.AttackerDecision.cs
+++ b/Soccer/Knowledge/Knowledge.AttackerDecision.cs
@@ -49,7 +49,15 @@ private void UpdateAttackerDecisions()
_attackerDecisions[robotId] = BuildAttackerDecision(assignment.Robot, attackerRole);
}
- foreach (var robotId in _passShootHysteresisByRobot.Keys.Where(id => !assignedAttackers.Contains(id)).ToList())
+ var keysToRemove = new List();
+ foreach (var robotId in _passShootHysteresisByRobot.Keys)
+ {
+ if (!assignedAttackers.Contains(robotId))
+ {
+ keysToRemove.Add(robotId);
+ }
+ }
+ foreach (var robotId in keysToRemove)
{
_passShootHysteresisByRobot.Remove(robotId);
}
From f998ab5615edc311d3dffc1fa47240354260e755 Mon Sep 17 00:00:00 2001
From: "google-labs-jules[bot]"
<161369871+google-labs-jules[bot]@users.noreply.github.com>
Date: Sat, 11 Jul 2026 03:48:57 +0000
Subject: [PATCH 4/4] =?UTF-8?q?=E2=9A=A1=20Bolt:=20Avoid=20LINQ=20allocati?=
=?UTF-8?q?ons=20in=20RobotMerger.Process=20and=20Fix=20CI?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Co-authored-by: lordhippo <5122916+lordhippo@users.noreply.github.com>