diff --git a/src/bike.rs b/src/bike.rs
index 38d1ca0..ab39015 100644
--- a/src/bike.rs
+++ b/src/bike.rs
@@ -5,36 +5,54 @@ use bevy::prelude::*;
 
 use crate::physics::CatControllerState;
 
+pub const REST_DISTANCE: f32 = 0.8;
+
 #[derive(Component)]
 pub struct CyberBikeBody;
 
 #[derive(Component)]
-pub struct CyberWheel;
+pub enum CyberWheel {
+    Front,
+    Rear,
+}
 
 // marker for front suspension joint
 #[derive(Component)]
 pub struct Steering;
-#[derive(Component)]
-pub struct FrontHub;
 
 // marker for rear suspension joint
 #[derive(Component)]
 pub struct Rearing;
-#[derive(Component)]
-pub struct RearHub;
+
+#[derive(Debug, Resource, Reflect)]
+pub struct SuspensionConfig {
+    pub rest_dist: f32,
+    pub konstant: f32,
+    pub damping: f32,
+}
+
+impl Default for SuspensionConfig {
+    fn default() -> Self {
+        Self {
+            rest_dist: REST_DISTANCE,
+            konstant: 150.0,
+            damping: 50.0,
+        }
+    }
+}
 
 fn spawn_bike(
     mut commands: Commands,
     mut meshes: ResMut<Assets<Mesh>>,
     mut materials: ResMut<Assets<StandardMaterial>>,
 ) {
-    let pos = Vec3::new(0.0, 4.0, 0.0);
-    let xform = Transform::from_translation(pos).with_rotation(Quat::from_rotation_z(0.0));
+    let pos = Vec3::new(0.0, 24.0, 0.0);
+    let xform = Transform::from_translation(pos); //.with_rotation(Quat::from_rotation_z(0.0));
 
     let body_collider =
         Collider::capsule_endpoints(0.5, Vec3::new(0.0, 0.0, -0.65), Vec3::new(0.0, 0.0, 0.8));
 
-    let bike = commands
+    let _bike = commands
         .spawn((xform, Visibility::default()))
         .insert((
             Name::new("body"),
@@ -45,8 +63,6 @@ fn spawn_bike(
             CyberBikeBody,
             CatControllerState::default(),
             ColliderDensity(20.0),
-            LinearDamping(0.1),
-            AngularDamping(2.0),
             LinearVelocity::ZERO,
             AngularVelocity::ZERO,
             ExternalForce::ZERO.with_persistence(false),
@@ -54,62 +70,89 @@ fn spawn_bike(
         ))
         .with_children(|builder| {
             let color = Color::srgb(0.7, 0.05, 0.7);
-            let mut rotation = Transform::default(); // Transform::from_rotation(Quat::from_rotation_y(FRAC_PI_2));
-            rotation.rotate_x(FRAC_PI_2);
+            let mut xform = Transform::default();
+            xform.rotate_x(FRAC_PI_2);
             let pbr_bundle = (
                 Mesh3d(meshes.add(Capsule3d::new(0.5, 1.45))),
-                rotation,
+                xform,
                 MeshMaterial3d(materials.add(color)),
             );
             builder.spawn(pbr_bundle);
-        })
-        .id();
+            spawn_wheels(builder, meshes, materials, xform, builder.parent_entity());
+        });
 
-    spawn_wheels(commands, meshes, materials, xform, bike);
+    //spawn_wheels(commands, meshes, materials, xform, bike);
+}
+
+fn spawn_caster(
+    commands: &mut ChildBuilder,
+    collider: Collider,
+    xform: Transform,
+    direction: Dir3,
+    parent: Entity,
+    is_front: bool,
+) {
+    let caster = ShapeCaster::new(collider, xform.translation, Quat::IDENTITY, direction)
+        .with_query_filter(SpatialQueryFilter::from_excluded_entities([parent]));
+
+    let mut entity = commands.spawn((caster, Transform::default()));
+    if is_front {
+        entity.insert((Steering, Name::new("front wheel")));
+    } else {
+        entity.insert((Rearing, Name::new("rear wheel")));
+    }
 }
 
 fn spawn_wheels(
-    mut commands: Commands,
+    commands: &mut ChildBuilder,
     mut meshes: ResMut<Assets<Mesh>>,
     mut materials: ResMut<Assets<StandardMaterial>>,
     xform: Transform,
     body: Entity,
 ) {
-    let front_rake = Vec3::new(0.0, -1.0, -0.57).normalize(); // about 30 degrees
-    let front_pos = xform.translation + front_rake;
-
     let (mesh, collider) = gen_tire();
 
-    let front_hub = wheels_helper(
-        &mut commands,
+    let front_rake = Vec3::new(0.0, -1.0, -0.57).normalize(); // about 30 degrees
+    let front_attach = xform.translation + xform.forward() * 0.7;
+    let front_wheel_pos = front_attach + (front_rake * REST_DISTANCE);
+
+    spawn_caster(
+        commands,
+        collider.clone(),
+        Transform::from_translation(front_attach),
+        Dir3::new_unchecked(front_rake),
+        body,
+        true,
+    );
+    wheel_mesh(
+        commands,
         &mut meshes,
         &mut materials,
-        front_pos,
+        front_wheel_pos,
         mesh.clone(),
-        collider.clone(),
+        CyberWheel::Front,
     );
-    commands.entity(front_hub).insert(FrontHub);
-    commands.spawn((
-        Steering,
-        FixedJoint::new(front_hub, body).with_local_anchor_2(*xform.forward() + front_rake),
-    ));
 
     let rear_rake = Vec3::new(0.0, -1.0, 0.57).normalize();
-    let rear_pos = xform.translation + rear_rake;
+    let rear_attach = xform.translation + xform.back() * 0.7;
+    let rear_wheel_pos = rear_attach + (rear_rake * REST_DISTANCE);
 
-    let rear_hub = wheels_helper(
-        &mut commands,
+    spawn_caster(
+        commands,
+        collider,
+        Transform::from_translation(rear_attach),
+        Dir3::new_unchecked(rear_rake),
+        body,
+        false,
+    );
+    wheel_mesh(
+        commands,
         &mut meshes,
         &mut materials,
-        rear_pos,
+        rear_wheel_pos,
         mesh,
-        collider,
+        CyberWheel::Rear,
     );
-    commands.entity(rear_hub).insert(RearHub);
-    commands.spawn((
-        Rearing,
-        FixedJoint::new(rear_hub, body).with_local_anchor_2(*xform.back() + rear_rake),
-    ));
 }
 
 //-************************************************************************
@@ -117,37 +160,20 @@ fn spawn_wheels(
 //-************************************************************************
 
 fn gen_tire() -> (Mesh, Collider) {
-    let mut tire_mesh: Mesh = Torus::new(0.25, 0.40).into();
-    let tire_verts = tire_mesh
-        .attribute(Mesh::ATTRIBUTE_POSITION)
-        .unwrap()
-        .as_float3()
-        .unwrap()
-        .iter()
-        .map(|v| {
-            //
-            let v = Vec3::from_array(*v);
-            let m = Mat3::from_rotation_z(90.0f32.to_radians());
-            let p = m.mul_vec3(v);
-            p.to_array()
-        })
-        .collect::<Vec<[f32; 3]>>();
-    tire_mesh.remove_attribute(Mesh::ATTRIBUTE_POSITION);
-    tire_mesh.insert_attribute(Mesh::ATTRIBUTE_POSITION, tire_verts);
-
-    let collider = Collider::convex_hull_from_mesh(&tire_mesh).unwrap();
+    let tire_mesh: Mesh = Sphere::new(0.4).into();
+    let collider = Collider::sphere(0.4);
 
     (tire_mesh, collider)
 }
 
-fn wheels_helper(
-    commands: &mut Commands,
+fn wheel_mesh(
+    commands: &mut ChildBuilder,
     meshes: &mut ResMut<Assets<Mesh>>,
     materials: &mut ResMut<Assets<StandardMaterial>>,
     position: Vec3,
     tire_mesh: Mesh,
-    collider: Collider,
-) -> Entity {
+    wheel: CyberWheel,
+) {
     let wheel_material = &StandardMaterial {
         base_color: Color::srgb(0.01, 0.01, 0.01),
         alpha_mode: AlphaMode::Opaque,
@@ -156,47 +182,21 @@ fn wheels_helper(
     };
 
     let xform = Transform::from_translation(position);
-    let hub_mesh: Mesh = Sphere::new(0.1).into();
 
-    let hub = commands
-        .spawn((
-            Name::new("hub"),
-            RigidBody::Dynamic,
-            MassPropertiesBundle::from_shape(&Collider::sphere(0.1), 200.0),
-            Mesh3d(meshes.add(hub_mesh)),
-            MeshMaterial3d(materials.add(wheel_material.clone())),
-            xform,
-        ))
-        .id();
-
-    let tire = commands
-        .spawn((
-            Name::new("tire"),
-            Mesh3d(meshes.add(tire_mesh)),
-            MeshMaterial3d(materials.add(wheel_material.clone())),
-            xform,
-            CyberWheel,
-            RigidBody::Dynamic,
-            collider,
-            Friction::new(0.9).with_dynamic_coefficient(0.6),
-            Restitution::new(0.1),
-            ColliderDensity(30.0),
-            CollisionLayers::from_bits(2, 2),
-            ExternalTorque::ZERO.with_persistence(false),
-            CollisionMargin(0.05),
-            SweptCcd::NON_LINEAR,
-        ))
-        .id();
-
-    // connect hubs and tires to make wheels
-    commands.spawn(RevoluteJoint::new(hub, tire).with_aligned_axis(Vec3::X));
-    hub
+    commands.spawn((
+        Name::new("tire"),
+        Mesh3d(meshes.add(tire_mesh)),
+        MeshMaterial3d(materials.add(wheel_material.clone())),
+        xform,
+        wheel,
+    ));
 }
 
 pub struct CyberBikePlugin;
 
 impl Plugin for CyberBikePlugin {
     fn build(&self, app: &mut App) {
+        app.init_resource::<SuspensionConfig>();
         app.add_systems(Startup, spawn_bike);
     }
 }
diff --git a/src/camera.rs b/src/camera.rs
index ca4c8cd..75a51c9 100644
--- a/src/camera.rs
+++ b/src/camera.rs
@@ -16,7 +16,7 @@ impl Default for DebugCamOffset {
     fn default() -> Self {
         DebugCamOffset {
             rot: 60.0,
-            dist: 10.0,
+            dist: 30.0,
             alt: 4.0,
         }
     }