nmarshall commited on
Commit
dcdd22a
·
1 Parent(s): f00861b

gameplay: integrate lazy camera collision queries

Browse files
crates/urt-gameplay/src/bin/urt-camera-world.rs CHANGED
@@ -503,6 +503,165 @@ fn run() -> Result<String, String> {
503
  array(&out.view.angles)
504
  ))
505
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
506
  _ => Err("unknown command".into()),
507
  }
508
  }
 
503
  array(&out.view.angles)
504
  ))
505
  }
506
+ "queried-camera" => {
507
+ if w.len() < 9 || w[1] > 1 || w[2] > 1024 {
508
+ return Err("invalid camera header".into());
509
+ }
510
+ let mut state = w[0];
511
+ let slot = w[1] as usize;
512
+ let n = w[2] as usize;
513
+ let _fallback = urt_gameplay::transition::View {
514
+ origin: w[3..6].try_into().unwrap(),
515
+ angles: w[6..9].try_into().unwrap(),
516
+ };
517
+ let mut p = 9;
518
+ let mut world = vec![];
519
+ for _ in 0..n {
520
+ let v = w.get(p..p + 9).ok_or("missing world record")?;
521
+ p += 9;
522
+ let class = HashEntity {
523
+ in_use: v[0] as i32,
524
+ class_present: v[1] != 0,
525
+ class_hash: v[2],
526
+ };
527
+ let origin = v[3..6].try_into().unwrap();
528
+ let angles = v[6..9].try_into().unwrap();
529
+ let aim = blob(&w, &mut p)?;
530
+ let label = blob(&w, &mut p)?;
531
+ world.push(WorldEntity {
532
+ class,
533
+ origin,
534
+ angles,
535
+ aim,
536
+ label,
537
+ });
538
+ }
539
+ let blocked = w
540
+ .get(p..p + n)
541
+ .ok_or("missing telefrag flags")?
542
+ .iter()
543
+ .map(|v| *v != 0)
544
+ .collect::<Vec<_>>();
545
+ p += n;
546
+ let bound_words = w.get(p..p + 6).ok_or("missing query bounds")?;
547
+ p += 6;
548
+ let bounds = std::array::from_fn(|h| {
549
+ std::array::from_fn(|j| f32::from_bits(bound_words[h * 3 + j]))
550
+ });
551
+ let mut queries = vec![];
552
+ let mut client_words = vec![0; 1024];
553
+ client_words[901] = u32::MAX;
554
+ let mut math = math_calls(&w, &mut p)?;
555
+ if p != w.len() {
556
+ return Err("trailing camera words".into());
557
+ }
558
+ let mut entity = urt_gameplay::transition::CameraEntity {
559
+ origin: [0x12345678; 3],
560
+ clear: [0x12345678; 6],
561
+ };
562
+ let blank = urt_gameplay::transition::CameraPlayer {
563
+ movement: 0xaabbccdd,
564
+ origin: [0xaabbccdd; 3],
565
+ velocity: [0xaabbccdd; 3],
566
+ field104: 0xaabbccdd,
567
+ angles: [0xaabbccdd; 3],
568
+ mode3108: 0xaabbccdd,
569
+ field4324: 0xaabbccdd,
570
+ };
571
+ let mut clients = [blank.clone(), blank];
572
+ let (out, spawn) = configure_camera_queried(
573
+ &world,
574
+ &mut state,
575
+ &mut math,
576
+ &mut entity,
577
+ &mut clients[slot],
578
+ SpawnQueryWorld {
579
+ bounds,
580
+ client_words: &client_words,
581
+ },
582
+ |j, b| {
583
+ let indices = query_results(j, if blocked[j] { 2 } else { 0 });
584
+ queries.push(query_json(j, b, &indices));
585
+ Ok(indices)
586
+ },
587
+ )
588
+ .map_err(|e| format!("{e:?}"))?;
589
+ math.finish().map_err(|e| format!("{e:?}"))?;
590
+ let e = word_object(
591
+ &[4, 8, 92, 96, 100, 156, 160, 180, 460],
592
+ &[
593
+ entity.clear[0],
594
+ entity.clear[1],
595
+ entity.origin[0],
596
+ entity.origin[1],
597
+ entity.origin[2],
598
+ entity.clear[2],
599
+ entity.clear[3],
600
+ entity.clear[4],
601
+ entity.clear[5],
602
+ ],
603
+ );
604
+ let clients = clients
605
+ .iter()
606
+ .map(|p| {
607
+ word_object(
608
+ &[4, 20, 24, 28, 32, 36, 40, 104, 152, 156, 160, 3108, 4324],
609
+ &[
610
+ p.movement,
611
+ p.origin[0],
612
+ p.origin[1],
613
+ p.origin[2],
614
+ p.velocity[0],
615
+ p.velocity[1],
616
+ p.velocity[2],
617
+ p.field104,
618
+ p.angles[0],
619
+ p.angles[1],
620
+ p.angles[2],
621
+ p.mode3108,
622
+ p.field4324,
623
+ ],
624
+ )
625
+ })
626
+ .collect::<Vec<_>>()
627
+ .join(",");
628
+ let effects = out
629
+ .effects
630
+ .iter()
631
+ .map(|e| match e {
632
+ CameraEffect::FindClass => 276433,
633
+ CameraEffect::Fallback => 168114,
634
+ CameraEffect::PickTarget => 276586,
635
+ CameraEffect::Angles => 62944,
636
+ })
637
+ .collect::<Vec<_>>();
638
+ let matches = out.matches.iter().map(|j| *j as u32).collect::<Vec<_>>();
639
+ let diagnostic = match out.diagnostic {
640
+ None => "null",
641
+ Some(TargetDiagnostic::Null) => "\"null\"",
642
+ Some(TargetDiagnostic::Missing) => "\"missing\"",
643
+ };
644
+ let spawn_index = spawn.as_ref().map(|v| v.index as i32).unwrap_or(-1);
645
+ let spawn_candidates = array(
646
+ &spawn
647
+ .as_ref()
648
+ .map(|v| v.candidates.iter().map(|j| *j as u32).collect::<Vec<_>>())
649
+ .unwrap_or_default(),
650
+ );
651
+ let payload = format!(
652
+ "{{\"spawn_index\":{spawn_index},\"spawn_candidates\":{spawn_candidates},\"class_index\":{},\"target_index\":{},\"rng_state\":{state},\"matches\":{},\"diagnostic\":{diagnostic},\"effects\":{},\"view\":{{\"origin\":{},\"angles\":{}}},\"entity\":{e},\"clients\":[{clients}]}}",
653
+ out.class_index.map(|j| j as i32).unwrap_or(-1),
654
+ out.target_index.map(|j| j as i32).unwrap_or(-1),
655
+ array(&matches),
656
+ array(&effects),
657
+ array(&out.view.origin),
658
+ array(&out.view.angles)
659
+ );
660
+ Ok(format!(
661
+ "{{\"camera\":{payload},\"queries\":[{}]}}",
662
+ queries.join(",")
663
+ ))
664
+ }
665
  _ => Err("unknown command".into()),
