diff --git a/dat/SHIP b/dat/SHIP
new file mode 100644
index 0000000..5e84f0c
--- /dev/null
+++ b/dat/SHIP
@@ -0,0 +1,14 @@
+// ================
+// NOTES.
+// ================
+
+Units:
+  Thrust, speed is in pixels/second.
+  turn is in degrees per half a second.
+
+  energy, armor and shield regen are in points a minute.
+
+  crew is in, uh.. people.
+  mass is in tons.
+  cargo and weapon capacity are int tons.
+
diff --git a/dat/fleet.xml b/dat/fleet.xml
index a95ab57..7a64d5d 100644
--- a/dat/fleet.xml
+++ b/dat/fleet.xml
@@ -3,7 +3,7 @@
   <fleet name="Test">
     <faction>2</faction>
       <pilots>
-        <pilot chance='100'>Mr. Test</pilot>
+        <pilot chance='100'>Miss. Test</pilot>
       </pilots>
   </fleet>
   <fleet name="Merchant Ship">
diff --git a/bin/ai_test.lua b/scripts/ai/test.lua
similarity index 100%
rename from bin/ai_test.lua
rename to scripts/ai/test.lua
diff --git a/src/ai.c b/src/ai.c
index 944b73a..1b049e1 100644
--- a/src/ai.c
+++ b/src/ai.c
@@ -3,6 +3,8 @@
 #include <lauxlib.h>
 #include <lualib.h>
 
+#include <math.h>
+
 #include "def.h"
 #include "log.h"
 #include "pilot.h"
@@ -25,19 +27,31 @@
 // Call the AI function with name f.
 #define AI_LCALL(f) (lua_getglobal(L, f), lua_call(L, 0, 0))
 
+// Don't run the function if (n) params aren't passed.
+#define MIN_ARGS(n) if(lua_gettop(L) < n) return 0
+
 static int ai_minbrakedist(lua_State* L); // Minimal breaking distance.
 static int ai_accel(lua_State* L); // Accelerate.
 
-// Basic task.
-// name   : Tasks name (Lua function.)
-// target : Target, this will depend on the task itself.
-typedef struct {
-  char* name;
-  union {
-    void* target;
-    unsigned int ID;
-  };
-} Task;
+// Internal C routines.
+static void ai_freetask(Task* t);
+// Ai routines for Lua.
+// Tasks.
+static int ai_pushtask(lua_State* L);     // pushtask(string, number/pointer, number)
+static int ai_poptask(lua_State* L);      // poptask()
+static int ai_taskname(lua_State* L);     // Number taskname.
+// Consult values.
+static int ai_gettarget(lua_State* L);    // Pointer gettarget()
+static int ai_gettargetid(lua_State* L);  // Number gettargetis()
+static int ai_getdistance(lua_State* L);  // Number getdist(Vec2)
+static int ai_getpos(lua_State* L);       // getpos(number/pilot)
+static int ai_minbrakedist(lua_State* L); // Number minbrakedist()
+// Movement.
+static int ai_accel(lua_State* L);        // accel(number); nuimber <= 1.
+static int ai_turn(lua_State* L);         // turn(number); abs(number) <= 1.
+static int ai_face(lua_State* L);         // face(number/pointer)
+// Misc.
+static int ai_createvect(lua_State* L);   // createvect(number, number)
 
 // Global Lua interpreter.
 static lua_State* L = NULL;
