diff --git a/src/body.h b/src/body.h
index d04b925..d05e56a 100644
--- a/src/body.h
+++ b/src/body.h
@@ -15,6 +15,8 @@ public:
   virtual Object::Type GetType(void) { return Object::BODY; }
   virtual void SetPosition(vector3d p) = 0;
   virtual vector3d GetPosition(void) = 0; /* Within frame. */
+  virtual void SetVelocity(vector3d v) { assert(0); }
+  virtual vector3d GetVelocity(void) { assert(0); return vector3d(0.0); }
   virtual double GetRadius(void) const = 0 ;
   virtual void Render(const Frame* camFrame) = 0;
   virtual void SetFrame(Frame* f) { m_frame = f; }
diff --git a/src/dynamic_body.cpp b/src/dynamic_body.cpp
index 11eb438..a1cbeab 100644
--- a/src/dynamic_body.cpp
+++ b/src/dynamic_body.cpp
@@ -53,6 +53,11 @@ DynamicBody::~DynamicBody(void) {
   dBodyDestroy(m_body);
 }
 
+vector3d DynamicBody::GetVelocity(void) {
+  const dReal* v = dBodyGetLinearVel(m_body);
+  return vector3d(v[0], v[1], v[2]);
+}
+
 void DynamicBody::SetVelocity(vector3d v) {
   dBodySetLinearVel(m_body, v.x, v.y, v.z);
 }
diff --git a/src/dynamic_body.h b/src/dynamic_body.h
index f210a80..e866c5f 100644
--- a/src/dynamic_body.h
+++ b/src/dynamic_body.h
@@ -11,7 +11,8 @@ public:
   DynamicBody(void);
   virtual ~DynamicBody(void);
   virtual void SetRotation(const matrix4x4d& r);
-  void SetVelocity(vector3d v);
+  virtual void SetVelocity(vector3d v);
+  virtual vector3d GetVelocity(void);
   void SetAngVelocity(vector3d v);
   void SetMesh(ObjMesh* m);
   virtual bool OnCollision(Body* b, Uint32 flags) { return true; }
