diff --git a/src/main.cpp b/src/main.cpp
index 212a5e1..d8fb78e 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -217,12 +217,14 @@ void L3D::MainLoop(void) {
   player->SetLabel("Me");
   Space::AddBody(player);
 
-  StarSystem s(0, 0, 0);
+  StarSystem s(0, 0, 1);
   HyperspaceTo(&s);
 
   const float zpos = EARTH_RADIUS * 3;
-  Frame* pframe = *(++(++(Space::rootFrame->m_children.begin())));
+  //Frame* pframe = *(++(++(Space::rootFrame->m_children.begin())));
+  Frame* pframe = *(Space::rootFrame->m_children.begin());
 
+#if 0
   Frame* stationFrame = new Frame(pframe, "Station frame..");
   stationFrame->SetRadius(5000);
   stationFrame->m_sbody = 0;
@@ -250,10 +252,13 @@ void L3D::MainLoop(void) {
   station2->SetFrame(*pframe->m_children.begin()); /* Rotating frame of planet. */
   station2->OrientOnSurface(EARTH_RADIUS, M_PI/4, M_PI/4);
   Space::AddBody(station2);
+#endif
 
   player->SetFrame(pframe);
   //player->SetPosition(vector3d(0,0,0));
-  player->OrientOnSurface(EARTH_RADIUS*1.001, M_PI/4, M_PI/4);
+  //player->OrientOnSurface(EARTH_RADIUS*1.001, M_PI/4, M_PI/4);
+  //player->OrientOnSurface(EARTH_RADIUS*1.001, M_PI/4, M_PI/4);
+  player->SetPosition(vector3d(0, 0, EARTH_RADIUS));
   //player->SetPosition(vector3d(0,0,2000));
   //player->SetFrame(pframe);
 
@@ -271,7 +276,7 @@ void L3D::MainLoop(void) {
   infoView          = new InfoView();
 
   SetView(worldView);
-  player->SetDockedWith(station2, 0);
+  //player->SetDockedWith(station2, 0);
 
   Uint32 last_stats = SDL_GetTicks();
   int frame_stat = 0;
@@ -323,7 +328,7 @@ void L3D::MainLoop(void) {
     while(time_before_frame - last_phys_update > 16) {
       last_phys_update += 16;
       const float step = L3D::GetTimeStep();
-      Space::TimeStep(step);
+      if(step) Space::TimeStep(step);
       gameTime += step;
       phys_stat++;
     }
diff --git a/src/space.cpp b/src/space.cpp
index 3651ddb..58acbd7 100644
--- a/src/space.cpp
+++ b/src/space.cpp
@@ -106,7 +106,7 @@ static Frame* MakeFrameFor(StarSystem::SBody* sbody, Body* b, Frame* f) {
     orbFrame->SetRadius(sbody->GetMaxChildOrbitalDistance()*1.1);
     b->SetFrame(orbFrame);
     return orbFrame;
-  } else if(supertype == StarSystem::SUPERTYPE_STARPORT) {
+  } else if(sbody->type == StarSystem::TYPE_STARPORT_ORBITAL) {
     /*
      * Space stations want non-rotating frame to some distance
      * and a much closer rotating frame.
@@ -122,6 +122,17 @@ static Frame* MakeFrameFor(StarSystem::SBody* sbody, Body* b, Frame* f) {
     rotFrame->SetAngVelocity(vector3d(0,2*M_PI/sbody->GetRotationPeriod(), 0));
     b->SetFrame(rotFrame);
     return orbFrame;
+  } else if(sbody->type == StarSystem::TYPE_STARPORT_SURFACE) {
+    /*
+     * Just put body into rotating frame of planet, not in its own frame
+     * (Because collisions only happen between objects in same frame,
+     * and we want collisions on starport and on planet itself).
+     */
+    Frame* frame = *f->m_children.begin();
+    b->SetFrame(frame);
+    b->SetPosition(sbody->orbit.rotMatrix * (frame->m_astroBody->GetRadius()*vector3d(0, 1, 0)));
+    b->SetRotMatrix(sbody->orbit.rotMatrix);
+    return frame;
   } else {
     assert(0);
   }
@@ -137,6 +148,9 @@ void Space::GenBody(StarSystem::SBody* sbody, Frame* f) {
     } else if(sbody->type == StarSystem::TYPE_STARPORT_ORBITAL) {
       SpaceStation* ss = new SpaceStation(SpaceStation::JJHOOP);
       b = ss;
+    } else if(sbody->type == StarSystem::TYPE_STARPORT_SURFACE) {
+      SpaceStation* ss = new SpaceStation(SpaceStation::GROUND_FLAVOURED);
+      b = ss;
     } else {
       Planet* planet = new Planet(sbody);
       b = planet;
diff --git a/src/star_system.cpp b/src/star_system.cpp
index 314c596..250cc4f 100644
--- a/src/star_system.cpp
+++ b/src/star_system.cpp
@@ -798,8 +798,8 @@ void StarSystem::SBody::PickPlanetType(StarSystem* system, SBody* star, const fi
       (*i)->PickPlanetType(system, star, distToPrimary, rand, false);
     }
   }
-  /* Starports. */
-  if((averageTemp < CELSIUS+100) && (averageTemp > 100) &&
+  /* Starports - orbital. */
+  if((genMoons) && (averageTemp < CELSIUS+100) && (averageTemp > 100) &&
       (rand.Fixed() < system->m_humanInfested)) {
     SBody* sp = new SBody;
     sp->type = TYPE_STARPORT_ORBITAL;
@@ -810,14 +810,51 @@ void StarSystem::SBody::PickPlanetType(StarSystem* system, SBody* star, const fi
     sp->averageTemp = this->averageTemp;
     sp->mass = 0;
     sp->name = "Starport";
-    fixed semiMajorAxis = fixed(1, 2000);
+    fixed semiMajorAxis;
+    if(children.size()) {
+      semiMajorAxis = fixed(1,2) * children[0]->orbMin;
+    } else {
+      semiMajorAxis = fixed(1, 3557);
+    }
     sp->orbit.eccentricity = 0;
     sp->orbit.semiMajorAxis = semiMajorAxis.ToDouble()*AU;
     sp->orbit.period = calc_orbital_period(sp->orbit.semiMajorAxis, this->mass.ToDouble()*EARTH_MASS);
     sp->orbit.rotMatrix = matrix4x4d::Identity();
-    this->children.push_back(sp);
+    children.insert(children.begin(), sp);
     sp->orbMin = semiMajorAxis;
     sp->orbMax = semiMajorAxis;
+
+    if(rand.Fixed() < system->m_humanInfested) {
+      SBody* sp2 = new SBody;
+      *sp2 = *sp;
+      sp2->orbit.rotMatrix = matrix4x4d::RotateZMatrix(M_PI);
+      children.insert(children.begin(), sp2);
+    }
+  }
+  /* Starports - surface. */
+  if((averageTemp < CELSIUS+80) && (averageTemp > 100) &&
+      (type == TYPE_PLANET_DWARF)   ||
+      (type == TYPE_PLANET_SMALL)   ||
+      (type == TYPE_PLANET_WATER)   ||
+      (type == TYPE_PLANET_CO2)     ||
+      (type == TYPE_PLANET_METHANE) ||
+      (type == TYPE_PLANET_INDIGENOUS_LIFE)) {
+
+    int max = 6;
+    while((max-- > 0) && (rand.Fixed() < system->m_humanInfested)) {
+      SBody* sp = new SBody;
+      sp->type = TYPE_STARPORT_SURFACE;
+      sp->seed = rand.Int32();
+      sp->tmp = 0;
+      sp->parent = this;
+      sp->averageTemp = this->averageTemp;
+      sp->mass = 0;
+      sp->name = "Starport";
+      /* Used for orientation on planet surface. */
+      sp->orbit.rotMatrix = matrix4x4d::RotateZMatrix(2*M_PI*rand.Double()) *
+                            matrix4x4d::RotateYMatrix(2*M_PI*rand.Double());
+      children.insert(children.begin(), sp);
+    }
   }
 }
 
diff --git a/src/system_info_view.cpp b/src/system_info_view.cpp
index 3fd10d0..3bad5c1 100644
--- a/src/system_info_view.cpp
+++ b/src/system_info_view.cpp
@@ -51,6 +51,17 @@ void SystemInfoView::OnBodySelected(StarSystem::SBody* b) {
       snprintf(buf, sizeof(buf), "Day length    %.1f earth days\n", dayLen/(60*60*24));
       desc += buf;
     }
+    int numSurfaceStarports = 0;
+    std::string nameList;
+    for(std::vector<StarSystem::SBody*>::iterator i = b->children.begin(); i != b->children.end(); ++i) {
+      if((*i)->type == StarSystem::TYPE_STARPORT_SURFACE) {
+        nameList += (numSurfaceStarports ? ", " : "") + (*i)->name;
+        numSurfaceStarports++;
+      }
+    }
+    if(numSurfaceStarports) {
+      desc += "Starports    "+nameList+"\n";
+    }
   }
   m_infoText->SetText(desc);
 }
@@ -61,6 +72,7 @@ void SystemInfoView::PutBodies(StarSystem::SBody* body, int dir, float pos[2],
   float myPos[2];
   myPos[0] = pos[0];
   myPos[1] = pos[1];
+  if(body->type == StarSystem::TYPE_STARPORT_SURFACE) return;
   if(body->type != StarSystem::TYPE_GRAVPOINT) {
     Gui::ImageButton* ib = new Gui::ImageButton(body->GetIcon());
     ib->GetSize(size);
diff --git a/src/system_view.cpp b/src/system_view.cpp
index 91893fe..7c7ed7a 100644
--- a/src/system_view.cpp
+++ b/src/system_view.cpp
@@ -116,6 +116,7 @@ void SystemView::PutLabel(StarSystem::SBody* b) {
 #define ROUGH_SIZE_OF_THING 10.0
 
 void SystemView::PutBody(StarSystem::SBody* b) {
+  if(b->type == StarSystem::TYPE_STARPORT_SURFACE) return;
   if(b->type != StarSystem::TYPE_GRAVPOINT) {
     glPointSize(5);
     glColor3f(1,1,1);