@@ -52,11 +66,24 @@ int ai_init(void) {
   if(L == NULL)
     return -1;
 
-  // Register C funstions in Lua.
-  lua_register(L, "minbrakedist", ai_minbrakedist);
-  lua_register(L, "accel", ai_accel);
+  // Open the standard Lua libraries.
+  luaL_openlibs(L);
 
-  if(luaL_dofile(L, "ai_test.lua") != 0) {
+  // Register C funstions in Lua.
+  lua_register(L, "pushtask",     ai_pushtask);
+  lua_register(L, "poptask",      ai_poptask);
+  lua_register(L, "taskname",     ai_taskname);
+  lua_register(L, "gettarget",    ai_gettarget);
+  lua_register(L, "gettargetid",  ai_gettargetid);
+  lua_register(L, "getdistance",  ai_getdistance);
+  lua_register(L, "getpos",       ai_getpos);
+  lua_register(L, "minbrakedist", ai_minbrakedist);
+  lua_register(L, "accel",        ai_accel);
+  lua_register(L, "turn",         ai_turn);
+  lua_register(L, "face",         ai_face);
+  lua_register(L, "createvect",   ai_createvect);
+
+  if(luaL_dofile(L, "../scripts/ai/test.lua") != 0) {
     WARN("Unable to load AI file: %s", "ai_test.lua");
     return -1;
   }
@@ -72,41 +99,184 @@ void ai_exit(void) {
 void ai_think(Pilot* pilot) {
   cur_pilot = pilot; // Set current pilot being processed.
   pilot_acc = pilot_turn = 0.; // Clean up some variables.
-  if(pilot->action == NULL) {
+  if(cur_pilot->task == NULL)
     // Idle git!
     AI_LCALL("control");
-  }
+  else
+    // Pilot has a currently running task.
+    AI_LCALL(cur_pilot->task->name);
+
+  // Make sure pilot_acc and pilot_turn are legal moves.
+  if(pilot_acc > 1.) pilot_acc = 1.;    // Value must be <= 1.
+  if(pilot_turn > 1.) pilot_turn = 1.;  // Value must be between -1 and 1.
+  else if(pilot_turn < -1.) pilot_turn = -1.;
 
   cur_pilot->solid->dir_vel = 0.;
-  if(pilot_turn)
+  if(pilot_turn) // Set the turning velocity.
     cur_pilot->solid->dir_vel -= cur_pilot->ship->turn * pilot_turn;
   vect_pset(&cur_pilot->solid->force, cur_pilot->ship->thrust * pilot_acc, cur_pilot->solid->dir);
 }
 
+// =====================
+// INTERNAL C FUNCTIONS.
+// =====================
+
+// Free the task.
+static void ai_freetask(Task* t) {
+  if(t->next) ai_freetask(t->next); // Woot, recursive freeing!
+
+  if(t->name)    free(t->name);
+  if(t->target) free(t->target);
+  free(t);
+}
+
 // ========================================================
 // C functions to call from Lua.
-// -----------------------------
+// ========================================================
+
+// Push the current stack.
+static int ai_pushtask(lua_State* L) {
+  int pos;
+  if(lua_isnumber(L, 1)) pos = (int) lua_tonumber(L, 1);
+  else return 0; // Invalid param.
+
+  Task* t = MALLOC_L(Task);
+  t->name = (lua_isstring(L, 2)) ? strdup((char*) lua_tostring(L, 2)) : NULL;
+  t->next = NULL;
+
+  if(lua_gettop(L) > 2) {
+    if(lua_isnumber(L, 3))
+      t->ID = (unsigned int) lua_tonumber(L, 3);
+    else if(lua_islightuserdata(L, 3))
+      t->target = (void*)lua_topointer(L, 3);
+  }
+
+  if(cur_pilot->task == NULL) // No other tasks.
+    cur_pilot->task = t;
+  else if(pos == 1) {
+    // Put at the end.
+    Task* pointer;
+    for(pointer = cur_pilot->task; pointer->next; pointer = pointer->next);
+    pointer->next = t;
+  } else {
+    // Default put at the beginning.
+    t->next = cur_pilot->task;
+    cur_pilot->task = t;
+  }
+  return 0;
+}
+
+// Pop the current task.
+static int ai_poptask(lua_State* L) {
+  Task* t = cur_pilot->task;
+  cur_pilot->task = t->next;
+  t->next = NULL;
+  ai_freetask(t);
+  return 0;
+}
+
+// Grab the current tasks name.
+static int ai_taskname(lua_State* L) {
+  if(cur_pilot->task) lua_pushstring(L, cur_pilot->task->name);
+  else lua_pushnil(L);
+  return 1;
+}
+
+// Grab the targer pointer.
+static int ai_gettarget(lua_State* L) {
+  lua_pushlightuserdata(L, cur_pilot->task->target);
+  return 1;
+}
+
+// Get the ID.
+static int ai_gettargetid(lua_State* L) {
+  lua_pushnumber(L, cur_pilot->task->ID);
+  return 1;
+}
+
+// Get the distance from the pointer.
+static int ai_getdistance(lua_State* L) {
+  MIN_ARGS(1);
+  Vec2* vect = (Vec2*)lua_topointer(L,1);
+  lua_pushnumber(L, MOD(vect->x-cur_pilot->solid->pos.x, vect->y-cur_pilot->solid->pos.y));
+  return 1;
+}
+
+// Get the pilots position.
+static int ai_getpos(lua_State* L) {
+  Pilot* p;
+  if(lua_isnumber(L, 1)) p = get_pilot((int)lua_tonumber(L,1)); // Pilot ID.
+  else if(lua_islightuserdata(L, 1)) p = (Pilot*)lua_topointer(L, 1); // Pilot pointer.
+  else p = cur_pilot; // Default to ones self.
+
+  lua_pushlightuserdata(L, &p->solid->pos);
+
+  return 1;
+}
+
+// ========================================================
 // Get the minimum braking distance.
 // 
-// Braking vel ==> v*t = 0.5 a * t^2 => t = 2*v / a
+// Braking vel ==> 0 = v - a*dt
 // Add turn around time (to initial velocity) :
 // ==> 180.*360./cur_pilot->ship->turn
 // Add it to general euler equation x = v*t + 0.5 * a * t^2
 // Have fun.
 // ========================================================
 static int ai_minbrakedist(lua_State* L) {
-  double time = 2. * VMOD(cur_pilot->solid->vel) /
+  double time = VMOD(cur_pilot->solid->vel) /
         (cur_pilot->ship->thrust / cur_pilot->solid->mass);
 
-  double dist = VMOD(cur_pilot->solid->vel) * (time + 0.5 * (180. * 360. / cur_pilot->ship->turn)) -
+  double dist = VMOD(cur_pilot->solid->vel) * (time + cur_pilot->ship->turn/360.) -
         0.5 * (cur_pilot->ship->thrust / cur_pilot->solid->mass)*time*time;
 
   lua_pushnumber(L, dist); // return
   return 1;
 }
 
+// Accelerate the pilot based on a param.
 static int ai_accel(lua_State* L) {
-  pilot_acc = (lua_isnumber(L, 1)) ? (double)lua_tonumber(L, 1) : 1.;
+  MIN_ARGS(1);
+  pilot_acc = (lua_isnumber(L, 1)) ? ABS((double)lua_tonumber(L, 1)) : 1.;
   return 0;
 }
 
+// Turn the pilot based on a param.
+static int ai_turn(lua_State* L) {
+  MIN_ARGS(1);
+  pilot_turn = (lua_isnumber(L, 1)) ? (double)lua_tonumber(L, 1) : 0.;
+  return 0;
+}
+
+// Face the target.
+static int ai_face(lua_State* L) {
+  MIN_ARGS(1);
+  Vec2* v; // Grab the position to face.
+  if(lua_isnumber(L,1)) v = &get_pilot((unsigned int)lua_tonumber(L,1))->solid->pos;
+  else if(lua_islightuserdata(L,1)) v = (Vec2*)lua_topointer(L,1);
+
+  double mod;
+  if(lua_gettop(L) > 1 && lua_isnumber(L,2))
+    switch((int)lua_tonumber(L,2)) {
+      case 1: mod *= -1; break;
+      case 2: break;
+    }
+  
+  pilot_turn = mod * angle_diff(cur_pilot->solid->dir, vect_angle(&cur_pilot->solid->pos, v));
+
+  return 0;
+}
+
+// Create a vector.
+static int ai_createvect(lua_State* L) {
+  MIN_ARGS(2);
+  Vec2* v = MALLOC_L(Vec2);
+  double x = (lua_isnumber(L, 1)) ? (double)lua_tonumber(L,1) : 0.;
+  double y = (lua_isnumber(L, 2)) ? (double)lua_tonumber(L,2) : 0.;
+
+  vect_cset(v, x, y);
+
+  lua_pushlightuserdata(L, (void*)v);
+  return 1;
+}
+
diff --git a/src/ai.h b/src/ai.h
index a5f3029..4bcb1c1 100644
--- a/src/ai.h
+++ b/src/ai.h
@@ -1,5 +1,16 @@
 #pragma once
 
+struct Task {
+  struct Task* next;
+  char* name;
+
+  union {
+    void* target; // Vec2 etc.
+    unsigned int ID; // Pilot ID etc.
+  };
+};
+typedef struct Task Task;
+
 int ai_init(void);
 void ai_exit(void);
 
diff --git a/src/def.h b/src/def.h
index d027c8b..afd8def 100644
--- a/src/def.h
+++ b/src/def.h
@@ -4,7 +4,6 @@
 #define CALLOC_L(type)(calloc(1, sizeof(type)))
 
 #define ABS(X)  ((X<0)?-X:X)
-#define FABS(X) ((X<0.)?-X:X)
 
 #define DATA "data"
 
diff --git a/src/physics.c b/src/physics.c
index f0a0fa8..2318a2b 100644
--- a/src/physics.c
+++ b/src/physics.c
@@ -4,12 +4,21 @@
 
 #include "physics.h"
 
-#ifndef M_PI
-#define M_PI 3.14159265358979323846f
-#endif
+// ================
+// MISC
+// ================
+double angle_diff(const double ref, double a) {
+  if(a < M_PI) a += 2*M_PI;
+  double d = fmod((a-ref), 2*M_PI);
+  return (d <= M_PI) ? d : d - 2*M_PI;
+}
+
+// ================
+// VEC2
+// ================
 
 // Set the vector value using cartesian coords.
-void vect_cset(Vec2* v, double x, double y) {
+void vect_cset(Vec2* v, const double x, const double y) {
   v->x = x;
   v->y = y;
   v->mod = MOD(x,y);
@@ -17,7 +26,7 @@ void vect_cset(Vec2* v, double x, double y) {
 }
 
 // Set the vector value using polar coords.
-void vect_pset(Vec2* v, double mod, double angle) {
+void vect_pset(Vec2* v, const double mod, const double angle) {
   v->mod = mod;
   v->angle = angle;
   v->x = v->mod*cos(v->angle);
@@ -37,6 +46,16 @@ void vectnull(Vec2* v) {
   v->x = v->y = v->mod = v->angle = 0.;
 }
 
+// Get the direction pointed to by two vectors (from ref to v).
+double vect_angle(const Vec2* ref, const Vec2* v) {
+  return ANGLE(VX(*v)-VX(*ref), VY(*v)-VY(*ref));
+}
+
+
+// ================
+// SOLID!
+// ================
+
 // ==Update method.========================================
 // d^2 x(t) / d t^2 = a, a = constant (acceleration)
 // x'(0) = v, x(0) = p
@@ -50,7 +69,7 @@ void vectnull(Vec2* v) {
 #if 0 // Simply commenting this out to avoid silly warnings.
 static void simple_update(Solid* obj, const double dt) {
   // Make sure angle doesn't flip.
-  obj->dir += obj->dir_vel/360.*dt;
+  obj->dir += M_PI/360.*obj->dir_vel*dt;
   if(obj->dir > 2*M_PI)   obj->dir -= 2*M_PI;
   if(obj->dir < 0.)      obj->dir += 2*M_PI;
   
@@ -100,7 +119,7 @@ static void simple_update(Solid* obj, const double dt) {
 #define RK4_MIN_H 0.01 // Minimal pass we want.
 static void rk4_update(Solid* obj, const double dt) {
   // Make sure angle doesn't flip.
-  obj->dir += obj->dir_vel/360.0*dt;
+  obj->dir += M_PI/360.*obj->dir_vel*dt;
   if(obj->dir > 2*M_PI)   obj->dir -= 2*M_PI;
   if(obj->dir < 0.0)      obj->dir += 2*M_PI;
 
@@ -123,20 +142,20 @@ static void rk4_update(Solid* obj, const double dt) {
     for(i = 0; i < N; i++) {
       // X component.
       tx = ix = vx;
-      tx += 2*ix + h*tx;
-      tx += 2*ix + h*tx;
+      tx += 2.*ix + h*tx;
+      tx += 2.*ix + h*tx;
       tx += ix + h*tx;
-      tx *= h/6;
+      tx *= h/6.;
 
       px += tx;
       vx += ax*h;
 
       // Y component.
       ty = iy = vy;
-      ty += 2*(iy + h/2*ty);
-      ty += 2*(iy + h/2*ty);
+      ty += 2.*(iy + h/2.*ty);
+      ty += 2.*(iy + h/2.*ty);
       ty += iy +h*ty;
-      ty *= h/6;
+      ty *= h/6.;
 
       py += ty;
       vy += ay*h;
@@ -153,8 +172,8 @@ static void rk4_update(Solid* obj, const double dt) {
 void solid_init(Solid* dest, const double mass, const Vec2* vel, const Vec2* pos) {
   dest->mass = mass;
 
-  dest->force.mod = 0;
-  dest->dir       = 0;
+  vect_cset(&dest->force, 0., 0.);
+  dest->dir = 0.;
 
   if(vel == NULL) vectnull(&dest->vel);
   else vectcpy(&dest->vel, vel);
diff --git a/src/physics.h b/src/physics.h
index a939652..e47ead4 100644
--- a/src/physics.h
+++ b/src/physics.h
@@ -6,8 +6,11 @@
 #define VMOD(v)   ((v).mod)
 #define VANGLE(v) ((v).angle)
 
-#define MOD(x,y)  (sqrt(x*x + y*y))
-#define ANGLE(x,y)((x==0.) ? 0. : ((x<0.)?atan(y/x)+M_PI:atan(y/x)))
+#define MOD(x,y)  (sqrt((x)*(x) + (y)*(y)))
+#define ANGLE(x,y)(((x)==0.) ? 0. : (((x)<0.)?atan((y)/(x))+M_PI:atan((y)/(x))))
+
+// Misc
+double angle_diff(const double ref, double a);
 
 // Base of 2D vectors.
 typedef struct {
@@ -16,10 +19,11 @@ typedef struct {
 } Vec2;
 
 // Vector manupulation.
-void vect_cset(Vec2* v, double x, double y);
-void vect_pset(Vec2* v, double mod, double angle);
+void vect_cset(Vec2* v, const double x, const double y);
+void vect_pset(Vec2* v, const double mod, const double angle);
 void vectcpy(Vec2* dest, const Vec2* src);
 void vectnull(Vec2* v);
+double vect_angle(const Vec2* ref, const Vec2* v);
 
 // Describe any solid in 2D space.
 struct Solid {
diff --git a/src/pilot.c b/src/pilot.c
index d7077b0..7256c4a 100644
--- a/src/pilot.c
+++ b/src/pilot.c
@@ -83,7 +83,7 @@ void pilot_init(Pilot* pilot, Ship* ship, char* name, const Vec2* vel, const Vec
   pilot->energy = ship->energy;
 
   // Initially idle.
-  pilot->action = NULL;
+  pilot->task = NULL;
 
   if(flags & PILOT_PLAYER) {
     pilot->think = (void*)player_think; // Players don't need to thing! :P
diff --git a/src/pilot.h b/src/pilot.h
index f8d3cb4..16f75d7 100644
--- a/src/pilot.h
+++ b/src/pilot.h
@@ -1,25 +1,11 @@
 #pragma once
 #include "def.h"
 #include "physics.h"
+#include "ai.h"
 #include "ship.h"
 
 #define PILOT_PLAYER    1 // Pilot is a player.
 
-// =========================================================
-// AI:
-// Ai is based on an action list which contains the current
-// action (FIFO). Actions will run the appropriate Lua code.
-// =========================================================
-typedef enum { ACT_ATTACK, ACT_TRAVEL, ACT_BRAKE } action_type;
-
-// Actions.
-struct Action {
-  struct Action* next;
-  action_type type;
-  void* target;
-};
-typedef struct Action Action;
-
 // Primary pilot structure.
 struct Pilot {
   unsigned int id; // Pilots id.
@@ -38,7 +24,7 @@ struct Pilot {
 
   // AI.
   void (*think)(struct Pilot*); // Ai thinking for the pilot.
-  Action* action; // Current action.
+  Task* task; // Current action.
 };
 typedef struct Pilot Pilot;