shithub: sce

Download patch

ref: 74c69f3ae34bd47609e5e3b82038d1a18143fd17
parent: 3f13cbdf07b968edf21e58ebe71884f7072fb816
author: qwx <[email protected]>
date: Mon Jun 28 20:00:54 EDT 2021

rename Obj → Unit

Unit: movable object assigned to a team
Obj: superset entity: neutral and/or immovable objects

briefly considered naming them Dingus, but dictionary
definition makes it not applicable (they are named).
you know, for giggles?

--- a/com.c
+++ b/com.c
@@ -58,11 +58,11 @@
 	return n;
 }
 
-static Mobj *
-getmobj(Mobj *r)
+static Munit *
+getmunit(Munit *r)
 {
 	int n;
-	Mobj *mo;
+	Munit *mu;
 	Team *t;
 
 	n = r->idx >> Teamshift & Nteam - 1;
@@ -72,18 +72,18 @@
 	}
 	t = teams + n;
 	n = r->idx & Teamidxmask;
-	if(n > t->sz || (mo = t->mo[n]) == nil){
-		werrstr("obj index %d out of bounds", n);
+	if(n > t->sz || (mu = t->mu[n]) == nil){
+		werrstr("unit index %d out of bounds", n);
 		return nil;
 	}
-	if(mo->idx != r->idx || mo->uuid != r->uuid
-	|| mo->x != r->x || mo->y != r->y){
+	if(mu->idx != r->idx || mu->uuid != r->uuid
+	|| mu->x != r->x || mu->y != r->y){
 		werrstr("phase error: %s at %d,%d has %#ux,%ld, req has %d,%d %#ux,%ld",
-			mo->o->name, mo->x, mo->y, mo->idx, mo->uuid,
+			mu->u->name, mu->x, mu->y, mu->idx, mu->uuid,
 			r->x, r->y, r->idx, r->uuid);
 		return nil;
 	}
-	return mo;
+	return mu;
 }
 
 static int
@@ -91,7 +91,7 @@
 {
 	int n;
 	Point click;
-	Mobj reqm, reqt, *mo, *tgt;
+	Munit reqm, reqt, *mu, *tgt;
 
 	if((n = unpack(p, e, "dldd dd dldd",
 	&reqm.idx, &reqm.uuid, &reqm.x, &reqm.y,
@@ -98,15 +98,15 @@
 	&click.x, &click.y,
 	&reqt.idx, &reqt.uuid, &reqt.x, &reqt.y)) < 0)
 		goto error;
-	if((mo = getmobj(&reqm)) == nil)
+	if((mu = getmunit(&reqm)) == nil)
 		goto error;
-	if((tgt = getmobj(&reqt)) == nil)
+	if((tgt = getmunit(&reqt)) == nil)
 		goto error;
 	if(click.x >= nodemapwidth || click.y >= nodemapheight){
 		werrstr("reqmove: invalid location %d,%d", click.x, click.y);
 		return -1;
 	}
-	moveone(click, mo, tgt);
+	moveone(click, mu, tgt);
 	return n;
 error:
 	return -1;
@@ -117,19 +117,19 @@
 {
 	int n;
 	Point tgt;
-	Mobj reqm, *mo;
+	Munit reqm, *mu;
 
 	if((n = unpack(p, e, "dldd dd",
 	&reqm.idx, &reqm.uuid, &reqm.x, &reqm.y,
 	&tgt.x, &tgt.y)) < 0)
 		goto error;
-	if((mo = getmobj(&reqm)) == nil)
+	if((mu = getmunit(&reqm)) == nil)
 		goto error;
 	if(tgt.x >= nodemapwidth || tgt.y >= nodemapheight){
 		werrstr("reqmove: invalid target %d,%d", tgt.x, tgt.y);
 		return -1;
 	}
-	moveone(tgt, mo, nil);
+	moveone(tgt, mu, nil);
 	return n;
 error:
 	return -1;
@@ -257,13 +257,13 @@
 }
 
 int
-sendmovenear(Mobj *mo, Point click, Mobj *tgt)
+sendmovenear(Munit *mu, Point click, Munit *tgt)
 {
 	Msg *m;
 
 	m = getclbuf();
 	if(packmsg(m, "h dldd dd dldd", Tmovenear,
-	mo->idx, mo->uuid, mo->x, mo->y,
+	mu->idx, mu->uuid, mu->x, mu->y,
 	click.x, click.y,
 	tgt->idx, tgt->uuid, tgt->x, tgt->y) < 0){
 		fprint(2, "sendmovenear: %r\n");
@@ -273,13 +273,13 @@
 }
 
 int
-sendmove(Mobj *mo, Point tgt)
+sendmove(Munit *mu, Point tgt)
 {
 	Msg *m;
 
 	m = getclbuf();
 	if(packmsg(m, "h dldd dd", Tmove,
-	mo->idx, mo->uuid, mo->x, mo->y,
+	mu->idx, mu->uuid, mu->x, mu->y,
 	tgt.x, tgt.y) < 0){
 		fprint(2, "sendmove: %r\n");
 		return -1;
--- a/dat.h
+++ b/dat.h
@@ -4,9 +4,10 @@
 typedef struct Pic Pic;
 typedef struct Pics Pics;
 typedef struct Obj Obj;
+typedef struct Unit Unit;
 typedef struct Path Path;
-typedef struct Mobj Mobj;
-typedef struct Mobjl Mobjl;
+typedef struct Munit Munit;
+typedef struct Munitl Munitl;
 typedef struct Tile Tile;
 typedef struct Map Map;
 typedef struct Resource Resource;
@@ -115,6 +116,9 @@
 	int w;
 	int h;
 	int f;
+};
+struct Unit{
+	Obj;
 	Attack *atk[2];
 	int hp;
 	int def;
@@ -125,7 +129,7 @@
 	double accel;
 	double halt;
 	double turn;
-	Obj **spawn;
+	Unit **spawn;
 	int nspawn;
 };
 struct Path{
@@ -138,8 +142,8 @@
 	Point *pathp;
 	Point *pathe;
 };
-struct Mobj{
-	Obj *o;
+struct Munit{
+	Unit *u;
 	int idx;
 	long uuid;
 	int state;
@@ -153,20 +157,20 @@
 	double Δθ;
 	int Δθs;
 	Path;
-	double u;
-	double v;
+	double vx→;
+	double vy→;
 	double speed;
-	Mobjl *movingp;
-	Mobjl *mobjl;
+	Munitl *movingp;
+	Munitl *munitl;
 	int f;
 	int team;
 	int hp;
 	int xp;
 };
-struct Mobjl{
-	Mobj *mo;
-	Mobjl *l;
-	Mobjl *lp;
+struct Munitl{
+	Munit *mu;
+	Munitl *l;
+	Munitl *lp;
 };
 
 struct Tile{
@@ -174,7 +178,7 @@
 };
 struct Map{
 	Tile *t;
-	Mobjl ml;
+	Munitl ml;
 };
 extern Map *map;
 extern int mapwidth, mapheight;
@@ -189,7 +193,7 @@
 	int r[Nresource];
 	int nunit;
 	int nbuild;
-	Mobj **mo;
+	Munit **mu;
 	int sz;
 	int firstempty;
 };
--- a/drw.c
+++ b/drw.c
@@ -14,8 +14,8 @@
 static Image *fbi;
 static Rectangle selr;
 static Point panmax;
-static Mobj *selected[Nselect];
-static Mobj **visbuf;
+static Munit *selected[Nselect];
+static Munit **visbuf;
 static int nvisbuf, nvis;
 
 enum{
@@ -29,7 +29,7 @@
 };
 typedef struct Drawlist Drawlist;
 struct Drawlist{
-	Mobj **mo;
+	Munit **mu;
 	Pic **pics;
 	int n;
 	int sz;
@@ -72,7 +72,7 @@
 {
 	int i;
 	Point vp;
-	Mobj *mo, *it;
+	Munit *mu, *it;
 
 	it = selected[0];
 	if(!ptinrect(p, selr) || it == nil)
@@ -79,8 +79,8 @@
 		return;
 	vp = divpt(subpt(p, selr.min), scale);
 	i = fbvis[vp.y * fbw + vp.x];
-	mo = i == -1 ? nil : visbuf[i];
-	if(mo == it){
+	mu = i == -1 ? nil : visbuf[i];
+	if(mu == it){
 		dprint("select: %#p not moving to itself\n", it);
 		return;
 	}
@@ -87,12 +87,12 @@
 	p = divpt(addpt(subpt(p, selr.min), pan), scale);
 	p.x /= Nodewidth;
 	p.y /= Nodeheight;
-	if(nodemapwidth - p.x < it->o->w || nodemapheight - p.y < it->o->h){
+	if(nodemapwidth - p.x < it->u->w || nodemapheight - p.y < it->u->h){
 		dprint("select: %#p not moving beyond map edge\n", it);
 		return;
 	}
-	if(mo != nil)
-		sendmovenear(it, p, mo);
+	if(mu != nil)
+		sendmovenear(it, p, mu);
 	else
 		sendmove(it, p);
 }
@@ -101,18 +101,18 @@
 drawhud(void)
 {
 	char s[256];
-	Mobj *mo;
+	Munit *mu;
 
 	draw(screen, Rpt(p0, screen->r.max), display->black, nil, ZP);
-	mo = selected[0];
-	if(mo == nil)
+	mu = selected[0];
+	if(mu == nil)
 		return;
-	snprint(s, sizeof s, "%s %d/%d", mo->o->name, mo->hp, mo->o->hp);
+	snprint(s, sizeof s, "%s %d/%d", mu->u->name, mu->hp, mu->u->hp);
 	string(screen, p0, display->white, ZP, font, s);
 }
 
 static int
-addvis(Mobj *mo)
+addvis(Munit *mu)
 {
 	int i;
 
@@ -121,7 +121,7 @@
 			nvisbuf * sizeof *visbuf);
 		nvisbuf += 16;
 	}
-	visbuf[i] = mo;
+	visbuf[i] = mu;
 	return i;
 }
 
@@ -270,7 +270,7 @@
 	int x, y;
 	u64int *row, v, m;
 	Node *n;
-	Mobj *mo;
+	Munit *mu;
 	Point *p;
 
 	r = Rpt(mulpt(r.min, Node2Tile), mulpt(r.max, Node2Tile));
@@ -293,15 +293,15 @@
 		}
 		n += nodemapwidth - (r.max.x - r.min.x);
 	}
-	if((mo = selected[0]) != nil && mo->pathp != nil){
-		for(p=mo->paths; p<mo->pathe; p++)
+	if((mu = selected[0]) != nil && mu->pathp != nil){
+		for(p=mu->paths; p<mu->pathe; p++)
 			compose(p->x / Nodewidth, p->y / Nodeheight, 0x00ff00);
-		compose(mo->target.x, mo->target.y, 0x00ffff);
+		compose(mu->target.x, mu->target.y, 0x00ffff);
 	}
 }
 
 static Pic *
-frm(Mobj *mo, int type)
+frm(Munit *mu, int type)
 {
 	static int rot17[Nrot] = {
 		0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,
@@ -311,11 +311,11 @@
 	Pics *pp;
 	Pic *p;
 
-	pp = &mo->o->pics[mo->state][type];
+	pp = &mu->u->pics[mu->state][type];
 	if(pp->pic == nil)
 		return nil;
-	frm = pp->iscopy ? mo->freezefrm : tc % pp->nf;
-	θ = mo->θ * 32.0 / 256;
+	frm = pp->iscopy ? mu->freezefrm : tc % pp->nf;
+	θ = mu->θ * 32.0 / 256;
 	switch(pp->nr){
 	case 17: θ = rot17[θ]; break;
 	default: θ = 0; break;
@@ -322,7 +322,7 @@
 	}
 	p = pp->pic[frm];
 	if(pp->teamcol)
-		p += nteam * θ + mo->team - 1;
+		p += nteam * θ + mu->team - 1;
 	else
 		p += θ;
 	return p;
@@ -338,55 +338,55 @@
 }
 
 static void
-drawmobjs(void)
+drawmunits(void)
 {
 	int n;
-	Mobj *mo;
+	Munit *mu;
 	Drawlist *dl;
 
 	for(dl=drawlist; dl<drawlist+DLend; dl++)
 		for(n=0; n<dl->n; n++){
-			mo = dl->mo[n];
+			mu = dl->mu[n];
 			if(dl->noalpha)
-				drawpic(mo->px, mo->py, dl->pics[n], addvis(mo));
+				drawpic(mu->px, mu->py, dl->pics[n], addvis(mu));
 			else
-				drawpicalpha(mo->px, mo->py, dl->pics[n]);
+				drawpicalpha(mu->px, mu->py, dl->pics[n]);
 		}
 }
 
 static void
-addpic(Drawlist *dl, Mobj *mo, int type)
+addpic(Drawlist *dl, Munit *mu, int type)
 {
 	int n;
 	Pic *p;
 
-	if((p = frm(mo, type)) == nil)
+	if((p = frm(mu, type)) == nil)
 		return;
 	if(dl->n >= dl->sz){
 		n = dl->sz * sizeof *dl->pics;
 		dl->pics = erealloc(dl->pics, n + 16 * sizeof *dl->pics, n);
-		dl->mo = erealloc(dl->mo, n + 16 * sizeof *dl->mo, n);
+		dl->mu = erealloc(dl->mu, n + 16 * sizeof *dl->mu, n);
 		dl->sz += 16;
 	}
 	n = dl->n++;
 	dl->pics[n] = p;
-	dl->mo[n] = mo;
+	dl->mu[n] = mu;
 }
 
 static void
-addmobjs(Map *m)
+addmunits(Map *m)
 {
 	int air;
-	Mobj *mo;
-	Mobjl *ml;
+	Munit *mu;
+	Munitl *ml;
 
 	for(ml=m->ml.l; ml!=&m->ml; ml=ml->l){
-		mo = ml->mo;
-		air = mo->o->f & Fair;
-		addpic(drawlist + (air ? DLairshad : DLgndshad), mo, PTshadow);
-		addpic(drawlist + (air ? DLair : DLgnd), mo, PTbase);
-		if(mo->state == OSmove)
-			addpic(drawlist + (air ? DLairglow : DLgndglow), mo, PTglow);
+		mu = ml->mu;
+		air = mu->u->f & Fair;
+		addpic(drawlist + (air ? DLairshad : DLgndshad), mu, PTshadow);
+		addpic(drawlist + (air ? DLair : DLgnd), mu, PTbase);
+		if(mu->state == OSmove)
+			addpic(drawlist + (air ? DLairglow : DLgndglow), mu, PTglow);
 	}
 }
 
@@ -425,11 +425,11 @@
 	for(y=r.min.y, m=map+y*mapwidth+r.min.x; y<r.max.y; y++){
 		for(x=r.min.x; x<r.max.x; x++, m++){
 			drawpic(x*Tilewidth, y*Tileheight, m->t->p, -1);
-			addmobjs(m);
+			addmunits(m);
 		}
 		m += mapwidth - (r.max.x - r.min.x);
 	}
-	drawmobjs();
+	drawmunits();
 	if(debugmap)
 		drawmap(r);
 	drawhud();
--- a/fns.h
+++ b/fns.h
@@ -3,13 +3,13 @@
 void	initnet(char*);
 int	parsemsg(Msg*);
 void	endmsg(Msg*);
-int	sendmovenear(Mobj*, Point, Mobj*);
-int	sendmove(Mobj*, Point);
+int	sendmovenear(Munit*, Point, Munit*);
+int	sendmove(Munit*, Point);
 int	sendpause(void);
 void	stepsnd(void);
 void	initsnd(void);
-void	linktomap(Mobj*);
-int	moveone(Point, Mobj*, Mobj*);
+void	linktomap(Munit*);
+int	moveone(Point, Munit*, Munit*);
 void	stepsim(void);
 void	initsim(void);
 void	initsv(int, char*);
@@ -26,14 +26,14 @@
 void	drawfb(void);
 void	initimg(void);
 void	initfs(void);
-void	setgoal(Point*, Mobj*, Mobj*);
-Mobj*	unitat(int, int);
-int	isblocked(int, int, Obj*);
-void	markmobj(Mobj*, int);
-int	findpath(Point, Mobj*);
-Mobj*	mapspawn(int, int, Obj*);
+void	setgoal(Point*, Munit*, Munit*);
+Munit*	unitat(int, int);
+int	isblocked(int, int, Unit*);
+void	markmunit(Munit*, int);
+int	findpath(Point, Munit*);
+Munit*	mapspawn(int, int, Unit*);
 void	initmap(void);
-int	spawn(int, int, Obj*, int);
+int	spawn(int, int, Unit*, int);
 void	nukequeue(Pairheap**);
 Pairheap*	popqueue(Pairheap**);
 void	decreasekey(Pairheap*, double, Pairheap**);
--- a/fs.c
+++ b/fs.c
@@ -9,11 +9,11 @@
 Resource resources[Nresource];
 
 typedef struct Table Table;
-typedef struct Objp Objp;
+typedef struct Unitp Unitp;
 typedef struct Picl Picl;
 typedef struct Tilel Tilel;
-struct Objp{
-	Obj *o;
+struct Unitp{
+	Unit *u;
 	int team;
 	int x;
 	int y;
@@ -43,11 +43,11 @@
 static Tilel tilel0 = {.l = &tilel0}, *tilel = &tilel0;
 static Pic tilesetpic;
 static Picl pic0 = {.l = &pic0}, *pic = &pic0;
-static Objp *objp;
+static Unitp *unitp;
 static Attack *attack;
-static Obj *obj;
+static Unit *unit;
 static char *tileset;
-static int nattack, nobj, nresource, nobjp;
+static int nattack, nunit, nresource, nunitp;
 static u32int bgcol = 0x00ffff;
 static int rot17idx[17] = {
 	0,2,4,6,8,10,12,14,16,17,19,21,23,25,27,29,31
@@ -96,7 +96,7 @@
 }
 
 static void
-loadobjpic(Pic *pic, Picl *pl, char *suff)
+loadunitpic(Pic *pic, Picl *pl, char *suff)
 {
 	int n, i, j;
 	char path[128];
@@ -112,7 +112,7 @@
 			continue;
 		}
 		if(pic0.h % Nteam != 0)
-			sysfatal("loadobjpic: obj %s sprite sheet %d,%d: height not multiple of %d",
+			sysfatal("loadunitpic: unit %s sprite sheet %d,%d: height not multiple of %d",
 				pl->name, pic0.w, pic0.h, Nteam);
 		pic0.h /= Nteam;
 		n = pic0.w * pic0.h;
@@ -162,11 +162,11 @@
 		if(pl->type & PFtile)
 			loadtilepic(p, pl);
 		else if(pl->type & PFshadow)
-			loadobjpic(p, pl, ".s");
+			loadunitpic(p, pl, ".s");
 		else if(pl->type & PFglow)
-			loadobjpic(p, pl, ".g");
+			loadunitpic(p, pl, ".g");
 		else
-			loadobjpic(p, pl, "");
+			loadunitpic(p, pl, "");
 		pic->l = pl->l;
 		free(pl);
 	}
@@ -233,7 +233,7 @@
 	char *s;
 	Attack *atk;
 	Resource *r;
-	Obj *o;
+	Unit *u;
 
 	for(;;){
 		switch(*fmt++){
@@ -275,16 +275,16 @@
 				sysfatal("vunpack: no such resource %s", s);
 			*va_arg(a, Resource**) = r;
 			break;
-		case 'o':
+		case 'u':
 			s = *fld++;
 			if(*s == 0)
-				sysfatal("vunpack: empty obj");
-			for(o=obj; o<obj+nobj; o++)
-				if(o->name != nil && strcmp(s, o->name) == 0)
+				sysfatal("vunpack: empty unit");
+			for(u=unit; u<unit+nunit; u++)
+				if(u->name != nil && strcmp(s, u->name) == 0)
 					break;
-			if(o == obj + nobj)
-				sysfatal("vunpack: no such obj %s", s);
-			*va_arg(a, Obj**) = o;
+			if(u == unit + nunit)
+				sysfatal("vunpack: no such unit %s", s);
+			*va_arg(a, Unit**) = u;
 			break;
 		case 't':
 			s = *fld++;
@@ -311,15 +311,15 @@
 static void
 readspawn(char **fld, int n, Table *)
 {
-	Obj *o, **os, **oe;
+	Unit *u, **us, **ue;
 
-	unpack(fld++, "o", &o);
-	if(o->spawn != nil)
-		sysfatal("readspawn: spawn already assigned for obj %s", *fld);
-	o->spawn = emalloc(--n * sizeof *o->spawn);
-	o->nspawn = n;
-	for(os=o->spawn, oe=os+n; os<oe; os++)
-		unpack(fld++, "o", os);
+	unpack(fld++, "u", &u);
+	if(u->spawn != nil)
+		sysfatal("readspawn: spawn already assigned for unit %s", *fld);
+	u->spawn = emalloc(--n * sizeof *u->spawn);
+	u->nspawn = n;
+	for(us=u->spawn, ue=us+n; us<ue; us++)
+		unpack(fld++, "u", us);
 }
 
 static void
@@ -347,18 +347,18 @@
 }
 
 static void
-readmapobj(char **fld, int, Table *tab)
+readmapunit(char **fld, int, Table *tab)
 {
-	Objp *op;
+	Unitp *up;
 
-	if(objp == nil)
-		objp = emalloc(nobjp * sizeof *objp);
-	op = objp + tab->row;
-	unpack(fld, "oddd", &op->o, &op->team, &op->x, &op->y);
-	if(op->team > nelem(teams))
-		op->team = 0;
-	if(op->team > nteam)
-		nteam = op->team;
+	if(unitp == nil)
+		unitp = emalloc(nunitp * sizeof *unitp);
+	up = unitp + tab->row;
+	unpack(fld, "uddd", &up->u, &up->team, &up->x, &up->y);
+	if(up->team > nelem(teams))
+		up->team = 0;
+	if(up->team > nteam)
+		nteam = up->team;
 }
 
 static void
@@ -386,24 +386,24 @@
 }
 
 static void
-readobj(char **fld, int, Table *tab)
+readunit(char **fld, int, Table *tab)
 {
-	Obj *o;
+	Unit *u;
 
-	if(obj == nil)
-		obj = emalloc(nobj * sizeof *obj);
-	o = obj + tab->row;
-	o->name = estrdup(*fld++);
-	unpack(fld, "ddddddddddaaffff", &o->f, &o->w, &o->h,
-		&o->hp, &o->def, &o->vis,
-		o->cost, o->cost+1, o->cost+2, &o->time,
-		o->atk, o->atk+1, &o->speed, &o->accel, &o->halt, &o->turn);
-	o->accel /= 256.0;
-	o->halt /= 256.0;
+	if(unit == nil)
+		unit = emalloc(nunit * sizeof *unit);
+	u = unit + tab->row;
+	u->name = estrdup(*fld++);
+	unpack(fld, "ddddddddddaaffff", &u->f, &u->w, &u->h,
+		&u->hp, &u->def, &u->vis,
+		u->cost, u->cost+1, u->cost+2, &u->time,
+		u->atk, u->atk+1, &u->speed, &u->accel, &u->halt, &u->turn);
+	u->accel /= 256.0;
+	u->halt /= 256.0;
 	/* halting distance in path node units */
-	o->halt /= Nodewidth;
-	if(o->w < 1 || o->h < 1)
-		sysfatal("readobj: %s invalid dimensions %d,%d", o->name, o->w, o->h);
+	u->halt /= Nodewidth;
+	if(u->w < 1 || u->h < 1)
+		sysfatal("readunit: %s invalid dimensions %d,%d", u->name, u->w, u->h);
 }
 
 static void
@@ -410,20 +410,20 @@
 readspr(char **fld, int n, Table *)
 {
 	int type, frm, nr;
-	Obj *o;
+	Unit *u;
 	Pics *ps;
 	Pic ***ppp, **p, **pe;
 
 	if(n < 4)
-		sysfatal("readspr %s: %d fields < 4 mandatory columns", o->name, n);
-	unpack(fld, "odd", &o, &type, &nr);
+		sysfatal("readspr %s: %d fields < 4 mandatory columns", u->name, n);
+	unpack(fld, "udd", &u, &type, &nr);
 	fld += 3;
 	n -= 3;
 	ps = nil;
 	switch(type & 0xf){
-	case PFidle: ps = o->pics[OSidle]; break;
-	case PFmove: ps = o->pics[OSmove]; break;
-	default: sysfatal("readspr %s: invalid type %#02ux", o->name, type & 0x7e);
+	case PFidle: ps = u->pics[OSidle]; break;
+	case PFmove: ps = u->pics[OSmove]; break;
+	default: sysfatal("readspr %s: invalid type %#02ux", u->name, type & 0x7e);
 	}
 	if(type & PFshadow)
 		ps += PTshadow;
@@ -433,9 +433,9 @@
 		ps += PTbase;
 	ppp = &ps->pic;
 	if(*ppp != nil)
-		sysfatal("readspr %s: pic type %#ux already allocated", o->name, type);
+		sysfatal("readspr %s: pic type %#ux already allocated", u->name, type);
 	if(ps->nf != 0 && ps->nf != n || ps->nr != 0 && ps->nr != nr)
-		sysfatal("readspr %s: spriteset phase error", o->name);
+		sysfatal("readspr %s: spriteset phase error", u->name);
 	ps->teamcol = (type & (PFshadow|PFtile|PFglow)) == 0;
 	ps->nf = n;
 	ps->nr = nr;
@@ -443,13 +443,13 @@
 	*ppp = p;
 	for(pe=p+n; p<pe; p++){
 		unpack(fld++, "d", &frm);
-		*p = pushpic(o->name, frm, type, nr, ps->teamcol);
+		*p = pushpic(u->name, frm, type, nr, ps->teamcol);
 	}
 }
 
 enum{
-	Tmapobj,
-	Tobj,
+	Tmapunit,
+	Tunit,
 	Tattack,
 	Tresource,
 	Tspawn,
@@ -458,8 +458,8 @@
 	Tspr,
 };
 Table table[] = {
-	[Tmapobj] {"mapobj", readmapobj, 4, &nobjp},
-	[Tobj] {"obj", readobj, 17, &nobj},
+	[Tmapunit] {"mapunit", readmapunit, 4, &nunitp},
+	[Tunit] {"unit", readunit, 17, &nunit},
 	[Tattack] {"attack", readattack, 4, &nattack},
 	[Tresource] {"resource", readresource, 2, &nresource},
 	[Tspawn] {"spawn", readspawn, -1, nil},
@@ -546,17 +546,17 @@
 }
 
 static void
-initmapobj(void)
+initmapunit(void)
 {
-	Objp *op;
+	Unitp *up;
 	Map *m;
 
 	for(m=map; m<map+mapwidth*mapheight; m++)
 		m->ml.l = m->ml.lp = &m->ml;
-	for(op=objp; op<objp+nobjp; op++)
-		if(spawn(op->x * Node2Tile, op->y * Node2Tile, op->o, op->team) < 0)
-			sysfatal("initmapobj: %s team %d: %r", op->o->name, op->team);
-	free(objp);
+	for(up=unitp; up<unitp+nunitp; up++)
+		if(spawn(up->x * Node2Tile, up->y * Node2Tile, up->u, up->team) < 0)
+			sysfatal("initmapunit: %s team %d: %r", up->u->name, up->team);
+	free(unitp);
 }
 
 static void
@@ -571,18 +571,18 @@
 }
 
 static void
-fixobjspr(void)
+fixunitspr(void)
 {
-	Obj *o;
+	Unit *u;
 	Pics *idle, *move;
 
-	for(o=obj; o<obj+nobj; o++){
-		if(o->f & Fbuild)
+	for(u=unit; u<unit+nunit; u++){
+		if(u->f & Fbuild)
 			continue;
-		idle = o->pics[OSidle];
-		move = o->pics[OSmove];
+		idle = u->pics[OSidle];
+		move = u->pics[OSmove];
 		if(idle[PTbase].pic == nil && move[PTbase].pic == nil)
-			sysfatal("obj %s: no base sprites loaded", o->name);
+			sysfatal("unit %s: no base sprites loaded", u->name);
 		if(idle[PTbase].pic == nil){
 			memcpy(idle+PTbase, move+PTbase, sizeof *idle);
 			memcpy(idle+PTshadow, move+PTshadow, sizeof *idle);
@@ -616,9 +616,9 @@
 {
 	checkdb();
 	initmap();
-	initmapobj();
+	initmapunit();
 	cleanup();
-	fixobjspr();
+	fixunitspr();
 }
 
 void
--- a/map.c
+++ b/map.c
@@ -10,39 +10,39 @@
 int nodemapwidth, nodemapheight;
 
 static void
-updatemap(Mobj *mo)
+updatemap(Munit *mu)
 {
-	Mobj *bmo;
+	Munit *bmu;
 
-	if(isblocked(mo->x, mo->y, mo->o)){
-		bmo = unitat(mo->x, mo->y);
-		sysfatal("markmobj: attempt to place %s at %d,%d, non-free block having %s at %d,%d",
-			mo->o->name, mo->x, mo->y, bmo->o->name, bmo->x, bmo->y);
+	if(isblocked(mu->x, mu->y, mu->u)){
+		bmu = unitat(mu->x, mu->y);
+		sysfatal("markmunit: attempt to place %s at %d,%d, non-free block having %s at %d,%d",
+			mu->u->name, mu->x, mu->y, bmu->u->name, bmu->x, bmu->y);
 	}
-	linktomap(mo);
-	markmobj(mo, 1);
+	linktomap(mu);
+	markmunit(mu, 1);
 }
 
 static int
-findspawn(int *nx, int *ny, int ofs, Obj *o, Obj *spawn)
+findspawn(int *nx, int *ny, int ofs, Unit *u, Unit *spawn)
 {
 	int x, y, minx, miny, maxx, maxy;
 
-	minx = *nx - (ofs+1) * o->w;
-	miny = *ny - (ofs+1) * o->h;
-	maxx = *nx + spawn->w + ofs * o->w;
-	maxy = *ny + spawn->h + ofs * o->h;
-	for(x=minx+o->w, y=maxy; x<maxx; x++)
-		if(!isblocked(x, y, o))
+	minx = *nx - (ofs+1) * u->w;
+	miny = *ny - (ofs+1) * u->h;
+	maxx = *nx + spawn->w + ofs * u->w;
+	maxy = *ny + spawn->h + ofs * u->h;
+	for(x=minx+u->w, y=maxy; x<maxx; x++)
+		if(!isblocked(x, y, u))
 			goto found;
 	for(x=maxx, y=maxy; y>miny; y--)
-		if(!isblocked(x, y, o))
+		if(!isblocked(x, y, u))
 			goto found;
 	for(x=maxx, y=miny; x>minx; x--)
-		if(!isblocked(x, y, o))
+		if(!isblocked(x, y, u))
 			goto found;
 	for(x=minx, y=miny; y<=maxy; y++)
-		if(!isblocked(x, y, o))
+		if(!isblocked(x, y, u))
 			goto found;
 	return -1;
 found:
@@ -52,41 +52,41 @@
 }
 
 static int
-getspawn(int *nx, int *ny, Obj *o)
+getspawn(int *nx, int *ny, Unit *u)
 {
 	int n, x, y;
 	Map *m;
-	Mobjl *ml;
-	Mobj *mo;
-	Obj **os;
+	Munitl *ml;
+	Munit *mu;
+	Unit **us;
 
 	x = *nx;
 	y = *ny;
-	if(o->f & Fbuild){
-		if(isblocked(x, y, o)){
+	if(u->f & Fbuild){
+		if(isblocked(x, y, u)){
 			werrstr("getspawn: building placement at %d,%d blocked", x, y);
 			return -1;
 		}
 	}else{
 		m = map + y / Node2Tile * mapwidth + x / Node2Tile;
-		for(mo=nil, ml=m->ml.l; ml!=&m->ml; ml=ml->l){
-			mo = ml->mo;
-			for(os=mo->o->spawn, n=mo->o->nspawn; n>0; n--, os++)
-				if(*os == o)
+		for(mu=nil, ml=m->ml.l; ml!=&m->ml; ml=ml->l){
+			mu = ml->mu;
+			for(us=mu->u->spawn, n=mu->u->nspawn; n>0; n--, us++)
+				if(*us == u)
 					break;
 			if(n > 0)
 				break;
 		}
 		if(ml == &m->ml){
-			werrstr("getspawn: no spawn object at %d,%d", x, y);
+			werrstr("getspawn: no spawn unit at %d,%d", x, y);
 			return -1;
 		}
 		for(n=0; n<3; n++)
-			if(findspawn(&x, &y, n, o, mo->o) >= 0)
+			if(findspawn(&x, &y, n, u, mu->u) >= 0)
 				break;
 		if(n == 3){
 			werrstr("getspawn: no free spot for %s at %d,%d",
-				o->name, x, y);
+				u->name, x, y);
 			return -1;
 		}
 	}
@@ -95,31 +95,31 @@
 	return 0;
 }
 
-Mobj *
-mapspawn(int x, int y, Obj *o)
+Munit *
+mapspawn(int x, int y, Unit *u)
 {
-	Mobj *mo;
+	Munit *mu;
 
-	if(o->f & Fbuild && (x & Node2Tile-1 || y & Node2Tile-1)){
+	if(u->f & Fbuild && (x & Node2Tile-1 || y & Node2Tile-1)){
 		werrstr("mapspawn: building spawn %d,%d not aligned to tile map", x, y);
 		return nil;
 	}
-	if(getspawn(&x, &y, o) < 0)
+	if(getspawn(&x, &y, u) < 0)
 		return nil;
-	mo = emalloc(sizeof *mo);
-	mo->uuid = lrand();
-	mo->x = x;
-	mo->y = y;
-	mo->px = x * Nodewidth;
-	mo->py = y * Nodeheight;
-	mo->subpx = mo->px << Subpxshift;
-	mo->subpy = mo->py << Subpxshift;
-	mo->o = o;
-	mo->f = o->f;
-	mo->hp = o->hp;
-	mo->θ = frand() * 256;
-	updatemap(mo);
-	return mo;
+	mu = emalloc(sizeof *mu);
+	mu->uuid = lrand();
+	mu->x = x;
+	mu->y = y;
+	mu->px = x * Nodewidth;
+	mu->py = y * Nodeheight;
+	mu->subpx = mu->px << Subpxshift;
+	mu->subpy = mu->py << Subpxshift;
+	mu->u = u;
+	mu->f = u->f;
+	mu->hp = u->hp;
+	mu->θ = frand() * 256;
+	updatemap(mu);
+	return mu;
 }
 
 void
--- a/path.c
+++ b/path.c
@@ -67,24 +67,24 @@
 }
 
 int
-isblocked(int x, int y, Obj *o)
+isblocked(int x, int y, Unit *u)
 {
 	u64int *row;
 
-	if(o->f & Fair)
+	if(u->f & Fair)
 		return 0;
-	row = bload(x, y, o->w, o->h, 0, 0, 0, 0);
+	row = bload(x, y, u->w, u->h, 0, 0, 0, 0);
 	return (*row & 1ULL << 63) != 0;
 }
 
-Mobj *
+Munit *
 unitat(int px, int py)
 {
 	int x, y;
 	Rectangle r, mr;
 	Map *m;
-	Mobjl *ml;
-	Mobj *mo;
+	Munitl *ml;
+	Munit *mu;
 
 	x = px / Node2Tile;
 	y = py / Node2Tile;
@@ -92,32 +92,32 @@
 	for(; y>=r.min.y; y--)
 		for(x=r.max.x, m=map+y*mapwidth+x; x>=r.min.x; x--)
 			for(ml=m->ml.l; ml!=&m->ml; ml=ml->l){
-				mo = ml->mo;
-				mr.min.x = mo->x;
-				mr.min.y = mo->y;
-				mr.max.x = mr.min.x + mo->o->w;
-				mr.max.y = mr.min.y + mo->o->h;
-				if(px >= mo->x && px <= mo->x + mo->o->w
-				&& py >= mo->y && py <= mo->y + mo->o->h)
-					return mo;
+				mu = ml->mu;
+				mr.min.x = mu->x;
+				mr.min.y = mu->y;
+				mr.max.x = mr.min.x + mu->u->w;
+				mr.max.y = mr.min.y + mu->u->h;
+				if(px >= mu->x && px <= mu->x + mu->u->w
+				&& py >= mu->y && py <= mu->y + mu->u->h)
+					return mu;
 			}
 	return nil;
 }
 
 void
-markmobj(Mobj *mo, int set)
+markmunit(Munit *mu, int set)
 {
 	int w, h;
 
-	if(mo->o->f & Fair)
+	if(mu->u->f & Fair)
 		return;
-	w = mo->o->w;
-	if((mo->subpx & Subpxmask) != 0 && mo->x != (mo->px + 1) / Nodewidth)
+	w = mu->u->w;
+	if((mu->subpx & Subpxmask) != 0 && mu->x != (mu->px + 1) / Nodewidth)
 		w++;
-	h = mo->o->h;
-	if((mo->subpy & Subpxmask) != 0 && mo->y != (mo->py + 1) / Nodewidth)
+	h = mu->u->h;
+	if((mu->subpy & Subpxmask) != 0 && mu->y != (mu->py + 1) / Nodewidth)
 		h++;
-	bset(mo->x, mo->y, w, h, set);
+	bset(mu->x, mu->y, w, h, set);
 }
 
 static double
@@ -358,7 +358,7 @@
 }
 
 static Node *
-a∗(Node *a, Node *b, Mobj *mo)
+a∗(Node *a, Node *b, Munit *mu)
 {
 	double g, Δg;
 	Node *x, *n, **dp;
@@ -377,7 +377,7 @@
 		if(x == b)
 			break;
 		x->closed = 1;
-		dp = successors(x, mo->o->w, mo->o->h, b);
+		dp = successors(x, mu->u->w, mu->u->h, b);
 		for(n=*dp++; n!=nil; n=*dp++){
 			if(n->closed)
 				continue;
@@ -406,46 +406,46 @@
 }
 
 static void
-resizepathbuf(Mobj *mo, int nstep)
+resizepathbuf(Munit *mu, int nstep)
 {
-	if(mo->npathbuf >= nstep)
+	if(mu->npathbuf >= nstep)
 		return;
 	nstep = nstep + 16;
-	mo->paths = erealloc(mo->paths, nstep * sizeof mo->paths, mo->npathbuf * sizeof mo->paths);
-	mo->npathbuf = nstep;
+	mu->paths = erealloc(mu->paths, nstep * sizeof mu->paths, mu->npathbuf * sizeof mu->paths);
+	mu->npathbuf = nstep;
 }
 
 static void
-directpath(Node *a, Node *g, Mobj *mo)
+directpath(Node *a, Node *g, Munit *mu)
 {
-	resizepathbuf(mo, 1);
-	mo->pathlen = eucdist(a, g);
-	mo->pathe = mo->paths + 1;
-	mo->paths->x = g->x * Nodewidth;
-	mo->paths->y = g->y * Nodewidth;
+	resizepathbuf(mu, 1);
+	mu->pathlen = eucdist(a, g);
+	mu->pathe = mu->paths + 1;
+	mu->paths->x = g->x * Nodewidth;
+	mu->paths->y = g->y * Nodewidth;
 }
 
 static void
-backtrack(Node *n, Node *a, Mobj *mo)
+backtrack(Node *n, Node *a, Munit *mu)
 {
 	int x, y;
 	Point *p;
 
 	assert(n != a && n->step > 0);
-	resizepathbuf(mo, n->step);
-	mo->pathlen = n->len;
-	p = mo->paths + n->step;
-	mo->pathe = p--;
+	resizepathbuf(mu, n->step);
+	mu->pathlen = n->len;
+	p = mu->paths + n->step;
+	mu->pathe = p--;
 	for(; n!=a; n=n->from){
 		x = n->x * Nodewidth;
 		y = n->y * Nodeheight;
 		*p-- = (Point){x, y};
 	}
-	assert(p == mo->paths - 1);
+	assert(p == mu->paths - 1);
 }
 
 static Node *
-nearestnonjump(Node *n, Node *b, Mobj *mo)
+nearestnonjump(Node *n, Node *b, Munit *mu)
 {
 	static Point dirtab[] = {
 		{0,-1},
@@ -460,7 +460,7 @@
 	for(i=0; i<nelem(dirtab); i++){
 		x = n->x + dirtab[i].x;
 		y = n->y + dirtab[i].y;
-		while(!isblocked(x, y, mo->o)){
+		while(!isblocked(x, y, mu->u)){
 			m = nodemap + y * nodemapwidth + x;
 			m->x = x;
 			m->y = y;
@@ -481,17 +481,17 @@
 }
 
 void
-setgoal(Point *p, Mobj *mo, Mobj *block)
+setgoal(Point *p, Munit *mu, Munit *block)
 {
 	int x, y, e;
 	double Δ, Δ´;
 	Node *n1, *n2, *pm;
 
-	if(mo->o->f & Fair || block == nil){
-		mo->goalblocked = 0;
+	if(mu->u->f & Fair || block == nil){
+		mu->goalblocked = 0;
 		return;
 	}
-	mo->goalblocked = 1;
+	mu->goalblocked = 1;
 	dprint("setgoal: moving goal %d,%d in block %#p ", p->x, p->y, block);
 	pm = nodemap + p->y * nodemapwidth + p->x;
 	pm->x = p->x;
@@ -500,8 +500,8 @@
 	x = block->x;
 	y = block->y;
 	n1 = nodemap + y * nodemapwidth + x;
-	n2 = n1 + (block->o->h - 1) * nodemapwidth;
-	for(e=x+block->o->w; x<e; x++, n1++, n2++){
+	n2 = n1 + (block->u->h - 1) * nodemapwidth;
+	for(e=x+block->u->w; x<e; x++, n1++, n2++){
 		n1->x = x;
 		n1->y = y;
 		Δ´ = octdist(pm, n1);
@@ -511,19 +511,19 @@
 			p->y = y;
 		}
 		n2->x = x;
-		n2->y = y + block->o->h - 1;
+		n2->y = y + block->u->h - 1;
 		Δ´ = octdist(pm, n2);
 		if(Δ´ < Δ){
 			Δ = Δ´;
 			p->x = x;
-			p->y = y + block->o->h - 1;
+			p->y = y + block->u->h - 1;
 		}
 	}
 	x = block->x;
 	y = block->y + 1;
 	n1 = nodemap + y * nodemapwidth + x;
-	n2 = n1 + block->o->w - 1;
-	for(e=y+block->o->h-2; y<e; y++, n1+=nodemapwidth, n2+=nodemapwidth){
+	n2 = n1 + block->u->w - 1;
+	for(e=y+block->u->h-2; y<e; y++, n1+=nodemapwidth, n2+=nodemapwidth){
 		n1->x = x;
 		n1->y = y;
 		Δ´ = octdist(pm, n1);
@@ -532,12 +532,12 @@
 			p->x = x;
 			p->y = y;
 		}
-		n2->x = x + block->o->w - 1;
+		n2->x = x + block->u->w - 1;
 		n2->y = y;
 		Δ´ = octdist(pm, n2);
 		if(Δ´ < Δ){
 			Δ = Δ´;
-			p->x = x + block->o->w - 1;
+			p->x = x + block->u->w - 1;
 			p->y = y;
 		}
 	}
@@ -545,47 +545,47 @@
 }
 
 int
-findpath(Point p, Mobj *mo)
+findpath(Point p, Munit *mu)
 {
 	Node *a, *b, *n;
 
-	dprint("findpath %d,%d → %d,%d\n", mo->x, mo->y, p.x, p.y);
+	dprint("findpath %d,%d → %d,%d\n", mu->x, mu->y, p.x, p.y);
 	clearpath();
-	a = nodemap + mo->y * nodemapwidth + mo->x;
-	a->x = mo->x;
-	a->y = mo->y;
+	a = nodemap + mu->y * nodemapwidth + mu->x;
+	a->x = mu->x;
+	a->y = mu->y;
 	b = nodemap + p.y * nodemapwidth + p.x;
 	b->x = p.x;
 	b->y = p.y;
-	if(mo->o->f & Fair){
-		directpath(a, b, mo);
+	if(mu->u->f & Fair){
+		directpath(a, b, mu);
 		return 0;
 	}
-	markmobj(mo, 0);
-	n = a∗(a, b, mo);
+	markmunit(mu, 0);
+	n = a∗(a, b, mu);
 	if(n != b){
 		dprint("findpath: goal unreachable\n");
 		if((n = nearest) == a || n == nil || a->h < n->h){
 			werrstr("a∗: can't move");
-			markmobj(mo, 1);
+			markmunit(mu, 1);
 			return -1;
 		}
 		dprint("nearest: %#p %d,%d dist %f\n", n, n->x, n->y, n->h);
-		b = nearestnonjump(n, b, mo);
+		b = nearestnonjump(n, b, mu);
 		if(b == a){
 			werrstr("a∗: really can't move");
-			markmobj(mo, 1);
+			markmunit(mu, 1);
 			return -1;
 		}
 		clearpath();
-		a->x = mo->x;
-		a->y = mo->y;
+		a->x = mu->x;
+		a->y = mu->y;
 		b->x = (b - nodemap) % nodemapwidth;
 		b->y = (b - nodemap) / nodemapwidth;
-		if((n = a∗(a, b, mo)) == nil)
+		if((n = a∗(a, b, mu)) == nil)
 			sysfatal("findpath: phase error");
 	}
-	markmobj(mo, 1);
-	backtrack(n, a, mo);
+	markmunit(mu, 1);
+	backtrack(n, a, mu);
 	return 0;
 }
--- a/sce/map1.db
+++ b/sce/map1.db
@@ -15,15 +15,15 @@
 map,7,3,22,18,8,2,16,16,12,14,5,17,23,2,14,1
 map,23,4,2,18,16,1,12,20,20,4,4,4,11,23,24,6
 map,11,15,4,9,23,17,11,8,20,19,10,7,13,14,13,10
-mapobj,control,1,2,2
-mapobj,scv,1,2,2
-mapobj,scv,1,2,2
-mapobj,scv,1,2,2
-mapobj,scv,1,2,2
-mapobj,hatchery,2,10,10
-mapobj,drone,2,10,10
-mapobj,drone,2,10,10
-mapobj,drone,2,10,10
-mapobj,drone,2,10,10
-mapobj,mutalisk,2,10,10
-mapobj,mineral0,1,8,2
+mapunit,control,1,2,2
+mapunit,scv,1,2,2
+mapunit,scv,1,2,2
+mapunit,scv,1,2,2
+mapunit,scv,1,2,2
+mapunit,hatchery,2,10,10
+mapunit,drone,2,10,10
+mapunit,drone,2,10,10
+mapunit,drone,2,10,10
+mapunit,drone,2,10,10
+mapunit,mutalisk,2,10,10
+mapunit,mineral0,1,8,2
--- a/sce/map2.db
+++ b/sce/map2.db
@@ -63,13 +63,13 @@
 map,7,24,10,16,13,16,22,10,20,19,24,20,15,20,20,18,18,20,5,22,19,19,16,1,15,9,1,5,18,20,10,7,18,22,15,11,3,2,4,10,19,15,7,5,6,11,22,18,22,24,14,23,1,9,3,20,12,10,19,5,4,24,21,17
 map,20,14,3,8,24,22,18,18,15,5,21,8,21,6,15,9,5,8,2,2,3,6,1,17,13,3,7,5,9,20,16,4,22,10,14,2,14,18,22,3,3,14,22,2,6,23,3,19,21,5,2,8,23,20,15,3,3,5,22,6,24,15,7,15
 map,7,18,11,4,2,5,16,2,21,19,18,3,22,18,3,20,12,14,12,10,13,18,15,6,18,16,2,16,1,11,6,24,2,15,13,6,19,17,7,16,5,12,2,16,1,22,1,6,17,1,23,13,19,21,17,19,8,19,14,15,10,5,4,1
-mapobj,control,1,3,2
-mapobj,scv,1,3,2
-mapobj,scv,1,3,2
-mapobj,scv,1,3,2
-mapobj,scv,1,3,2
-mapobj,control,2,58,59
-mapobj,scv,2,58,59
-mapobj,scv,2,58,59
-mapobj,scv,2,58,59
-mapobj,scv,2,58,59
+mapunit,control,1,3,2
+mapunit,scv,1,3,2
+mapunit,scv,1,3,2
+mapunit,scv,1,3,2
+mapunit,scv,1,3,2
+mapunit,control,2,58,59
+mapunit,scv,2,58,59
+mapunit,scv,2,58,59
+mapunit,scv,2,58,59
+mapunit,scv,2,58,59
--- a/sce/map3.db
+++ b/sce/map3.db
@@ -255,13 +255,13 @@
 map,11,13,19,8,21,1,2,14,22,15,19,3,8,18,6,7,17,11,16,12,9,15,16,16,12,20,3,9,18,3,13,13,7,12,21,3,23,24,11,4,6,9,3,6,15,12,15,3,4,17,2,3,17,23,24,15,6,19,21,18,24,4,20,21,12,24,10,2,11,10,7,13,12,24,23,24,2,24,7,21,3,11,21,13,22,5,22,8,19,12,10,4,14,6,11,16,13,21,5,17,6,21,2,2,2,22,1,4,7,24,21,2,20,13,18,16,15,24,11,2,18,23,17,9,21,4,12,22,1,15,21,17,15,16,8,4,13,20,19,23,23,5,22,17,21,1,1,11,21,18,11,19,13,21,2,6,8,23,15,16,12,3,22,13,18,16,14,4,8,3,21,12,20,11,24,13,18,23,6,10,15,11,7,1,4,24,12,2,12,7,24,13,18,8,9,10,13,20,6,8,6,10,16,2,20,16,12,1,17,2,2,5,19,15,21,12,14,9,6,22,18,7,8,21,16,23,12,9,16,20,3,22,23,8,9,10,12,10,1,12,10,24,10,9,2,23,9,11,4,4,8,13,15,4,11,17
 map,20,7,19,13,22,7,20,3,24,8,3,16,14,17,21,4,19,20,8,24,1,16,17,21,12,23,4,21,11,12,2,6,14,9,3,10,14,5,8,8,11,18,9,1,9,17,13,3,24,1,7,2,8,24,12,19,15,6,11,7,17,9,6,3,9,21,5,11,15,8,5,18,22,2,24,9,13,15,3,16,13,12,24,8,16,6,10,4,7,13,16,1,1,19,22,8,2,7,16,12,9,6,10,16,3,2,21,13,12,5,2,9,10,23,12,16,6,11,7,2,5,20,15,4,16,8,14,8,1,18,23,5,17,10,18,15,12,18,14,5,9,24,23,3,8,3,13,11,22,6,1,24,17,2,7,5,20,13,14,19,8,7,8,12,8,24,4,7,14,21,9,1,2,16,20,1,12,12,15,15,13,19,23,10,4,9,15,7,19,3,22,18,4,4,23,12,2,13,7,10,11,18,5,22,18,21,20,12,22,6,11,24,17,21,14,24,6,8,18,14,8,18,3,16,15,20,7,1,8,10,14,9,10,14,8,18,3,23,16,1,23,1,18,3,14,10,7,22,19,20,21,16,6,4,3,1
 map,8,2,22,7,11,23,9,21,7,20,13,19,1,23,10,6,19,13,13,11,10,14,22,23,5,5,18,8,3,15,21,6,23,5,24,10,7,11,11,1,5,6,14,6,11,5,3,20,24,6,9,6,2,22,3,12,18,6,18,11,2,2,16,15,3,11,3,14,8,22,13,5,21,7,11,23,10,2,19,23,11,6,12,16,24,4,20,16,12,9,20,7,22,23,20,3,2,11,12,12,22,22,4,23,13,7,10,18,15,5,7,8,8,7,1,4,18,22,6,14,14,14,21,2,8,8,21,7,23,9,24,5,7,22,22,22,11,19,22,23,21,3,21,16,18,5,22,18,7,12,8,2,8,21,11,22,24,11,17,21,8,9,6,3,11,15,12,4,3,8,12,17,15,7,19,7,12,12,3,15,6,21,13,15,18,6,21,16,17,18,6,6,6,6,1,20,21,14,22,16,21,11,3,4,15,15,22,3,14,2,3,14,1,12,17,21,4,12,24,20,12,7,3,21,7,14,16,11,8,18,10,15,2,1,12,20,17,21,1,20,6,3,20,2,11,18,7,24,14,12,12,21,13,24,7,22
-mapobj,control,1,3,3
-mapobj,scv,1,3,3
-mapobj,scv,1,3,3
-mapobj,scv,1,3,3
-mapobj,scv,1,3,3
-mapobj,control,2,249,252
-mapobj,scv,2,249,252
-mapobj,scv,2,249,252
-mapobj,scv,2,249,252
-mapobj,scv,2,249,252
+mapunit,control,1,3,3
+mapunit,scv,1,3,3
+mapunit,scv,1,3,3
+mapunit,scv,1,3,3
+mapunit,scv,1,3,3
+mapunit,control,2,249,252
+mapunit,scv,2,249,252
+mapunit,scv,2,249,252
+mapunit,scv,2,249,252
+mapunit,scv,2,249,252
--- a/sce/sce.db
+++ b/sce/sce.db
@@ -6,17 +6,21 @@
 attack,fusion cutter,5,10,15
 attack,spines,5,10,22
 attack,glave wurm,9,96,30
-# obj: name, flags, w, h, hp, def, vis, cost[3], time, attack[2], speed, accel, halt, turn
-obj,scv,0x3,4,4,60,0,224,1,50,0,20,fusion cutter,,4.92,67,12227,40
-obj,drone,0x1,4,4,40,0,224,1,50,0,20,spines,,4.92,67,12227,40
-obj,mutalisk,0x5,4,4,120,0,224,2,100,100,600,glave wurm,glave wurm,6.67,67,21745,40
-obj,control,0x8,16,12,1500,1,1,10,400,0,1800,,,0,0,0,0
-obj,hatchery,0x8,16,12,1250,1,1,10,300,0,1800,,,0,0,0,0
-obj,mineral0,0x8,8,8,1250,1,1,10,300,0,1800,,,0,0,0,0
-# spawn: objname, [obj..]
+# unit: name, flags, w, h, hp, def, vis, cost[3], time, attack[2], speed, accel, halt, turn
+unit,scv,0x3,4,4,60,0,224,1,50,0,20,fusion cutter,,4.92,67,12227,40
+unit,drone,0x1,4,4,40,0,224,1,50,0,20,spines,,4.92,67,12227,40
+unit,mutalisk,0x5,4,4,120,0,224,2,100,100,600,glave wurm,glave wurm,6.67,67,21745,40
+unit,control,0x8,16,12,1500,1,1,10,400,0,1800,,,0,0,0,0
+unit,hatchery,0x8,16,12,1250,1,1,10,300,0,1800,,,0,0,0,0
+unit,mineral0,0x8,8,8,1250,1,1,10,300,0,1800,,,0,0,0,0
+# gather: name, resource, w, h, state frame, [state frame..]
+gather,mineral0,minerals,12,8,0,1,2,3
+gather,mineral1,minerals,12,8,0,1,2,3
+gather,mineral2,minerals,12,8,0,1,2,3
+# spawn: unitname, [unit..]
 spawn,control,scv
 spawn,hatchery,drone,mutalisk
-# spr: objname, flags (PF enum), rotations, [frame..]
+# spr: unitname, flags (PF enum), rotations, [frame..]
 spr,scv,0x2,17,0
 spr,scv,0xc002,17,0
 spr,scv,0x6004,17,0,1,2,3
@@ -30,5 +34,6 @@
 spr,mutalisk,0xc002,17,0,1,2,3,4
 spr,mutalisk,0x4,17,0,1,2,3,4
 spr,mutalisk,0xc004,17,0,1,2,3,4
+FIXME: flag: not animation frames, but state? or do it some other way; no team
 spr,mineral0,2,1,0
 spr,mineral0,0xc002,1,0
--- a/sim.c
+++ b/sim.c
@@ -9,14 +9,14 @@
 int nteam;
 int initres[Nresource], foodcap;
 
-static Mobjl moving0 = {.l = &moving0, .lp = &moving0}, *moving = &moving0;
+static Munitl moving0 = {.l = &moving0, .lp = &moving0}, *moving = &moving0;
 
-static Mobjl *
-linkmobj(Mobjl *l, Mobj *mo, Mobjl *p)
+static Munitl *
+linkmunit(Munitl *l, Munit *mu, Munitl *p)
 {
 	if(p == nil)
 		p = emalloc(sizeof *p);
-	p->mo = mo;
+	p->mu = mu;
 	p->l = l->l;
 	p->lp = l;
 	l->l->lp = p;
@@ -25,7 +25,7 @@
 }
 
 static void
-unlinkmobj(Mobjl *ml)
+unlinkmunit(Munitl *ml)
 {
 	if(ml == nil || ml->l == nil || ml->lp == nil)
 		return;
@@ -35,55 +35,55 @@
 }
 
 void
-linktomap(Mobj *mo)
+linktomap(Munit *mu)
 {
 	Map *m;
 
-	m = map + mo->y / Node2Tile * mapwidth + mo->x / Node2Tile;
-	mo->mobjl = linkmobj(mo->f & Fair ? m->ml.lp : &m->ml, mo, mo->mobjl);
+	m = map + mu->y / Node2Tile * mapwidth + mu->x / Node2Tile;
+	mu->munitl = linkmunit(mu->f & Fair ? m->ml.lp : &m->ml, mu, mu->munitl);
 }
 
 static void
-refmobj(Mobj *mo)
+refmunit(Munit *mu)
 {
 	int n, i;
 	Team *t;
 
-	t = teams + mo->team;
-	if(mo->f & Fbuild)
+	t = teams + mu->team;
+	if(mu->f & Fbuild)
 		t->nbuild++;
 	else
 		t->nunit++;
 	n = t->firstempty;
 	if(n == t->sz){
-		t->mo = erealloc(t->mo, (t->sz + 32) * sizeof *t->mo, t->sz * sizeof *t->mo);
+		t->mu = erealloc(t->mu, (t->sz + 32) * sizeof *t->mu, t->sz * sizeof *t->mu);
 		t->sz += 32;
 	}
-	t->mo[n] = mo;
-	mo->idx = mo->team << Teamshift | n;
+	t->mu[n] = mu;
+	mu->idx = mu->team << Teamshift | n;
 	for(i=t->firstempty+1; i<t->sz; i++)
-		if(t->mo[i] == nil)
+		if(t->mu[i] == nil)
 			break;
 	t->firstempty = i;
 }
 
 static void
-resetcoords(Mobj *mo)
+resetcoords(Munit *mu)
 {
-	markmobj(mo, 0);
-	mo->subpx = mo->px << Subpxshift;
-	mo->subpy = mo->py << Subpxshift;
-	markmobj(mo, 1);
+	markmunit(mu, 0);
+	mu->subpx = mu->px << Subpxshift;
+	mu->subpy = mu->py << Subpxshift;
+	markmunit(mu, 1);
 }
 
 static double
-facemobj(Point p, Mobj *mo)
+facemunit(Point p, Munit *mu)
 {
 	int dx, dy;
 	double vx, vy, d, θ, θ256, Δθ;
 
-	dx = p.x - mo->px;
-	dy = p.y - mo->py;
+	dx = p.x - mu->px;
+	dy = p.y - mu->py;
 	d = sqrt(dx * dx + dy * dy);
 	vx = dx / d;
 	vy = dy / d;
@@ -95,61 +95,61 @@
 		θ -= 2 * PI;
 	/* movement calculations use values in [0;256[, drawing in [0;32[ */
 	θ256 = θ * 256.0 / (2 * PI);
-	mo->u = vx;
-	mo->v = vy;
-	Δθ = θ256 - mo->θ;
+	mu->vx→ = vx;
+	mu->vy→ = vy;
+	Δθ = θ256 - mu->θ;
 	if(Δθ <= -256 / 2)
 		Δθ += 256;
 	else if(Δθ >= 256 / 2)
 		Δθ -= 256;
-	mo->Δθs = Δθ < 0 ? -1: 1;
-	mo->Δθ = fabs(Δθ);
+	mu->Δθs = Δθ < 0 ? -1: 1;
+	mu->Δθ = fabs(Δθ);
 	return θ256;
 }
 
 static void
-freemove(Mobj *mo)
+freemove(Munit *mu)
 {
-	unlinkmobj(mo->movingp);
-	mo->pathp = nil;
-	mo->freezefrm = tc % mo->o->pics[mo->state][PTbase].nf;
-	mo->state = OSidle;
-	resetcoords(mo);
+	unlinkmunit(mu->movingp);
+	mu->pathp = nil;
+	mu->freezefrm = tc % mu->u->pics[mu->state][PTbase].nf;
+	mu->state = OSidle;
+	resetcoords(mu);
 }
 
 static void
-nextmove(Mobj *mo)
+nextmove(Munit *mu)
 {
-	resetcoords(mo);
-	facemobj(*mo->pathp, mo);
+	resetcoords(mu);
+	facemunit(*mu->pathp, mu);
 }
 
 static int
-repath(Point p, Mobj *mo)
+repath(Point p, Munit *mu)
 {
-	freemove(mo);
-	mo->target = p;
-	if(findpath(p, mo) < 0){
-		mo->θ = facemobj(p, mo);
+	freemove(mu);
+	mu->target = p;
+	if(findpath(p, mu) < 0){
+		mu->θ = facemunit(p, mu);
 		return -1;
 	}
-	mo->movingp = linkmobj(moving, mo, mo->movingp);
-	mo->pathp = mo->paths;
-	mo->state = OSmove;
-	nextmove(mo);
+	mu->movingp = linkmunit(moving, mu, mu->movingp);
+	mu->pathp = mu->paths;
+	mu->state = OSmove;
+	nextmove(mu);
 	return 0;
 }
 
 int
-moveone(Point p, Mobj *mo, Mobj *block)
+moveone(Point p, Munit *mu, Munit *block)
 {
-	if(mo->o->speed == 0){
-		dprint("move: obj %s can't move\n", mo->o->name);
+	if(mu->u->speed == 0){
+		dprint("move: unit %s can't move\n", mu->u->name);
 		return -1;
 	}
-	setgoal(&p, mo, block);
-	if(repath(p, mo) < 0){
-		mo->speed = 0.0;
+	setgoal(&p, mu, block);
+	if(repath(p, mu) < 0){
+		mu->speed = 0.0;
 		dprint("move to %d,%d: %r\n", p.x, p.y);
 		return -1;
 	}
@@ -157,84 +157,84 @@
 }
 
 int
-spawn(int x, int y, Obj *o, int n)
+spawn(int x, int y, Unit *u, int n)
 {
-	Mobj *mo;
+	Munit *mu;
 
-	if((mo = mapspawn(x, y, o)) == nil)
+	if((mu = mapspawn(x, y, u)) == nil)
 		return -1;
-	mo->team = n;
-	mo->state = OSidle;
-	refmobj(mo);
+	mu->team = n;
+	mu->state = OSidle;
+	refmunit(mu);
 	return 0;
 }
 
 static int
-tryturn(Mobj *mo)
+tryturn(Munit *mu)
 {
 	int r;
 	double Δθ;
 
 	r = 1;
-	if(mo->Δθ <= mo->o->turn){
+	if(mu->Δθ <= mu->u->turn){
 		r = 0;
-		Δθ = mo->Δθ;
+		Δθ = mu->Δθ;
 	}else
-		Δθ = mo->o->turn;
-	mo->θ += mo->Δθs * Δθ;
-	if(mo->θ < 0)
-		mo->θ += 256;
-	else if(mo->θ >= 256)
-		mo->θ -= 256;
-	mo->Δθ -= Δθ;
+		Δθ = mu->u->turn;
+	mu->θ += mu->Δθs * Δθ;
+	if(mu->θ < 0)
+		mu->θ += 256;
+	else if(mu->θ >= 256)
+		mu->θ -= 256;
+	mu->Δθ -= Δθ;
 	return r;
 }
 
 static void
-updatespeed(Mobj *mo)
+updatespeed(Munit *mu)
 {
-	if(1 + mo->pathlen < (mo->speed / 8) * (mo->speed / 8) / 2 / (mo->o->accel / 8)){
-		mo->speed -= mo->o->accel;
-		if(mo->speed < 0.0)
-			mo->speed = 0.0;
-	}else if(mo->speed < mo->o->speed){
-		mo->speed += mo->o->accel;
-		if(mo->speed > mo->o->speed)
-			mo->speed = mo->o->speed;
+	if(1 + mu->pathlen < (mu->speed / 8) * (mu->speed / 8) / 2 / (mu->u->accel / 8)){
+		mu->speed -= mu->u->accel;
+		if(mu->speed < 0.0)
+			mu->speed = 0.0;
+	}else if(mu->speed < mu->u->speed){
+		mu->speed += mu->u->accel;
+		if(mu->speed > mu->u->speed)
+			mu->speed = mu->u->speed;
 	}
 }
 
 static int
-trymove(Mobj *mo)
+trymove(Munit *mu)
 {
 	int x, y, px, py, sx, sy, Δx, Δy, Δu, Δv, Δrx, Δry, Δpx, Δpy;
 	double dx, dy;
 
-	markmobj(mo, 0);
-	px = mo->px;
-	py = mo->py;
-	sx = mo->subpx;
-	sy = mo->subpy;
-	Δu = mo->u * (1 << Subpxshift);
-	Δv = mo->v * (1 << Subpxshift);
+	markmunit(mu, 0);
+	px = mu->px;
+	py = mu->py;
+	sx = mu->subpx;
+	sy = mu->subpy;
+	Δu = mu->vx→ * (1 << Subpxshift);
+	Δv = mu->vy→ * (1 << Subpxshift);
 	Δx = abs(Δu);
 	Δy = abs(Δv);
-	Δrx = fabs(mo->u * mo->speed) * (1 << Subpxshift);
-	Δry = fabs(mo->v * mo->speed) * (1 << Subpxshift);
-	Δpx = abs((mo->pathp->x << Subpxshift) - sx);
-	Δpy = abs((mo->pathp->y << Subpxshift) - sy);
+	Δrx = fabs(mu->vx→ * mu->speed) * (1 << Subpxshift);
+	Δry = fabs(mu->vy→ * mu->speed) * (1 << Subpxshift);
+	Δpx = abs((mu->pathp->x << Subpxshift) - sx);
+	Δpy = abs((mu->pathp->y << Subpxshift) - sy);
 	if(Δpx < Δrx)
 		Δrx = Δpx;
 	if(Δpy < Δry)
 		Δry = Δpy;
 	while(Δrx > 0 || Δry > 0){
-		x = mo->x;
-		y = mo->y;
+		x = mu->x;
+		y = mu->y;
 		if(Δrx > 0){
 			sx += Δu;
 			Δrx -= Δx;
 			if(Δrx < 0)
-				sx += mo->u < 0 ? -Δrx : Δrx;
+				sx += mu->vx→ < 0 ? -Δrx : Δrx;
 			x = (sx >> Subpxshift) + ((sx & Subpxmask) != 0);
 			x /= Nodewidth;
 		}
@@ -242,60 +242,60 @@
 			sy += Δv;
 			Δry -= Δy;
 			if(Δry < 0)
-				sy += mo->v < 0 ? -Δry : Δry;
+				sy += mu->vy→ < 0 ? -Δry : Δry;
 			y = (sy >> Subpxshift) + ((sy & Subpxmask) != 0);
 			y /= Nodewidth;
 		}
-		if(isblocked(x, y, mo->o))
+		if(isblocked(x, y, mu->u))
 			goto end;
 		/* disallow corner coasting */
-		if(x != mo->x && y != mo->y
-		&& (isblocked(x, mo->y, mo->o) || isblocked(mo->x, y, mo->o))){
+		if(x != mu->x && y != mu->y
+		&& (isblocked(x, mu->y, mu->u) || isblocked(mu->x, y, mu->u))){
 			dprint("detected corner coasting %d,%d vs %d,%d\n",
-				x, y, mo->x, mo->y);
+				x, y, mu->x, mu->y);
 			goto end;
 		}
-		mo->subpx = sx;
-		mo->subpy = sy;
-		mo->px = sx >> Subpxshift;
-		mo->py = sy >> Subpxshift;
-		mo->x = mo->px / Nodewidth;
-		mo->y = mo->py / Nodeheight;
+		mu->subpx = sx;
+		mu->subpy = sy;
+		mu->px = sx >> Subpxshift;
+		mu->py = sy >> Subpxshift;
+		mu->x = mu->px / Nodewidth;
+		mu->y = mu->py / Nodeheight;
 	}
-	markmobj(mo, 1);
-	dx = mo->px - px;
+	markmunit(mu, 1);
+	dx = mu->px - px;
 	dx *= dx;
-	dy = mo->py - py;
+	dy = mu->py - py;
 	dy *= dy;
-	mo->pathlen -= sqrt(dx + dy) / Nodewidth;
+	mu->pathlen -= sqrt(dx + dy) / Nodewidth;
 	return 0;
 end:
 	werrstr("trymove: can't move to %d,%d", x, y);
-	mo->subpx = mo->px << Subpxshift;
-	mo->subpy = mo->py << Subpxshift;
-	markmobj(mo, 1);
-	dx = mo->px - px;
+	mu->subpx = mu->px << Subpxshift;
+	mu->subpy = mu->py << Subpxshift;
+	markmunit(mu, 1);
+	dx = mu->px - px;
 	dx *= dx;
-	dy = mo->py - py;
+	dy = mu->py - py;
 	dy *= dy;
-	mo->pathlen -= sqrt(dx + dy) / Nodewidth;
+	mu->pathlen -= sqrt(dx + dy) / Nodewidth;
 	return -1;
 }
 
 static int
-domove(Mobj *mo)
+domove(Munit *mu)
 {
 	int r;
 
-	updatespeed(mo);
-	unlinkmobj(mo->mobjl);
-	r = trymove(mo);
-	linktomap(mo);
+	updatespeed(mu);
+	unlinkmunit(mu->munitl);
+	r = trymove(mu);
+	linktomap(mu);
 	return r;
 }
 
 static void
-stepmove(Mobj *mo)
+stepmove(Munit *mu)
 {
 	int n;
 
@@ -302,50 +302,50 @@
 	n = 0;
 restart:
 	n++;
-	if(tryturn(mo))
+	if(tryturn(mu))
 		return;
-	if(domove(mo) < 0){
+	if(domove(mu) < 0){
 		if(n > 1){
 			fprint(2, "stepmove: %s %#p bug inducing infinite loop!\n",
-				mo->o->name, mo);
+				mu->u->name, mu);
 			return;
 		}
 		dprint("stepmove: failed to move: %r\n");
-		if(repath(mo->target, mo) < 0){
+		if(repath(mu->target, mu) < 0){
 			dprint("stepmove: %s %#p moving towards target: %r\n",
-				mo->o->name, mo);
-			mo->speed = 0.0;
+				mu->u->name, mu);
+			mu->speed = 0.0;
 			return;
 		}
 		goto restart;
 	}
-	if(mo->px == mo->pathp->x && mo->py == mo->pathp->y){
-		mo->pathp++;
-		if(mo->pathp < mo->pathe){
-			nextmove(mo);
+	if(mu->px == mu->pathp->x && mu->py == mu->pathp->y){
+		mu->pathp++;
+		if(mu->pathp < mu->pathe){
+			nextmove(mu);
 			return;
-		}else if(mo->x == mo->target.x && mo->y == mo->target.y){
-			mo->npatherr = 0;
-			mo->speed = 0.0;
-			freemove(mo);
+		}else if(mu->x == mu->target.x && mu->y == mu->target.y){
+			mu->npatherr = 0;
+			mu->speed = 0.0;
+			freemove(mu);
 			return;
 		}
 		dprint("stepmove: %s %#p reached final node, but not target\n",
-			mo->o->name, mo);
-		if(mo->goalblocked && isblocked(mo->target.x, mo->target.y, mo->o)){
+			mu->u->name, mu);
+		if(mu->goalblocked && isblocked(mu->target.x, mu->target.y, mu->u)){
 			dprint("stepmove: %s %#p goal still blocked, stopping\n",
-				mo->o->name, mo);
-			mo->speed = 0.0;
-			freemove(mo);
+				mu->u->name, mu);
+			mu->speed = 0.0;
+			freemove(mu);
 			return;
 		}
-		if(mo->npatherr++ > 1
-		|| repath(mo->target, mo) < 0){
+		if(mu->npatherr++ > 1
+		|| repath(mu->target, mu) < 0){
 			dprint("stepmove: %s %#p trying to find target: %r\n",
-				mo->o->name, mo);
-			mo->npatherr = 0;
-			mo->speed = 0.0;
-			freemove(mo);
+				mu->u->name, mu);
+			mu->npatherr = 0;
+			mu->speed = 0.0;
+			freemove(mu);
 		}
 	}
 }
@@ -353,10 +353,10 @@
 void
 stepsim(void)
 {
-	Mobjl *ml, *oml;
+	Munitl *ml, *uml;
 
-	for(oml=moving->l, ml=oml->l; oml!=moving; oml=ml, ml=ml->l)
-		stepmove(oml->mo);
+	for(uml=moving->l, ml=uml->l; uml!=moving; uml=ml, ml=ml->l)
+		stepmove(uml->mu);
 }
 
 void