diff --git a/src/frame.cpp b/src/frame.cpp
index 84ccc7d..97aaf3c 100644
--- a/src/frame.cpp
+++ b/src/frame.cpp
@@ -23,6 +23,7 @@ void Frame::Init(Frame* parent, const char* label, unsigned int flags) {
   m_flags = flags;
   m_radius = 0;
   m_pos = vector3d(0.0f);
+  m_vel = vector3d(0.0);
   m_dSpaceID = dHashSpaceCreate(0);
   if(m_parent) {
     m_parent->m_children.push_back(this);
diff --git a/src/frame.h b/src/frame.h
index 917890f..6799dc3 100644
--- a/src/frame.h
+++ b/src/frame.h
@@ -15,6 +15,9 @@ public:
   const char* GetLabel(void)              { return m_label.c_str(); }
   void SetLabel(const char* label)        { m_label = label; }
   void SetPosition(const vector3d &pos)   { m_pos = pos; }
+  vector3d GetPosition(void)              { return m_pos; }
+  void SetVelocity(const vector3d& vel)   { m_vel = vel; }
+  vector3d GetVelocity(void)              { return m_vel; }
   void SetRadius(double radius)           { m_radius = radius; }
   void RemoveChild(Frame* f);
   void AddGeom(dGeomID g)                 { dSpaceAdd(m_dSpaceID, g); }
@@ -41,6 +44,8 @@ public:
 private:
   void Init(Frame* parent, const char* label, unsigned int flags);
   vector3d m_pos;
+  /* We don't use this to move frame, rather, orbital rails determine velocity. */
+  vector3d m_vel;
   std::string m_label;
   double m_radius;
   int m_flags;
diff --git a/src/main.cpp b/src/main.cpp
index 56c7717..19691fc 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -318,7 +318,8 @@ void L3D::HyperspaceTo(StarSystem* dest) {
   Space::Clear();
   Space::BuildSystem();
   float ang = rng.Double(M_PI);
-  L3D::player->SetPosition(vector3d(sin(ang)*8*AU, cos(ang)*8*AU, 0));
+  L3D::player->SetPosition(vector3d(sin(ang)*AU, cos(ang)*AU,0));
+  L3D::player->SetVelocity(vector3d(0.0));
   dest->GetPos(&L3D::playerLoc);
 }
 
diff --git a/src/space.cpp b/src/space.cpp
index 7ef4ff7..d9062dc 100644
--- a/src/space.cpp
+++ b/src/space.cpp
@@ -41,14 +41,18 @@ void Space::Clear(void) {
   L3D::player->SetFrame(rootFrame);
 }
 
-void Space::MoveFramesOfReference(Frame* f) {
+void Space::MoveOrbitingObjectFrames(Frame* f) {
   if(f->sBody) {
+    /* Not too efficient. */
     vector3d pos = f->sBody->orbit.CartesianPosAtTime(L3D::GetGameTime());
+    vector3d pos2 = f->sBody->orbit.CartesianPosAtTime(L3D::GetGameTime()+1.0);
+    vector3d vel = pos2 - pos;
     f->SetPosition(pos);
+    f->SetVelocity(vel);
   }
 
   for(std::list<Frame*>::iterator i = f->m_children.begin(); i != f->m_children.end(); ++i) {
-    MoveFramesOfReference(*i);
+    MoveOrbitingObjectFrames(*i);
   }
 }
 
@@ -67,11 +71,8 @@ void Space::GenBody(StarSystem::SBody* sbody, Frame* f) {
   b->SetLabel(sbody->name.c_str());
 
   Frame* myframe;
-
   if(sbody->parent) {
     myframe = new Frame(f, sbody->name.c_str());
-    vector3d pos = sbody->orbit.CartesianPosAtTime(0);
-    myframe->SetPosition(pos);
     myframe->SetRadius(10*sbody->GetRadius());
     myframe->sBody = sbody;
     b->SetFrame(myframe);
@@ -94,6 +95,7 @@ just_make_child:
 
 void Space::BuildSystem(void) {
   GenBody(L3D::current_system->rootBody, rootFrame);
+  MoveOrbitingObjectFrames(rootFrame);
 }
 
 void Space::AddBody(Body* b) {
@@ -115,6 +117,8 @@ void Space::UpdateFramesOfReference(void) {
     if(!b->GetFrame()->IsLocalPosInFrame(b->GetPosition())) {
       printf("%s leaves frame %s\n", b->GetLabel().c_str(), b->GetFrame()->GetLabel());
 
+      b->SetVelocity(b->GetVelocity() + b->GetFrame()->GetVelocity());
+
       Frame* new_frame = b->GetFrame()->m_parent;
       if(new_frame) { /* Don't fall out of root frame. */
         vector3d new_pos = b->GetPositionRelTo(new_frame);
@@ -126,12 +130,13 @@ void Space::UpdateFramesOfReference(void) {
     /* Entering into frames. */
     for(std::list<Frame*>::iterator j = b->GetFrame()->m_children.begin();
         j != b->GetFrame()->m_children.end(); ++j) {
-      Frame* kid = *j;
-      vector3d pos = b->GetFrame()->GetPosRelativeToOtherFrame(kid) + b->GetPosition();
-      if(kid->IsLocalPosInFrame(pos)) {
-        printf("%s enters frame %s\n", b->GetLabel().c_str(), kid->GetLabel());
+      Frame* child = *j;
+      vector3d pos = b->GetFrame()->GetPosRelativeToOtherFrame(child) + b->GetPosition();
+      if(child->IsLocalPosInFrame(pos)) {
+        printf("%s enters frame %s\n", b->GetLabel().c_str(), child->GetLabel());
         b->SetPosition(pos);
-        b->SetFrame(kid);
+        b->SetFrame(child);
+        b->SetVelocity(b->GetVelocity() - child->GetVelocity());
         break;
       }
     }
@@ -240,7 +245,7 @@ void Space::TimeStep(float step) {
 
   /* TODO: Does not need to be done this often. */
   UpdateFramesOfReference();
-  MoveFramesOfReference(rootFrame);
+  MoveOrbitingObjectFrames(rootFrame);
 
   for(bodiesIter_t i = bodies.begin(); i != bodies.end(); ++i) {
     (*i)->TimeStepUpdate(step);
diff --git a/src/space.h b/src/space.h
index 08366e5..4f04d39 100644
--- a/src/space.h
+++ b/src/space.h
@@ -24,7 +24,7 @@ public:
   typedef std::list<Body*>::iterator bodiesIter_t;
   static Frame* rootFrame;
 private:
-  static void MoveFramesOfReference(Frame* f);
+  static void MoveOrbitingObjectFrames(Frame* f);
   static void UpdateFramesOfReference(void);
   static void CollideFrame(Frame* f);
   static void PruneCorpses(void);