diff --git a/src/lib.rs b/src/lib.rs
index 2a31bd9..54d458b 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -1,6 +1,9 @@
 use argh::FromArgs;
 use bevy::prelude::*;
 
+const SPEED: f32 = 20.0;
+const SPEED_DIFF_RANGE: f32 = 0.08; // +/- 8%
+
 #[derive(Debug, FromArgs, Resource)]
 /// Toid Watching
 pub struct Config {
@@ -26,6 +29,9 @@ impl Pointable for Vec3 {
 #[derive(Resource, Deref, DerefMut)]
 pub struct Index(pub rstar::RTree<Toint>);
 
+#[derive(Resource, Deref, DerefMut)]
+pub struct Positions(pub std::collections::HashMap<Entity, Vec3>);
+
 #[derive(Component, Debug, Clone, Deref, DerefMut, Default)]
 pub struct Buddies(Vec<Entity>);
 
@@ -33,12 +39,21 @@ pub struct Buddies(Vec<Entity>);
 pub struct Velocity(Vec3);
 
 #[derive(Component)]
-pub struct Toid;
+pub struct Toid {
+    pub speed: f32,
+}
 
-pub fn turkey_time(commands: &mut Commands, scene: &Handle<Scene>) -> Entity {
+pub fn turkey_time(
+    commands: &mut Commands,
+    scene: &Handle<Scene>,
+    r: &mut impl rand::prelude::Rng,
+) -> Entity {
+    let speed_diff = r.gen_range(-SPEED_DIFF_RANGE..=SPEED_DIFF_RANGE);
+    let speed = SPEED + (SPEED * speed_diff);
+    let vel = unit_vec(r) * speed;
     commands
         .spawn(SpatialBundle::default())
-        .insert((Velocity::default(), Buddies::default(), Toid))
+        .insert((Velocity(vel), Buddies::default(), Toid { speed }))
         .with_children(|t| {
             t.spawn(SceneBundle {
                 scene: scene.to_owned(),
@@ -60,3 +75,54 @@ pub fn add_gizmos(mut gizmos: Gizmos, toids: Query<(&Transform, Entity), With<To
         gizmos.ray(rpos, pos.forward(), Color::RED);
     }
 }
+
+pub fn update_pos(
+    mut toids: Query<(&mut Transform, &Velocity, Entity)>,
+    time: Res<Time>,
+    mut index: Res<Index>,
+) {
+    let dt = time.delta_seconds();
+    for (mut xform, vel, _entity) in toids.iter_mut() {
+        let vel = vel.0;
+        xform.translation += vel * dt;
+    }
+}
+
+pub fn update_vel(
+    mut toids: Query<(&Transform, &mut Velocity, &Toid), With<Toid>>,
+    time: Res<Time>,
+) {
+    let dt = time.delta_seconds();
+    for (xform, mut vel, toid) in toids.iter_mut() {
+        let speed = toid.speed;
+        let mut dir = xform.forward();
+
+        // nudge up if too low
+
+        // nudge toward origin if too far
+
+        // find buddies and orient: point more towards further-away buddies
+    }
+}
+
+pub fn update_buddies(mut toids: Query<(&Transform, Entity, &mut Buddies)>, index: Res<Index>) {}
+
+//-************************************************************************
+// util
+//-************************************************************************
+
+pub fn unit_vec(r: &mut impl rand::prelude::Rng) -> Vec3 {
+    let mut x1: f32 = 0.0;
+    let mut x2: f32 = 0.0;
+    let mut ssum = std::f32::MAX;
+    while ssum >= 1.0 {
+        x1 = r.gen_range(-1.0..=1.0);
+        x2 = r.gen_range(-1.0..=1.0);
+        ssum = x1.powi(2) + x2.powi(2);
+    }
+    let sqrt = (1.0 - ssum).sqrt();
+    let x = 2.0 * x1 * sqrt;
+    let y = 2.0 * x2 * sqrt;
+    let z = 1.0 - 2.0 * ssum;
+    Vec3::new(x, y, z).normalize()
+}
diff --git a/src/main.rs b/src/main.rs
index 550d0ad..8740fcd 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -29,13 +29,15 @@ fn setup(
     config: Res<Config>,
     models: Res<AssetServer>,
 ) {
+    let rand = &mut rand::thread_rng();
+
     commands.spawn(Camera3dBundle {
         transform: Transform::from_xyz(0., 1.5, 6.).looking_at(Vec3::ZERO, Vec3::Y),
         ..default()
     });
     // plane
     commands.spawn(PbrBundle {
-        mesh: meshes.add(Mesh::from(shape::Plane::from_size(5.0))),
+        mesh: meshes.add(Mesh::from(shape::Plane::from_size(50.0))),
         material: materials.add(Color::rgb(0.3, 0.5, 0.3).into()),
         ..default()
     });
@@ -43,7 +45,7 @@ fn setup(
     let toid_model = models.load("models/boid.glb#Scene0");
 
     for _ in 0..config.toids {
-        let _ = turkey_time(&mut commands, &toid_model);
+        let _ = turkey_time(&mut commands, &toid_model, rand);
     }
 
     // light