diff --git a/assets/maps/ascent_svg_height_defense.json.gz b/assets/maps/ascent_svg_height_defense.json.gz index ab6c6f01..d0641538 100644 Binary files a/assets/maps/ascent_svg_height_defense.json.gz and b/assets/maps/ascent_svg_height_defense.json.gz differ diff --git a/assets/maps/bind_svg_height_attack.json.gz b/assets/maps/bind_svg_height_attack.json.gz index 152c4194..7c56d878 100644 Binary files a/assets/maps/bind_svg_height_attack.json.gz and b/assets/maps/bind_svg_height_attack.json.gz differ diff --git a/assets/maps/bind_svg_height_defense.json.gz b/assets/maps/bind_svg_height_defense.json.gz index affab695..c3d2e7a2 100644 Binary files a/assets/maps/bind_svg_height_defense.json.gz and b/assets/maps/bind_svg_height_defense.json.gz differ diff --git a/assets/maps/breeze_svg_height_attack.json.gz b/assets/maps/breeze_svg_height_attack.json.gz index 78c15679..6c7f55c0 100644 Binary files a/assets/maps/breeze_svg_height_attack.json.gz and b/assets/maps/breeze_svg_height_attack.json.gz differ diff --git a/assets/maps/breeze_svg_height_defense.json.gz b/assets/maps/breeze_svg_height_defense.json.gz index 4272b16c..fbd289bf 100644 Binary files a/assets/maps/breeze_svg_height_defense.json.gz and b/assets/maps/breeze_svg_height_defense.json.gz differ diff --git a/assets/maps/corrode_svg_height_attack.json.gz b/assets/maps/corrode_svg_height_attack.json.gz index 3f525062..dbdebef9 100644 Binary files a/assets/maps/corrode_svg_height_attack.json.gz and b/assets/maps/corrode_svg_height_attack.json.gz differ diff --git a/assets/maps/corrode_svg_height_defense.json.gz b/assets/maps/corrode_svg_height_defense.json.gz index 3595abb4..f9bbb7cc 100644 Binary files a/assets/maps/corrode_svg_height_defense.json.gz and b/assets/maps/corrode_svg_height_defense.json.gz differ diff --git a/assets/maps/fracture_svg_height_attack.json.gz b/assets/maps/fracture_svg_height_attack.json.gz index 34d49e44..7675e386 100644 Binary files a/assets/maps/fracture_svg_height_attack.json.gz and b/assets/maps/fracture_svg_height_attack.json.gz differ diff --git a/assets/maps/fracture_svg_height_defense.json.gz b/assets/maps/fracture_svg_height_defense.json.gz index bc474c2f..f1109722 100644 Binary files a/assets/maps/fracture_svg_height_defense.json.gz and b/assets/maps/fracture_svg_height_defense.json.gz differ diff --git a/assets/maps/haven_svg_height_attack.json.gz b/assets/maps/haven_svg_height_attack.json.gz index a2b636fe..9f68185f 100644 Binary files a/assets/maps/haven_svg_height_attack.json.gz and b/assets/maps/haven_svg_height_attack.json.gz differ diff --git a/assets/maps/haven_svg_height_defense.json.gz b/assets/maps/haven_svg_height_defense.json.gz index d84f3f0f..b2a9e405 100644 Binary files a/assets/maps/haven_svg_height_defense.json.gz and b/assets/maps/haven_svg_height_defense.json.gz differ diff --git a/assets/maps/icebox_svg_height_attack.json.gz b/assets/maps/icebox_svg_height_attack.json.gz index 09091ea3..403165e6 100644 Binary files a/assets/maps/icebox_svg_height_attack.json.gz and b/assets/maps/icebox_svg_height_attack.json.gz differ diff --git a/assets/maps/icebox_svg_height_defense.json.gz b/assets/maps/icebox_svg_height_defense.json.gz index 6dd031de..b18e792d 100644 Binary files a/assets/maps/icebox_svg_height_defense.json.gz and b/assets/maps/icebox_svg_height_defense.json.gz differ diff --git a/assets/maps/lotus_svg_height_attack.json.gz b/assets/maps/lotus_svg_height_attack.json.gz index 2a2cc2ff..93ad9334 100644 Binary files a/assets/maps/lotus_svg_height_attack.json.gz and b/assets/maps/lotus_svg_height_attack.json.gz differ diff --git a/assets/maps/lotus_svg_height_defense.json.gz b/assets/maps/lotus_svg_height_defense.json.gz index ea0b1558..ad0d0486 100644 Binary files a/assets/maps/lotus_svg_height_defense.json.gz and b/assets/maps/lotus_svg_height_defense.json.gz differ diff --git a/assets/maps/pearl_svg_height_attack.json.gz b/assets/maps/pearl_svg_height_attack.json.gz index d49030c0..12596fa9 100644 Binary files a/assets/maps/pearl_svg_height_attack.json.gz and b/assets/maps/pearl_svg_height_attack.json.gz differ diff --git a/assets/maps/pearl_svg_height_defense.json.gz b/assets/maps/pearl_svg_height_defense.json.gz index 3d025d0d..34b9842f 100644 Binary files a/assets/maps/pearl_svg_height_defense.json.gz and b/assets/maps/pearl_svg_height_defense.json.gz differ diff --git a/assets/maps/split_svg_height_attack.json.gz b/assets/maps/split_svg_height_attack.json.gz index b94e2374..cc2c98ca 100644 Binary files a/assets/maps/split_svg_height_attack.json.gz and b/assets/maps/split_svg_height_attack.json.gz differ diff --git a/assets/maps/split_svg_height_defense.json.gz b/assets/maps/split_svg_height_defense.json.gz index fb6f9427..99ec7477 100644 Binary files a/assets/maps/split_svg_height_defense.json.gz and b/assets/maps/split_svg_height_defense.json.gz differ diff --git a/assets/maps/summit_svg_height_attack.json.gz b/assets/maps/summit_svg_height_attack.json.gz index 30f64588..dff944fb 100644 Binary files a/assets/maps/summit_svg_height_attack.json.gz and b/assets/maps/summit_svg_height_attack.json.gz differ diff --git a/assets/maps/summit_svg_height_defense.json.gz b/assets/maps/summit_svg_height_defense.json.gz index 83803526..b9674460 100644 Binary files a/assets/maps/summit_svg_height_defense.json.gz and b/assets/maps/summit_svg_height_defense.json.gz differ diff --git a/assets/maps/sunset_svg_height_attack.json.gz b/assets/maps/sunset_svg_height_attack.json.gz index 1693c46c..0fe7758a 100644 Binary files a/assets/maps/sunset_svg_height_attack.json.gz and b/assets/maps/sunset_svg_height_attack.json.gz differ diff --git a/assets/maps/sunset_svg_height_defense.json.gz b/assets/maps/sunset_svg_height_defense.json.gz index c42cca61..5e467e30 100644 Binary files a/assets/maps/sunset_svg_height_defense.json.gz and b/assets/maps/sunset_svg_height_defense.json.gz differ diff --git a/docs/vision-model.md b/docs/vision-model.md index f780a87f..df8ad46f 100644 --- a/docs/vision-model.md +++ b/docs/vision-model.md @@ -845,5 +845,47 @@ Checked on 2026-10-05: * Native, over the same grid: p99 from 3.5 ms to 1.6 ms, p50 from 0.26 ms to 0.18 ms. -The slowest cones left are full circles in open areas such as Breeze mid, -where the visible outline itself has some 2,800 corners. +The slowest cones left were full circles in open areas such as Breeze mid, +where the visible outline itself had some 2,800 corners. Most of those +corners were on traced curves; see the next section. + +## Curves drawn with the points they need (2026-10-07) + +A cone pays for every corner it can see, about 1.3 µs each natively, and the +curved walls were traced with a point every 0.03 units or so: the round wall +in Breeze mid was nearly a thousand points on a circle of radius 9, all within +0.008 of it. Summit, Pearl and Breeze drew 84–89% of their wall segments +shorter than 0.1 units. + +`scripts/riot/simplify_walls.py` in the archive now runs after `build_art.py`. +A wall is redrawn only when simplifying at least halves its points and saves +at least 16, which picks out the traced curves (about 20 walls on each of the +heavy maps; none on Abyss or Ascent attack). A redrawn wall is simplified to +within 0.005 units and grown by 0.005, with mitres past right angles +bevelled, so: + +* it covers every edge it had, so any ray the old wall stopped, it stops: no + new leaks, and no crack can open between two walls; +* no point of its outline is more than 0.01 units from the old wall (the + whole outline is checked, not just its corners); +* its heights, floor and id are unchanged. + +A wall that would miss one of its old edges or stray further is kept as it +was, as is a wall drawn nonzero with more than one ring (none are today). +Wall points fall from 25,563 to 5,409 on Summit attack, 17,707 to 4,024 on +Pearl attack and 13,500 to 4,273 on Breeze attack. + +Checked on 2026-10-07 against the previous models, the 360° cut from every +standable spot on an 8-unit grid over all 26 map sides (33,000 spots), each +compared along 20,000 directions: + +* No direction on any map sees farther than before. +* At most 0.045% of directions on any map side see less (by more than 0.25 + units). The largest change at any spot is a 4.5° sliver on Lotus attack + that now ends 0.1 units from the eye instead of 1.1. +* Native, worst 1% of 360° cuts: Pearl attack 3.8 → 0.8 ms, Summit attack + 3.1 → 1.0 ms, Breeze defense 2.9 → 0.8 ms. Maps without traced curves are + unchanged. +* Dart (the query the web runs, timed in the test VM), worst 1% of 103° + cones: Pearl attack + 8.7 → 0.7 ms, Breeze defense 4.4 → 0.8 ms, Summit defense 4.4 → 0.7 ms. diff --git a/test/bundled_map_models_test.dart b/test/bundled_map_models_test.dart index f97176ca..c1a294a1 100644 --- a/test/bundled_map_models_test.dart +++ b/test/bundled_map_models_test.dart @@ -5,8 +5,9 @@ import 'package:flutter_test/flutter_test.dart'; /// The bundled SVG-height models are Icarus's drawn walls carrying the /// heights of VALORANT's minimap vision lines (see docs/vision-model.md). The -/// builder and the vision-line review data live in the icarus-vision-pipeline -/// archive (scripts/riot, tools/vision-lines). Here the models are pinned +/// builder (scripts/riot/build_art.py, then simplify_walls.py) and the +/// vision-line review data live in the icarus-vision-pipeline archive +/// (scripts/riot, tools/vision-lines). Here the models are pinned /// byte for byte: /// a change to any of them is a change to what players see and must come /// with a deliberate update to this table. @@ -18,51 +19,51 @@ const _modelChecksums = { 'ascent_svg_height_attack.json.gz': '00530c60076b564b3ac5020d983de60d1554fdc3e12f97d137b49f9932ba42cb', 'ascent_svg_height_defense.json.gz': - 'e25313890e098d5bef86fa094f512483c82e0fb166074f80d3081dece976a2a7', + 'ff1e5cceeb5de9508b7f3d21e4bbd9f52df925293e86a863e6128e51c74d9ed9', 'bind_svg_height_attack.json.gz': - 'ae27a16a23fbdf5b44ca050c16b1f89a03bea4113efad1da1d95e3c5b08111ba', + '3682c493e305d3ef9d379b42669dedad772dec9297d5cfede79f686281ff0518', 'bind_svg_height_defense.json.gz': - '8c6d2611c88518e900fc59c5bc7ba0f1fea15c1e0491ad0b4618a64286515af3', + 'c3190df7b4e5c794b7d7e9724fdf25c7273c19dc5f893d3bbff0638dda48a1c5', 'breeze_svg_height_attack.json.gz': - 'afa3dbbe0a741ad3bb9df699deed3fbdfe07764be5136ab07735f456786b996b', + 'e8a91f798da33ffae3c70a8f3a684450ad93bab8d77001f5257d0e3f8f645ab6', 'breeze_svg_height_defense.json.gz': - 'c744d6bb946abd1ed233a6cc0bb214dc5ff42317941128f0b6edb4b953d9f6ee', + '13e8e1e1b4b7c91e80a7a4c8f8ea1994d38272a5639c5a8096d14fcdf68116d1', 'corrode_svg_height_attack.json.gz': - '467fc710f8912b81ae31403fc144cf94730891e87b9bd57dd07f5f1076b0415d', + '7cb371eda6449d9ae0942352436b37bd6084d2618af00d06567677daa0a7a96c', 'corrode_svg_height_defense.json.gz': - '32b41d8de237a8788b65ec655339310b5f14f4baa37c2468c7a82f1cb0acf136', + 'a3b7204fa23b62445af09bdb53907410c400bc1a351faf70c5d7af939ec88781', 'fracture_svg_height_attack.json.gz': - '181776c0bfc042d3901367f9e1db8276f2c5d8f57b4fd5cc575b3cdb815c7b9b', + '187662474f144b49b8c8bfa82ec20a94dc5922f1dcdb100b2860b87787fffcd1', 'fracture_svg_height_defense.json.gz': - '04f40b1d132e21a783106fadb3ec604309318da0491f664121a0d122b6202f52', + 'd1dea3de3dc3b78f735c6d3d23d5f75cdcae1de02d419d382f74c92b13688c18', 'haven_svg_height_attack.json.gz': - '43529cc5731df622df66c7d05205fb149bb36ae0d14e7940a1e83af0a1535ecf', + '774fa91440c7a17244b7a05abc44298b1637c1b7b37e39cbf0a4d89c5e0c6b4a', 'haven_svg_height_defense.json.gz': - 'b4fb1b072f0de7c8d78141ea1227befe60c4dfc61234fdb6e6c54585ec0c24ee', + 'c9805ab93858c83eb65526fa27ca049189fec33348eff56d7d97c98355a4bf25', 'icebox_svg_height_attack.json.gz': - '5755af829f1ef568fa8c8cc49256d431e987b8dc020f227be83d8644dfa9f22d', + '1bb664441d29df5ef6c068dfd3492aab6a86b953645ace1f0be75f7bb57776a6', 'icebox_svg_height_defense.json.gz': - 'e1feb443b83915f362db96df9644274f3f8abb9636b39b359c4b14e3004373aa', + 'b12626026a08250430a60555875ce1c7217e1fcbac2221c652f509fb3056b6da', 'lotus_svg_height_attack.json.gz': - 'e0246d2298948c97cb1b14a7e3a78c37639364781746d85246f3326d88e646e7', + '6794bebee6f8d9f84aa5934b1fb286b5aa8600d0821286428a43ab9d5ada7ad1', 'lotus_svg_height_defense.json.gz': - 'ba349690b50fa9101bd78534e1ed70e36e0b4e3976276257d167243d6e000d15', + '119c82aa47f99274734382cb6122d97f68bb2221d949174302d289704b7f88d4', 'pearl_svg_height_attack.json.gz': - '9b1e1751375c4f350221632a1218a6d82b468dc99cd3a73c4c9e444d46624011', + 'bc5fc05e3336238ddcd94290389f5eb58fffe70e0f6c5f7ee242f6fb173b27f0', 'pearl_svg_height_defense.json.gz': - '64c06641fe30e66cdbee3e4e5cbbeb230ac817a797be1c0c5255f5f6a52d2121', + '0bc5e6e4f3c1bc1dcd0722784e24eb3b8df8ad3b62fdaab061a11f2274429eba', 'split_svg_height_attack.json.gz': - 'a532f2815c1d570727063c6e07bd776228ea745b015990f1411a437244d49287', + '15d8da7276311ea0c3ba090cdb87380000c457888640279988b515db0e1cab28', 'split_svg_height_defense.json.gz': - 'd2c33e89e929919a07522b562825cc4d529ebf0a5d82e751df1c99b471e5e0c0', + '77b1f0ce8d97dea046666761192a29a3db8b6f78a5b8453436ee7204867c1e3d', 'summit_svg_height_attack.json.gz': - '30e0894932abde8134fa477edb41885cde316637ca548d2bc701fd191e8d70b0', + '5a5f5f74abbe6e3819c409892974386eecccd806a609698b054cf665284e0098', 'summit_svg_height_defense.json.gz': - 'd9499a88a76fb73f31d818a1c28e200687a662df71827aa133f0bb56b908b876', + '44ce26d9371526823526ca9bf8c8d94e27b2930574fe3de9681b6e66cd30189c', 'sunset_svg_height_attack.json.gz': - '012f38f95f49df79c81896685e899de4408147fb367e178954d34c6c4e3842f4', + '16cdd31bc3b8a9af9f7e0b0c15d7a0e6d82913d3e32e11e07f460b6458db1356', 'sunset_svg_height_defense.json.gz': - '86f9c66c4670ba1dc7859e2a71f0ac7c58929e63d900d68e720cb304747780b6', + '733dcb7cdad19541c65b60419f161789ca0c9e5937ebb371a9f804852c9c7ba1', }; void main() { diff --git a/test/svg_riot_vision_test.dart b/test/svg_riot_vision_test.dart index 87f1a9c8..d12226a4 100644 --- a/test/svg_riot_vision_test.dart +++ b/test/svg_riot_vision_test.dart @@ -94,7 +94,10 @@ void main() { test('a hole in a wall stays floor', () { // Haven's p5-stroke-10 is drawn even-odd with floor inside it. final model = _model('haven', 'attack'); - expect(model.receiverContains(const Offset(198.4425, 184.726)), isTrue); + const inHole = Offset(198.4425, 184.726); + expect(model.receiverContains(inHole), isTrue); + // No wall reaches into it: an agent placed there stays where it is. + expect(model.standablePointNear(inHole), inHole); }); test('a drawn ring by a wall does not slice a cone into slivers', () {