666
  }
667
  }
crates/urt-gameplay/src/camera_world.rs CHANGED
@@ -737,6 +737,19 @@ pub fn configure_camera_with_spawns<M: AngleMath>(
737
  if blocked.len() != world.len() {
738
  return Err(Error::InvalidCount);
739
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
740
  let classes = world.iter().map(|e| e.class).collect::<Vec<_>>();
741
  if find_class(&classes, world.len(), None, (-2104846030i32) as u32)?.is_some() {
742
  return Ok((
@@ -756,15 +769,14 @@ pub fn configure_camera_with_spawns<M: AngleMath>(
756
  }
757
  let spawns = world
758
  .iter()
759
- .zip(blocked)
760
- .map(|(e, b)| SpawnEntity {
761
  class: e.class,
762
- blocked: *b,
763
  origin: e.origin,
764
  angles: e.angles,
765
  })
766
  .collect::<Vec<_>>();
767
- let selected = fallback_spawn(&spawns, [0; 3], state, math)?;
768
  let camera = CameraResolution {
769
  class_index: None,
770
  target_index: None,
@@ -952,3 +964,73 @@ mod query_spawn_tests {
952
  assert_eq!(state, 7);
953
  }
954
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
737
  if blocked.len() != world.len() {
738
  return Err(Error::InvalidCount);
739
  }
740
+ configure_camera_with_spawn_check(world, state, math, entity, player, |j, _| Ok(blocked[j]))
741
+ }
742
+ pub fn configure_camera_with_spawn_check<
743
+ M: AngleMath,
744
+ F: FnMut(usize, &SpawnEntity) -> Result<bool, Error>,
745
+ >(
746
+ world: &[WorldEntity],
747
+ state: &mut u32,
748
+ math: &mut M,
749
+ entity: &mut crate::transition::CameraEntity,
750
+ player: &mut crate::transition::CameraPlayer,
751
+ mut check: F,
752
+ ) -> Result<(CameraResolution, Option<SpawnSelection>), Error> {
753
  let classes = world.iter().map(|e| e.class).collect::<Vec<_>>();
754
  if find_class(&classes, world.len(), None, (-2104846030i32) as u32)?.is_some() {
755
  return Ok((
 
769
  }
770
  let spawns = world
771
  .iter()
772
+ .map(|e| SpawnEntity {
 
773
  class: e.class,
774
+ blocked: false,
775
  origin: e.origin,
776
  angles: e.angles,
777
  })
778
  .collect::<Vec<_>>();
779
+ let selected = fallback_spawn_with_check(&spawns, [0; 3], state, math, &mut check)?;
780
  let camera = CameraResolution {
781
  class_index: None,
782
  target_index: None,
 
964
  assert_eq!(state, 7);
965
  }
966
  }
967
+
968
+ pub fn configure_camera_queried<
969
+ M: AngleMath,
970
+ F: FnMut(usize, crate::native_policy::SpawnBox) -> Result<Vec<usize>, Error>,
971
+ >(
972
+ world: &[WorldEntity],
973
+ state: &mut u32,
974
+ math: &mut M,
975
+ entity: &mut crate::transition::CameraEntity,
976
+ player: &mut crate::transition::CameraPlayer,
977
+ scene: SpawnQueryWorld<'_>,
978
+ mut query: F,
979
+ ) -> Result<(CameraResolution, Option<SpawnSelection>), Error> {
980
+ configure_camera_with_spawn_check(world, state, math, entity, player, |j, e| {
981
+ overlap_check(j, e, scene, &mut query)
982
+ })
983
+ }
984
+ #[cfg(test)]
985
+ mod queried_camera_tests {
986
+ use super::*;
987
+ #[test]
988
+ fn primary_camera_never_queries() {
989
+ let world = [WorldEntity {
990
+ class: HashEntity {
991
+ in_use: 1,
992
+ class_present: true,
993
+ class_hash: (-2104846030i32) as u32,
994
+ },
995
+ origin: [0; 3],
996
+ angles: [0; 3],
997
+ aim: None,
998
+ label: None,
999
+ }];
1000
+ let mut rng = 7;
1001
+ let mut e = crate::transition::CameraEntity {
1002
+ origin: [8; 3],
1003
+ clear: [9; 6],
1004
+ };
1005
+ let mut p = crate::transition::CameraPlayer {
1006
+ movement: 7,
1007
+ origin: [7; 3],
1008
+ velocity: [7; 3],
1009
+ field104: 7,
1010
+ angles: [7; 3],
1011
+ mode3108: 7,
1012
+ field4324: 7,
1013
+ };
1014
+ let mut called = false;
1015
+ let (_, spawn) = configure_camera_queried(
1016
+ &world,
1017
+ &mut rng,
1018
+ &mut HostMath,
1019
+ &mut e,
1020
+ &mut p,
1021
+ SpawnQueryWorld {
1022
+ bounds: [[f32::NAN; 3]; 2],
1023
+ client_words: &[],
1024
+ },
1025
+ |_, _| {
1026
+ called = true;
1027
+ Err(Error::InvalidCount)
1028
+ },
1029
+ )
1030
+ .unwrap();
1031
+ assert!(!called);
1032
+ assert!(spawn.is_none());
1033
+ assert_eq!(rng, 7);
1034
+ assert_eq!(e.origin, [0; 3]);
1035
+ }
1036
+ }
docs/FINDINGS.md CHANGED
@@ -1658,3 +1658,6 @@ RE-813–822 replaces the scoreboard decimal assumption with actual37914 executi
1658
 
1659
 
1660
  **RE-886:** 128 coherent6717/168114/167638/6575 cases execute box construction and client filtering inside camera fallback. Existing primary cameras issue no spatial queries; fallback class matches issue ordered native -33 requests. Result/view/player fields and checked math match the prior boolean-boundary fixtures. Native broadphase and math remain supplied; respawn and complete intermission/runtime remain open. [Evidence](research/QVM_QUERIED_CAMERA.md).
 
 
 
 
1658
 
1659
 
1660
  **RE-886:** 128 coherent6717/168114/167638/6575 cases execute box construction and client filtering inside camera fallback. Existing primary cameras issue no spatial queries; fallback class matches issue ordered native -33 requests. Result/view/player fields and checked math match the prior boolean-boundary fixtures. Native broadphase and math remain supplied; respawn and complete intermission/runtime remain open. [Evidence](research/QVM_QUERIED_CAMERA.md).
1661
+
1662
+
1663
+ **RE-887:** Rust matches128 original continuous camera/queried-fallback/placement cases, including exact query order and primary-camera bypass. Spatial callbacks use the same recovered box/filter policy as standalone fallback. Existing camera/spawn APIs retain their contracts; native broadphase/math and complete respawn/intermission remain open. [Evidence](research/RUST_QUERIED_CAMERA.md).
docs/PROVISIONAL_TODO.md CHANGED
@@ -1689,3 +1689,6 @@ RE-885: Rust matches64 original168114/167638 compositions and their ordered box
1689
 
1690
 
1691
  RE-886: 128 coherent6717/168114/167638/6575 cases execute box construction and client filtering inside camera fallback. Existing primary cameras issue no spatial queries; fallback class matches issue ordered native -33 requests. Result/view/player fields and checked math match the prior boolean-boundary fixtures. Native broadphase and math remain supplied; respawn and complete intermission/runtime remain open. Full runtime completion remains open. [Evidence](research/QVM_QUERIED_CAMERA.md).
 
 
 
 
1689
 
1690
 
1691
  RE-886: 128 coherent6717/168114/167638/6575 cases execute box construction and client filtering inside camera fallback. Existing primary cameras issue no spatial queries; fallback class matches issue ordered native -33 requests. Result/view/player fields and checked math match the prior boolean-boundary fixtures. Native broadphase and math remain supplied; respawn and complete intermission/runtime remain open. Full runtime completion remains open. [Evidence](research/QVM_QUERIED_CAMERA.md).
1692
+
1693
+
1694
+ RE-887: Rust matches128 original continuous camera/queried-fallback/placement cases, including exact query order and primary-camera bypass. Spatial callbacks use the same recovered box/filter policy as standalone fallback. Existing camera/spawn APIs retain their contracts; native broadphase/math and complete respawn/intermission remain open. Full runtime completion remains open. [Evidence](research/RUST_QUERIED_CAMERA.md).
docs/RESEARCH_LEDGER.md CHANGED
@@ -2140,3 +2140,8 @@ Rust matches64 original168114/167638 compositions and their ordered box query tr
2140
  ## 2026-10-28 — RE-886 Original camera placement with queried fallback
2141
 
2142
  128 coherent6717/168114/167638/6575 cases execute box construction and client filtering inside camera fallback. Existing primary cameras issue no spatial queries; fallback class matches issue ordered native -33 requests. Result/view/player fields and checked math match the prior boolean-boundary fixtures. Native broadphase and math remain supplied; respawn and complete intermission/runtime remain open. Focused `cargo xtask test-group qvm-queried-camera` passes (4 Python tests); selected reports regenerate twice deterministically, with storage, documentation links and whitespace guards. Full suite deferred to task ten. Original assets unchanged; source fixtures do not establish complete native/runtime parity.
 
 
 
 
 
 
2140
  ## 2026-10-28 — RE-886 Original camera placement with queried fallback
2141
 
2142
  128 coherent6717/168114/167638/6575 cases execute box construction and client filtering inside camera fallback. Existing primary cameras issue no spatial queries; fallback class matches issue ordered native -33 requests. Result/view/player fields and checked math match the prior boolean-boundary fixtures. Native broadphase and math remain supplied; respawn and complete intermission/runtime remain open. Focused `cargo xtask test-group qvm-queried-camera` passes (4 Python tests); selected reports regenerate twice deterministically, with storage, documentation links and whitespace guards. Full suite deferred to task ten. Original assets unchanged; source fixtures do not establish complete native/runtime parity.
2143
+
2144
+
2145
+ ## 2026-10-28 — RE-887 Rust camera with lazy spatial queries
2146
+
2147
+ Rust matches128 original continuous camera/queried-fallback/placement cases, including exact query order and primary-camera bypass. Spatial callbacks use the same recovered box/filter policy as standalone fallback. Existing camera/spawn APIs retain their contracts; native broadphase/math and complete respawn/intermission remain open. Focused `cargo xtask test-group rust-queried-camera` passes (13 Python tests); selected reports regenerate twice deterministically, with storage, documentation links and whitespace guards. Full suite deferred to task ten. Original assets unchanged; source fixtures do not establish complete native/runtime parity.
docs/REVERSE_ENGINEERING_TODO.md CHANGED
@@ -1726,3 +1726,6 @@ Purpose: turn the supplied installation into an evidence-backed specification of
1726
 
1727
 
1728
  - [x] RE-886 Original camera placement with queried fallback ([evidence](research/QVM_QUERIED_CAMERA.md)).
 
 
 
 
1726
 
1727
 
1728
  - [x] RE-886 Original camera placement with queried fallback ([evidence](research/QVM_QUERIED_CAMERA.md)).
1729
+
1730
+
1731
+ - [x] RE-887 Rust camera with lazy spatial queries ([evidence](research/RUST_QUERIED_CAMERA.md)).
docs/research/README.md CHANGED
@@ -1261,3 +1261,6 @@ The extension collector adds five focused tests for native tail calls, command-r
1261
 
1262
 
1263
  [RE-886: Original camera placement with queried fallback](QVM_QUERIED_CAMERA.md).
 
 
 
 
1261
 
1262
 
1263
  [RE-886: Original camera placement with queried fallback](QVM_QUERIED_CAMERA.md).
1264
+
1265
+
1266
+ [RE-887: Rust camera with lazy spatial queries](RUST_QUERIED_CAMERA.md).
docs/research/RUST_QUERIED_CAMERA.md ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
 
1
+ # Rust camera with lazy spatial queries
2
+
3
+ RE-887. Reproduce with `python3 scripts/analyze_rust_queried_camera.py`; focused validation: `cargo xtask test-group rust-queried-camera`. [Machine report](rust-queried-camera.json).
4
+
5
+ Rust matches128 original continuous camera/queried-fallback/placement cases, including exact query order and primary-camera bypass. Spatial callbacks use the same recovered box/filter policy as standalone fallback. Existing camera/spawn APIs retain their contracts; native broadphase/math and complete respawn/intermission remain open.
6
+
7
+ Original executable/native runtime and complete Linux/macOS Rust/Bevy/Solari acceptance remain unverified.
docs/research/rust-health-impulse.json CHANGED
@@ -2985,7 +2985,7 @@
2985
  "exit_code": 2
2986
  }
2987
  ],
2988
- "rust_unit_tests": 142,
2989
  "source_report": "docs/research/qvm-health-impulse.json",
2990
  "source_report_sha256": "625fd8064004ea6dbdf398d51d0af844d9c635ff04c0a0790886dddb6ab81e71"
2991
  }
 
2985
  "exit_code": 2
2986
  }
2987
  ],
2988
+ "rust_unit_tests": 143,
2989
  "source_report": "docs/research/qvm-health-impulse.json",
2990
  "source_report_sha256": "625fd8064004ea6dbdf398d51d0af844d9c635ff04c0a0790886dddb6ab81e71"
2991
  }
docs/research/rust-queried-camera.json ADDED
The diff for this file is too large to render. See raw diff
 
scripts/analyze_rust_queried_camera.py ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python3
2
+ import hashlib,json
3
+ from pathlib import Path
4
+ from rust_camera_world_support import binary,result,invoke
5
+ from analyze_qvm import write_json
6
+ from analyze_rust_camera_spawn import encode as old_encode,project as old_project
7
+ def encode(s):
8
+ out=old_encode(s);pos=len(out)-1-4*len(s['math']);out[pos:pos]=s['bounds'];return out
9
+ def project(s):return {'camera':old_project(s),'queries':[{k:v for k,v in q.items() if k!='trace_sha256'} for q in s['queries']]}
10
+
11
+ def main():
12
+ b=binary();p=Path('docs/research/qvm-queried-camera.json');data=p.read_bytes();rows=[]
13
+ for s in json.loads(data)['probes']:rows.append({'source':project(s),'rust':result(b,'queried-camera',encode(s))})
14
+ write_json(Path('docs/research/rust-queried-camera.json'),{'source_report':str(p),'source_report_sha256':hashlib.sha256(data).hexdigest(),'probes':rows,'limits':'Rust matches128 original continuous camera/queried-fallback/placement cases, including exact query order and primary-camera bypass. Spatial callbacks use the same recovered box/filter policy as standalone fallback. Existing camera/spawn APIs retain their contracts; native broadphase/math and complete respawn/intermission remain open.'})
15
+ if __name__=='__main__':main()
scripts/test_rust_queried_camera.py ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
 
1
+ import hashlib,json,unittest
2
+ from pathlib import Path
3
+ class PortTests(unittest.TestCase):
4
+ def test_all_original_cases(self):
5
+ r=json.loads(Path('docs/research/rust-queried-camera.json').read_text());src=json.loads(Path(r['source_report']).read_text());self.assertEqual(len(r['probes']),len(src['probes']));self.assertGreater(len(r['probes']),20)
6
+ for p in r['probes']:self.assertEqual(p['rust'],p['source'])
7
+ def test_source_identity(self):
8
+ r=json.loads(Path('docs/research/rust-queried-camera.json').read_text());self.assertEqual(hashlib.sha256(Path(r['source_report']).read_bytes()).hexdigest(),r['source_report_sha256'])
9
+ if __name__=='__main__':unittest.main()
xtask/checks.tsv CHANGED
@@ -2632,3 +2632,19 @@ report scripts/analyze_qvm_queried_camera.py docs/research/qvm-queried-camera.js
2632
  edge docs/research/qvm-queried-camera.json scripts/test_qvm_queried_camera.py
2633
  group qvm-queried-camera scripts/analyze_qvm_queried_camera.py
2634
  edge scripts/analyze_qvm_queried_camera.py scripts/analyze_qvm_resumer_audit.py
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2632
  edge docs/research/qvm-queried-camera.json scripts/test_qvm_queried_camera.py
2633
  group qvm-queried-camera scripts/analyze_qvm_queried_camera.py
2634
  edge scripts/analyze_qvm_queried_camera.py scripts/analyze_qvm_resumer_audit.py
2635
+ edge Cargo.toml scripts/analyze_rust_queried_camera.py
2636
+ edge Cargo.lock scripts/analyze_rust_queried_camera.py
2637
+ edge crates/urt-gameplay/Cargo.toml scripts/analyze_rust_queried_camera.py
2638
+ edge crates/urt-gameplay/src/lib.rs scripts/analyze_rust_queried_camera.py
2639
+ edge crates/urt-gameplay/src/camera_world.rs scripts/analyze_rust_queried_camera.py
2640
+ edge crates/urt-gameplay/src/bin/urt-camera-world.rs scripts/analyze_rust_queried_camera.py
2641
+ edge docs/research/qvm-queried-camera.json scripts/analyze_rust_queried_camera.py
2642
+ group rust-queried-camera scripts/analyze_rust_health_impulse.py
2643
+ group gameplay scripts/analyze_rust_queried_camera.py
2644
+ edge crates/urt-gameplay/src/native_policy.rs scripts/analyze_rust_queried_camera.py
2645
+ group rust-queried-camera scripts/analyze_rust_camera_spawn.py
2646
+ group rust-queried-camera scripts/analyze_rust_camera_world.py
2647
+ report scripts/analyze_rust_queried_camera.py docs/research/rust-queried-camera.json
2648
+ edge docs/research/rust-queried-camera.json scripts/test_rust_queried_camera.py
2649
+ group rust-queried-camera scripts/analyze_rust_queried_camera.py
2650
+ edge scripts/analyze_rust_queried_camera.py scripts/analyze_qvm_resumer_audit.py