Removing Lighting Walk Tables
?
?

Keyboard Navigation

Global Keys

[, < / ], > Jump to previous / next episode
W, K, P / S, J, N Jump to previous / next timestamp
t / T Toggle theatre / SUPERtheatre mode
V Revert filter to original state Y Select link (requires manual Ctrl-c)

Menu toggling

q Quotes r References f Filter y Link c Credits

In-Menu and Index Controls

a
w
s
d
h j k l


Esc Close menu / unfocus timestamp

Quotes and References Menus and Index

Enter Jump to timestamp

Quotes, References and Credits Menus

o Open URL (in new tab)

Filter Menu

x, Space Toggle category and focus next
X, ShiftSpace Toggle category and focus previous
v Invert topics / media as per focus

Filter and Link Menus

z Toggle filter / linking mode

Credits Menu

Enter Open URL (in new tab)
0:02Recap and set the stage for the day debugging lighting
🗩
0:02Recap and set the stage for the day debugging lighting
🗩
0:02Recap and set the stage for the day debugging lighting
🗩
1:03Demo our light bleed bug
🏃
1:03Demo our light bleed bug
🏃
1:03Demo our light bleed bug
🏃
1:45Demo our light copying bug
🏃
1:45Demo our light copying bug
🏃
1:45Demo our light copying bug
🏃
6:00Describe BlockCopyAtlas()
📖
6:00Describe BlockCopyAtlas()
📖
6:00Describe BlockCopyAtlas()
📖
7:09Assert in BlockCopyAtlas() that the Z loop doesn't happen
7:09Assert in BlockCopyAtlas() that the Z loop doesn't happen
7:09Assert in BlockCopyAtlas() that the Z loop doesn't happen
7:50Hit our Z loop assertion in BlockCopyAtlas()
🏃
7:50Hit our Z loop assertion in BlockCopyAtlas()
🏃
7:50Hit our Z loop assertion in BlockCopyAtlas()
🏃
8:49Move our Z loop assertion in BlockCopyAtlas() down to the Z clearing loop
8:49Move our Z loop assertion in BlockCopyAtlas() down to the Z clearing loop
8:49Move our Z loop assertion in BlockCopyAtlas() down to the Z clearing loop
9:11Hit our Z clearing loop assertion in BlockCopyAtlas()
🏃
9:11Hit our Z clearing loop assertion in BlockCopyAtlas()
🏃
9:11Hit our Z clearing loop assertion in BlockCopyAtlas()
🏃
9:45Inspect the BlockCopyAtlas() values in an -Od build
🏃
9:45Inspect the BlockCopyAtlas() values in an -Od build
🏃
9:45Inspect the BlockCopyAtlas() values in an -Od build
🏃
11:26Comment out the Z clearing loop in BlockCopyAtlas()
11:26Comment out the Z clearing loop in BlockCopyAtlas()
11:26Comment out the Z clearing loop in BlockCopyAtlas()
11:51Try to eyeball our light copying bug
🏃
11:51Try to eyeball our light copying bug
🏃
11:51Try to eyeball our light copying bug
🏃
12:14Toggle off DebugDrawSpatialGrid() in UpdateLighting()
12:14Toggle off DebugDrawSpatialGrid() in UpdateLighting()
12:14Toggle off DebugDrawSpatialGrid() in UpdateLighting()
12:44Our light copying / flashing bug seems to still occur
🏃
12:44Our light copying / flashing bug seems to still occur
🏃
12:44Our light copying / flashing bug seems to still occur
🏃
14:47Uncomment the Z clearing loop in BlockCopyAtlas()
14:47Uncomment the Z clearing loop in BlockCopyAtlas()
14:47Uncomment the Z clearing loop in BlockCopyAtlas()
15:14Scour BlockCopyAtlas() for bugs
📖
15:14Scour BlockCopyAtlas() for bugs
📖
15:14Scour BlockCopyAtlas() for bugs
📖
18:07Remove the minus 1 from the StopZ computation in BlockCopyAtlas()
18:07Remove the minus 1 from the StopZ computation in BlockCopyAtlas()
18:07Remove the minus 1 from the StopZ computation in BlockCopyAtlas()
18:35We still see a little bit of flashing
🏃
18:35We still see a little bit of flashing
🏃
18:35We still see a little bit of flashing
🏃
18:54Enable LIGHT_ATLAS_ASSERT
18:54Enable LIGHT_ATLAS_ASSERT
18:54Enable LIGHT_ATLAS_ASSERT
19:25Immediately trap on VALIDATE_TEXEL_ATLAS() of the SpecAtlas
🏃
19:25Immediately trap on VALIDATE_TEXEL_ATLAS() of the SpecAtlas
🏃
19:25Immediately trap on VALIDATE_TEXEL_ATLAS() of the SpecAtlas
🏃
19:35Toggle off the VALIDATE_TEXEL_ATLAS() calls in UpdateLighting()
19:35Toggle off the VALIDATE_TEXEL_ATLAS() calls in UpdateLighting()
19:35Toggle off the VALIDATE_TEXEL_ATLAS() calls in UpdateLighting()
19:47Trap on VALIDATE_TEXEL_ATLAS() in BlockCopyAtlas()
🏃
19:47Trap on VALIDATE_TEXEL_ATLAS() in BlockCopyAtlas()
🏃
19:47Trap on VALIDATE_TEXEL_ATLAS() in BlockCopyAtlas()
🏃
19:54Toggle off the VALIDATE_TEXEL_ATLAS() calls using #if TEMPORARY
19:54Toggle off the VALIDATE_TEXEL_ATLAS() calls using #if TEMPORARY
19:54Toggle off the VALIDATE_TEXEL_ATLAS() calls using #if TEMPORARY
20:19Trap on VALIDATE_TEXEL_ATLAS() at the end of BlockCopyAtlas()
🏃
20:19Trap on VALIDATE_TEXEL_ATLAS() at the end of BlockCopyAtlas()
🏃
20:19Trap on VALIDATE_TEXEL_ATLAS() at the end of BlockCopyAtlas()
🏃
20:29Toggle off the final VALIDATE_TEXEL_ATLAS() call using #if TEMPORARY
20:29Toggle off the final VALIDATE_TEXEL_ATLAS() call using #if TEMPORARY
20:29Toggle off the final VALIDATE_TEXEL_ATLAS() call using #if TEMPORARY
20:43Successfully run without fetching out of bounds
🏃
20:43Successfully run without fetching out of bounds
🏃
20:43Successfully run without fetching out of bounds
🏃
21:02Remove the minus 1 from the StopX and StopY computations in BlockCopyAtlas()
21:02Remove the minus 1 from the StopX and StopY computations in BlockCopyAtlas()
21:02Remove the minus 1 from the StopX and StopY computations in BlockCopyAtlas()
21:22We have lighting movement across tiles
🏃
21:22We have lighting movement across tiles
🏃
21:22We have lighting movement across tiles
🏃
23:25Decrease tUpdateBlend from 1 to 15/60 in UpdateLighting()
23:25Decrease tUpdateBlend from 1 to 15/60 in UpdateLighting()
23:25Decrease tUpdateBlend from 1 to 15/60 in UpdateLighting()
23:49Still see the lighting shift
🏃
23:49Still see the lighting shift
🏃
23:49Still see the lighting shift
🏃
24:13Decrease tUpdateBlend from 15/60 to 1/60 in UpdateLighting()
24:13Decrease tUpdateBlend from 15/60 to 1/60 in UpdateLighting()
24:13Decrease tUpdateBlend from 15/60 to 1/60 in UpdateLighting()
24:29The shift is due to the light being recomputed differently
🏃
24:29The shift is due to the light being recomputed differently
🏃
24:29The shift is due to the light being recomputed differently
🏃
25:22Toggle off the -1 to 1 origin cube in UpdateAndRenderWorld()
25:22Toggle off the -1 to 1 origin cube in UpdateAndRenderWorld()
25:22Toggle off the -1 to 1 origin cube in UpdateAndRenderWorld()
26:59The wall tiles darken after shifting
🏃
26:59The wall tiles darken after shifting
🏃
26:59The wall tiles darken after shifting
🏃
28:07Toggle off PushLight() on the DebugLightP in UpdateAndRenderWorld()
28:07Toggle off PushLight() on the DebugLightP in UpdateAndRenderWorld()
28:07Toggle off PushLight() on the DebugLightP in UpdateAndRenderWorld()
28:26The room still seems to brighten when we enter
🏃
28:26The room still seems to brighten when we enter
🏃
28:26The room still seems to brighten when we enter
🏃
30:18The light bleed takes longer with our slower tUpdateBlend
🏃
30:18The light bleed takes longer with our slower tUpdateBlend
🏃
30:18The light bleed takes longer with our slower tUpdateBlend
🏃
31:01Increase tUpdateBlend from 1/60 to 1 in UpdateLighting()
31:01Increase tUpdateBlend from 1/60 to 1 in UpdateLighting()
31:01Increase tUpdateBlend from 1/60 to 1 in UpdateLighting()
31:50The copy is now fine, but the ray casting differs when shifting the lighting voxel
🏃
31:50The copy is now fine, but the ray casting differs when shifting the lighting voxel
🏃
31:50The copy is now fine, but the ray casting differs when shifting the lighting voxel
🏃
34:12Prevent UpdateLighting() from offsetting VoxCameraOffset.Y by 2
34:12Prevent UpdateLighting() from offsetting VoxCameraOffset.Y by 2
34:12Prevent UpdateLighting() from offsetting VoxCameraOffset.Y by 2
35:03The lighting region is now centred
🏃
35:03The lighting region is now centred
🏃
35:03The lighting region is now centred
🏃
36:38Scour GridRayCast() for a reason for differences when shifting the lighting voxel
📖
36:38Scour GridRayCast() for a reason for differences when shifting the lighting voxel
📖
36:38Scour GridRayCast() for a reason for differences when shifting the lighting voxel
📖
41:16Scour ComputeWalkTable() for bugs
📖
41:16Scour ComputeWalkTable() for bugs
📖
41:16Scour ComputeWalkTable() for bugs
📖
42:40Make WalkTableOffset be an array of 4 in sample_direction, for ComputeWalkTable() to use
42:40Make WalkTableOffset be an array of 4 in sample_direction, for ComputeWalkTable() to use
42:40Make WalkTableOffset be an array of 4 in sample_direction, for ComputeWalkTable() to use
43:12The light doesn't seem to have changed
🏃
43:12The light doesn't seem to have changed
🏃
43:12The light doesn't seem to have changed
🏃
43:58Double-check ComputeWalkTable() for correctness
📖
43:58Double-check ComputeWalkTable() for correctness
📖
43:58Double-check ComputeWalkTable() for correctness
📖
45:16Consider removing lighting walk tables
📖
45:16Consider removing lighting walk tables
📖
45:16Consider removing lighting walk tables
📖
46:56The ray casting still differs when shifting the lighting voxel
🏃
46:56The ray casting still differs when shifting the lighting voxel
🏃
46:56The ray casting still differs when shifting the lighting voxel
🏃
47:27Consider making UpdateLighting() force dVoxel to be a multiple of 2 so the quadrant doesn't change
📖
47:27Consider making UpdateLighting() force dVoxel to be a multiple of 2 so the quadrant doesn't change
📖
47:27Consider making UpdateLighting() force dVoxel to be a multiple of 2 so the quadrant doesn't change
📖
48:32gir33 The problem changed, though, there's still a dark spot but it doesn't move now
🗪
48:32gir33 The problem changed, though, there's still a dark spot but it doesn't move now
🗪
48:32gir33 The problem changed, though, there's still a dark spot but it doesn't move now
🗪
48:51Demo the moving dark spot
🏃
48:51Demo the moving dark spot
🏃
48:51Demo the moving dark spot
🏃
49:46gir33 I mean it seems like it only moved when leaving the room but not while moving within the room as before, no?
🗪
49:46gir33 I mean it seems like it only moved when leaving the room but not while moving within the room as before, no?
🗪
49:46gir33 I mean it seems like it only moved when leaving the room but not while moving within the room as before, no?
🗪
50:07Demo the changing dark spot when the lighting voxel alignment changes within a room
🏃
50:07Demo the changing dark spot when the lighting voxel alignment changes within a room
🏃
50:07Demo the changing dark spot when the lighting voxel alignment changes within a room
🏃
50:59Consider removing lighting walk tables
📖
50:59Consider removing lighting walk tables
📖
50:59Consider removing lighting walk tables
📖
55:15mallesbixie FruFru is a great variable name, though
🗪
55:15mallesbixie FruFru is a great variable name, though
🗪
55:15mallesbixie FruFru is a great variable name, though
🗪
55:20Consider removing lighting walk tables
📖
55:20Consider removing lighting walk tables
📖
55:20Consider removing lighting walk tables
📖
56:18Check GridRayCast() to inform our lighting walk table removal decision
📖
56:18Check GridRayCast() to inform our lighting walk table removal decision
📖
56:18Check GridRayCast() to inform our lighting walk table removal decision
📖
59:50Toggle on WalkTable stepping in GridRayCast()
59:50Toggle on WalkTable stepping in GridRayCast()
59:50Toggle on WalkTable stepping in GridRayCast()
1:00:06Traverse the orphanage into a relatively stably lit room
🏃
1:00:06Traverse the orphanage into a relatively stably lit room
🏃
1:00:06Traverse the orphanage into a relatively stably lit room
🏃
1:00:17Change the CostMetric-based ray casting loop in GridRayCast() to iterate over a hard-bounded GridWalkIteration
1:00:17Change the CostMetric-based ray casting loop in GridRayCast() to iterate over a hard-bounded GridWalkIteration
1:00:17Change the CostMetric-based ray casting loop in GridRayCast() to iterate over a hard-bounded GridWalkIteration
1:00:47The lighting looks the same
🏃
1:00:47The lighting looks the same
🏃
1:00:47The lighting looks the same
🏃
1:00:56Remove CostMetric entirely from GridRayCast()
1:00:56Remove CostMetric entirely from GridRayCast()
1:00:56Remove CostMetric entirely from GridRayCast()
1:01:23The lighting remains fine
🏃
1:01:23The lighting remains fine
🏃
1:01:23The lighting remains fine
🏃
1:01:46Consider formulating an exit criterion in GridRayCast() upon leaving the spatial partition
📖
1:01:46Consider formulating an exit criterion in GridRayCast() upon leaving the spatial partition
📖
1:01:46Consider formulating an exit criterion in GridRayCast() upon leaving the spatial partition
📖
1:04:29Determine to make GridRayCast() work without a walk table
📖
1:04:29Determine to make GridRayCast() work without a walk table
📖
1:04:29Determine to make GridRayCast() work without a walk table
📖
1:09:25Sketch out walk table-eliminated grid stepping in GridRayCast()
1:09:25Sketch out walk table-eliminated grid stepping in GridRayCast()
1:09:25Sketch out walk table-eliminated grid stepping in GridRayCast()
1:45:42spacenaming DirCurP is 2*DirCurP+dX/Y at the moment
🗪
1:45:42spacenaming DirCurP is 2*DirCurP+dX/Y at the moment
🗪
1:45:42spacenaming DirCurP is 2*DirCurP+dX/Y at the moment
🗪
1:46:06spacenaming XStepV have it included already
🗪
1:46:06spacenaming XStepV have it included already
🗪
1:46:06spacenaming XStepV have it included already
🗪
1:46:35Determine to remove lighting walk tables
📖
1:46:35Determine to remove lighting walk tables
📖
1:46:35Determine to remove lighting walk tables
📖
1:47:31Break
🗹
1:47:31Break
🗹
1:47:31Break
🗹
1:50:06Return and centre the camera
🗹
1:50:06Return and centre the camera
🗹
1:50:06Return and centre the camera
🗹
1:52:25Implement on-the-fly grid stepping in GridRayCast()
1:52:25Implement on-the-fly grid stepping in GridRayCast()
1:52:25Implement on-the-fly grid stepping in GridRayCast()
2:13:50Hit an overflow read access violation on SpatialGridLeaves in GridRayCast()
🏃
2:13:50Hit an overflow read access violation on SpatialGridLeaves in GridRayCast()
🏃
2:13:50Hit an overflow read access violation on SpatialGridLeaves in GridRayCast()
🏃
2:14:03Introduce a CheckGridIndex to separate out the two grid stepping routines in GridRayCast()
2:14:03Introduce a CheckGridIndex to separate out the two grid stepping routines in GridRayCast()
2:14:03Introduce a CheckGridIndex to separate out the two grid stepping routines in GridRayCast()
2:14:46The lighting behaves the same as before
🏃
2:14:46The lighting behaves the same as before
🏃
2:14:46The lighting behaves the same as before
🏃
2:15:11Break in to GridRayCast() and compare the values of the two grid stepping routines
🏃
2:15:11Break in to GridRayCast() and compare the values of the two grid stepping routines
🏃
2:15:11Break in to GridRayCast() and compare the values of the two grid stepping routines
🏃
2:16:33Fix the dGridIndexXBase and dGridIndexYBase computations in GridRayCast()
2:16:33Fix the dGridIndexXBase and dGridIndexYBase computations in GridRayCast()
2:16:33Fix the dGridIndexXBase and dGridIndexYBase computations in GridRayCast()
2:16:51Break in to GridRayCast() and compare the values of the two grid stepping routines
🏃
2:16:51Break in to GridRayCast() and compare the values of the two grid stepping routines
🏃
2:16:51Break in to GridRayCast() and compare the values of the two grid stepping routines
🏃
2:17:51Assert in GridRayCast() that GridIndex and CheckGridIndex match
2:17:51Assert in GridRayCast() that GridIndex and CheckGridIndex match
2:17:51Assert in GridRayCast() that GridIndex and CheckGridIndex match
2:18:14Run the game
🏃
2:18:14Run the game
🏃
2:18:14Run the game
🏃
2:18:24Update remedybg from 0.3.5.0 to 0.3.6.4
🗹
2:18:24Update remedybg from 0.3.5.0 to 0.3.6.4
🗹
2:18:24Update remedybg from 0.3.5.0 to 0.3.6.4
🗹
2:20:21Hit the GridIndex and CheckGridIndex matching assertion in GridRayCast()
🏃
2:20:21Hit the GridIndex and CheckGridIndex matching assertion in GridRayCast()
🏃
2:20:21Hit the GridIndex and CheckGridIndex matching assertion in GridRayCast()
🏃
2:21:49Swap in the new on-the-fly grid stepping in GridRayCast()
2:21:49Swap in the new on-the-fly grid stepping in GridRayCast()
2:21:49Swap in the new on-the-fly grid stepping in GridRayCast()
2:22:49Our ray casting correctly no longer differs when shifting the lighting voxel
🏃
2:22:49Our ray casting correctly no longer differs when shifting the lighting voxel
🏃
2:22:49Our ray casting correctly no longer differs when shifting the lighting voxel
🏃
2:24:19Consider how to update tTerminate
📖
2:24:19Consider how to update tTerminate
📖
2:24:19Consider how to update tTerminate
📖
2:29:46Make GridRayCast() compute tTerminate on the fly
2:29:46Make GridRayCast() compute tTerminate on the fly
2:29:46Make GridRayCast() compute tTerminate on the fly
2:38:43Our lighting happily looks no different
🏃
2:38:43Our lighting happily looks no different
🏃
2:38:43Our lighting happily looks no different
🏃
2:39:08Remove the lighting walk tables
2:39:08Remove the lighting walk tables
2:39:08Remove the lighting walk tables
2:41:08Run successfully and briefly consider our remaining light bleed bug
🏃
2:41:08Run successfully and briefly consider our remaining light bleed bug
🏃
2:41:08Run successfully and briefly consider our remaining light bleed bug
🏃
2:44:28Reflect on today's work and consider further simplifications
🗩
2:44:28Reflect on today's work and consider further simplifications
🗩
2:44:28Reflect on today's work and consider further simplifications
🗩
2:45:35~82% frame time (~400,000,000 cycles) on ComputeLightPropagationWork
🏃
2:45:35~82% frame time (~400,000,000 cycles) on ComputeLightPropagationWork
🏃
2:45:35~82% frame time (~400,000,000 cycles) on ComputeLightPropagationWork
🏃
2:46:43Make GridRayCast() only cast one ray
2:46:43Make GridRayCast() only cast one ray
2:46:43Make GridRayCast() only cast one ray
2:47:05~35% frame time (~35,000,000 cycles) on ComputeLightPropagationWork
🏃
2:47:05~35% frame time (~35,000,000 cycles) on ComputeLightPropagationWork
🏃
2:47:05~35% frame time (~35,000,000 cycles) on ComputeLightPropagationWork
🏃
2:47:36Make GridRayCast() cast the full LIGHTING_OCTAHEDRAL_RAYS_PER_TEXEL
2:47:36Make GridRayCast() cast the full LIGHTING_OCTAHEDRAL_RAYS_PER_TEXEL
2:47:36Make GridRayCast() cast the full LIGHTING_OCTAHEDRAL_RAYS_PER_TEXEL
2:47:42~82% frame time (~400,000,000 cycles) on ComputeLightPropagationWork
🏃
2:47:42~82% frame time (~400,000,000 cycles) on ComputeLightPropagationWork
🏃
2:47:42~82% frame time (~400,000,000 cycles) on ComputeLightPropagationWork
🏃
2:48:00Make GridRayCast() only cast no rays
2:48:00Make GridRayCast() only cast no rays
2:48:00Make GridRayCast() only cast no rays
2:48:08~11% frame time (~8,800,000 cycles) on ComputeLightPropagationWork
🏃
2:48:08~11% frame time (~8,800,000 cycles) on ComputeLightPropagationWork
🏃
2:48:08~11% frame time (~8,800,000 cycles) on ComputeLightPropagationWork
🏃
2:48:24Make GridRayCast() cast the full LIGHTING_OCTAHEDRAL_RAYS_PER_TEXEL
2:48:24Make GridRayCast() cast the full LIGHTING_OCTAHEDRAL_RAYS_PER_TEXEL
2:48:24Make GridRayCast() cast the full LIGHTING_OCTAHEDRAL_RAYS_PER_TEXEL
2:48:27~82% frame time (~400,000,000 cycles) on ComputeLightPropagationWork
🏃
2:48:27~82% frame time (~400,000,000 cycles) on ComputeLightPropagationWork
🏃
2:48:27~82% frame time (~400,000,000 cycles) on ComputeLightPropagationWork
🏃
2:48:58Make GridRayCast() cast half of the LIGHTING_OCTAHEDRAL_RAYS_PER_TEXEL
2:48:58Make GridRayCast() cast half of the LIGHTING_OCTAHEDRAL_RAYS_PER_TEXEL
2:48:58Make GridRayCast() cast half of the LIGHTING_OCTAHEDRAL_RAYS_PER_TEXEL
2:49:12Admire the cool red light bleed
🏃
2:49:12Admire the cool red light bleed
🏃
2:49:12Admire the cool red light bleed
🏃
2:49:49Make GridRayCast() double the RayWeight to compensate for the halved number of rays
2:49:49Make GridRayCast() double the RayWeight to compensate for the halved number of rays
2:49:49Make GridRayCast() double the RayWeight to compensate for the halved number of rays
2:50:09Admire the apparently structured light bleed bug
🏃
2:50:09Admire the apparently structured light bleed bug
🏃
2:50:09Admire the apparently structured light bleed bug
🏃
2:51:28Let GridRayCast() cast all the rays, at their appropriate weight
2:51:28Let GridRayCast() cast all the rays, at their appropriate weight
2:51:28Let GridRayCast() cast all the rays, at their appropriate weight
2:51:51Disable LIGHT_ATLAS_ASSERT
2:51:51Disable LIGHT_ATLAS_ASSERT
2:51:51Disable LIGHT_ATLAS_ASSERT
2:52:10~28ms frame time
🏃
2:52:10~28ms frame time
🏃
2:52:10~28ms frame time
🏃
2:52:36Disable HANDMADE_SLOW
2:52:36Disable HANDMADE_SLOW
2:52:36Disable HANDMADE_SLOW
2:52:48~24ms frame time
🏃
2:52:48~24ms frame time
🏃
2:52:48~24ms frame time
🏃
2:53:33That's it for today
🗩
2:53:33That's it for today
🗩
2:53:33That's it for today
🗩
2:54:12gir33 Are the GPU shaders just lerping from the results that the CPU is doing?
🗪
2:54:12gir33 Are the GPU shaders just lerping from the results that the CPU is doing?
🗪
2:54:12gir33 Are the GPU shaders just lerping from the results that the CPU is doing?
🗪
2:57:07gir33 Is that like a spherical harmonics encoding?
🗪
2:57:07gir33 Is that like a spherical harmonics encoding?
🗪
2:57:07gir33 Is that like a spherical harmonics encoding?
🗪
3:01:02That's it for today, with a glimpse into the future and reflections on the engine
🗩
3:01:02That's it for today, with a glimpse into the future and reflections on the engine
🗩
3:01:02That's it for today, with a glimpse into the future and reflections on the engine
🗩
3:02:42vaualbus Can Z be re-added in an easier way now that the system is easier?
🗪
3:02:42vaualbus Can Z be re-added in an easier way now that the system is easier?
🗪
3:02:42vaualbus Can Z be re-added in an easier way now that the system is easier?
🗪
3:05:13That's it
🗩
3:05:13That's it
🗩
3:05:13That's it
🗩