From 8242e9ed41769d86753bfecf0d2302b7b5671c95 Mon Sep 17 00:00:00 2001
From: Enno Rehling <enno@eressea.de>
Date: Thu, 9 Jun 2005 22:10:35 +0000
Subject: [PATCH] Eressea ist 64-bit ready. Denke ich jedenfalls.

---
 src/common/attributes/attributes.vcproj |   1 +
 src/common/attributes/follow.c          |   7 +-
 src/common/attributes/giveitem.c        |   9 +-
 src/common/attributes/hate.c            |   6 +-
 src/common/attributes/otherfaction.c    |  19 +-
 src/common/attributes/otherfaction.h    |   1 +
 src/common/gamecode/creation.c          |   2 +-
 src/common/gamecode/creport.c           |  44 ++---
 src/common/gamecode/gamecode.vcproj     |   1 +
 src/common/gamecode/items.c             |   4 +-
 src/common/gamecode/laws.c              |  54 +++---
 src/common/gamecode/randenc.c           |   2 +-
 src/common/gamecode/report.c            | 187 +++++++++++++-----
 src/common/items/artrewards.c           |   8 +-
 src/common/items/items.vcproj           |   1 +
 src/common/kernel/Jamfile               |   1 -
 src/common/kernel/battle.c              |  19 +-
 src/common/kernel/border.c              |  93 +++++----
 src/common/kernel/border.h              |   8 +-
 src/common/kernel/building.c            |  23 +--
 src/common/kernel/building.h            |   4 +-
 src/common/kernel/combatspells.c        |   5 +-
 src/common/kernel/curse.c               |  73 +++----
 src/common/kernel/curse.h               |  18 +-
 src/common/kernel/eressea.c             |  85 ++++----
 src/common/kernel/eressea.h             |   4 +-
 src/common/kernel/faction.c             |   5 +-
 src/common/kernel/faction.h             |   2 +-
 src/common/kernel/group.c               |  10 +-
 src/common/kernel/item.c                |  41 ++--
 src/common/kernel/kernel.vcproj         |   4 +-
 src/common/kernel/magic.c               |  53 ++---
 src/common/kernel/message.c             | 115 +++++++----
 src/common/kernel/names.c               |   3 +-
 src/common/kernel/objtypes.c            | 215 ---------------------
 src/common/kernel/objtypes.h            |  27 ---
 src/common/kernel/plane.c               |  42 ++--
 src/common/kernel/plane.h               |  20 +-
 src/common/kernel/region.c              |  61 +++---
 src/common/kernel/region.h              |  24 ++-
 src/common/kernel/reports.c             |   6 +-
 src/common/kernel/save.c                |  46 +++--
 src/common/kernel/save.h                |   2 +-
 src/common/kernel/ship.c                |  12 +-
 src/common/kernel/skill.c               |   6 +-
 src/common/kernel/spell.c               | 247 ++++++++++++++----------
 src/common/kernel/teleport.c            |  18 +-
 src/common/kernel/teleport.h            |   2 +-
 src/common/kernel/unit.c                |  33 ++--
 src/common/kernel/unit.h                |   5 +-
 src/common/modules/arena.c              |  16 +-
 src/common/modules/autoseed.c           |   4 +-
 src/common/modules/gmcmd.c              |  46 ++---
 src/common/modules/gmcmd.h              |   2 +-
 src/common/modules/modules.vcproj       |   1 +
 src/common/races/races.vcproj           |   1 +
 src/common/spells/alp.c                 |   7 +-
 src/common/spells/spells.vcproj         |   1 +
 src/common/spells/unitcurse.c           |  10 +-
 src/common/triggers/createcurse.c       |  18 +-
 src/common/triggers/giveitem.c          |   8 +-
 src/common/triggers/removecurse.c       |  14 +-
 src/common/triggers/triggers.vcproj     |   1 +
 src/common/triggers/unitmessage.c       |   8 +-
 src/common/util/attrib.c                |   2 +-
 src/common/util/command.c               |  14 +-
 src/common/util/crmessage.c             |  16 +-
 src/common/util/crmessage.h             |  10 +-
 src/common/util/cvector.c               |   4 +-
 src/common/util/event.c                 |  22 ---
 src/common/util/event.h                 |   5 +-
 src/common/util/goodies.c               |  19 +-
 src/common/util/goodies.h               |   1 -
 src/common/util/lists.c                 |   4 +-
 src/common/util/lists.h                 |   2 +-
 src/common/util/message.c               |  58 ++----
 src/common/util/message.h               |  21 +-
 src/common/util/resolve.c               |   5 +-
 src/common/util/resolve.h               |  10 +-
 src/common/util/translation.c           | 106 ++++------
 src/common/util/translation.h           |  17 +-
 src/common/util/umlaut.c                |   6 +-
 src/common/util/umlaut.h                |   9 +-
 src/common/util/util.vcproj             |   4 +
 src/common/util/variant.h               |   9 +-
 src/common/util/vmap.c                  |  14 +-
 src/common/util/vmap.h                  |  10 +-
 src/common/util/vset.c                  |   2 +-
 src/common/util/vset.h                  |   2 +-
 src/common/util/windir.h                |   2 +-
 src/eressea/eressea-lua.vcproj          |   1 +
 src/eressea/eressea.vcproj              |   1 +
 src/eressea/korrektur.c                 |   8 +-
 src/eressea/lua/eressea.cpp             |   2 +-
 src/eressea/lua/event.cpp               |   6 +-
 src/eressea/lua/region.cpp              |   4 +-
 src/eressea/main.c                      |   6 +-
 src/eressea/server.cpp                  |   2 +-
 src/mapper/map_region.c                 |   6 +-
 src/mapper/mapper.vcproj                |   1 +
 100 files changed, 1120 insertions(+), 1106 deletions(-)
 delete mode 100644 src/common/kernel/objtypes.c

diff --git a/src/common/attributes/attributes.vcproj b/src/common/attributes/attributes.vcproj
index e557dbb0d..955cc08fd 100644
--- a/src/common/attributes/attributes.vcproj
+++ b/src/common/attributes/attributes.vcproj
@@ -35,6 +35,7 @@
 				ProgramDataBaseFileName=".\Debug/"
 				WarningLevel="4"
 				SuppressStartupBanner="TRUE"
+				Detect64BitPortabilityProblems="TRUE"
 				DebugInformationFormat="1"
 				CompileAs="0"/>
 			<Tool
diff --git a/src/common/attributes/follow.c b/src/common/attributes/follow.c
index 762c533b2..cf3126e9f 100644
--- a/src/common/attributes/follow.c
+++ b/src/common/attributes/follow.c
@@ -20,6 +20,7 @@
 
 #include <attrib.h>
 #include <resolve.h>
+#include <variant.h>
 
 static int
 verify_follow(attrib * a)
@@ -34,9 +35,9 @@ static int
 read_follow(attrib * a, FILE * F)
 {
 	if (global.data_version < BASE36IDS_VERSION) {
-		int i;
-		fscanf(F, "%d", &i);
-		ur_add((void*)i, (void**)&a->data.v, resolve_unit);
+		variant var;
+		fscanf(F, "%d", &var.i);
+		ur_add(var, (void**)&a->data.v, resolve_unit);
 	} else {
 		return read_unit_reference(NULL, F);
 	}
diff --git a/src/common/attributes/giveitem.c b/src/common/attributes/giveitem.c
index c5614196e..7cc19b90d 100644
--- a/src/common/attributes/giveitem.c
+++ b/src/common/attributes/giveitem.c
@@ -53,16 +53,17 @@ static int
 a_readgive(attrib * a, FILE * F)
 {
 	give_data * gdata = (give_data*)a->data.v;
-	int i;
+	variant var;
 	char zText[32];
 
 	if (global.data_version<ITEMTYPE_VERSION) return a_readdefault(a, F);
 
 	fscanf(F, "%s ", zText);
-	i = atoi36(zText);
-	gdata->building = findbuilding(i);
-	if (gdata->building==NULL) ur_add((void*)i, (void**)&gdata->building, resolve_building);
+	var.i = atoi36(zText);
+	gdata->building = findbuilding(var.i);
+	if (gdata->building==NULL) ur_add(var, (void**)&gdata->building, resolve_building);
 	for (;;) {
+    int i;
 		fscanf(F, "%s", zText);
 		if (!strcmp("end", zText)) break;
 		fscanf(F, "%d", &i);
diff --git a/src/common/attributes/hate.c b/src/common/attributes/hate.c
index 7e45bc5e4..4b6d955b5 100644
--- a/src/common/attributes/hate.c
+++ b/src/common/attributes/hate.c
@@ -40,9 +40,9 @@ static int
 read_hate(attrib * a, FILE * F)
 {
 	if (global.data_version < BASE36IDS_VERSION) {
-		int i;
-		fscanf(F, "%d", &i);
-		ur_add((void*)i, (void**)&a->data.v, resolve_unit);
+		variant var;
+		fscanf(F, "%d", &var.i);
+		ur_add(var, (void**)&a->data.v, resolve_unit);
 	} else {
 		return read_unit_reference((unit**)&a->data.v, F);
 	}
diff --git a/src/common/attributes/otherfaction.c b/src/common/attributes/otherfaction.c
index aa984a0bd..aad850969 100644
--- a/src/common/attributes/otherfaction.c
+++ b/src/common/attributes/otherfaction.c
@@ -12,12 +12,15 @@
  */
 
 #include <config.h>
+#include <eressea.h>
 #include "otherfaction.h"
 
-#include <eressea.h>
 #include <faction.h>
+#include <unit.h>
 #include <attrib.h>
 
+#include <assert.h>
+
 /*
  * simple attributes that do not yet have their own file 
  */
@@ -63,3 +66,17 @@ init_otherfaction(void)
 {
 	at_register(&at_otherfaction);
 }
+
+faction *
+visible_faction(const faction *f, const unit * u)
+{
+	if (!alliedunit(u, f, HELP_FSTEALTH)) {
+		attrib *a = a_find(u->attribs, &at_otherfaction);
+		if (a) {
+			faction *fv = get_otherfaction(a);
+			assert (fv != NULL);	/* fv should never be NULL! */
+			return fv;
+		}
+	}
+	return u->faction;
+}
diff --git a/src/common/attributes/otherfaction.h b/src/common/attributes/otherfaction.h
index fa97f31ae..9331a8ee1 100644
--- a/src/common/attributes/otherfaction.h
+++ b/src/common/attributes/otherfaction.h
@@ -21,6 +21,7 @@ extern struct attrib_type at_otherfaction;
 extern void init_otherfaction(void);
 extern struct faction * get_otherfaction(const struct attrib * a);
 extern struct attrib * make_otherfaction(struct faction * f);
+extern struct faction * visible_faction(const struct faction *f, const struct unit * u);
 
 #ifdef __cplusplus
 extern "C" {
diff --git a/src/common/gamecode/creation.c b/src/common/gamecode/creation.c
index 1a3516dc8..0cdc09ab0 100644
--- a/src/common/gamecode/creation.c
+++ b/src/common/gamecode/creation.c
@@ -80,7 +80,7 @@ void
 listnames(void)
 {
 	region *r;
-	int i;
+	size_t i;
 
 	puts("Die Liste der benannten Regionen ist:");
 
diff --git a/src/common/gamecode/creport.c b/src/common/gamecode/creport.c
index e66bc21cd..7ef6941ac 100644
--- a/src/common/gamecode/creport.c
+++ b/src/common/gamecode/creport.c
@@ -277,50 +277,50 @@ print_curses(FILE * F, const faction * viewer, const void * obj, typ_t typ)
 }
 
 static int
-cr_unit(const void * v, char * buffer, const void * userdata)
+cr_unit(variant var, char * buffer, const void * userdata)
 {
 	const faction * report = (const faction*)userdata;
-	unit * u = (unit *)v;
+	unit * u = (unit *)var.v;
 	sprintf(buffer, "%d", u?u->no:-1);
 	unused(report);
 	return 0;
 }
 
 static int
-cr_ship(const void * v, char * buffer, const void * userdata)
+cr_ship(variant var, char * buffer, const void * userdata)
 {
 	const faction * report = (const faction*)userdata;
-	ship * u = (ship *)v;
+	ship * u = (ship *)var.v;
 	sprintf(buffer, "%d", u?u->no:-1);
 	unused(report);
 	return 0;
 }
 
 static int
-cr_building(const void * v, char * buffer, const void * userdata)
+cr_building(variant var, char * buffer, const void * userdata)
 {
 	const faction * report = (const faction*)userdata;
-	building * u = (building *)v;
+	building * u = (building *)var.v;
 	sprintf(buffer, "%d", u?u->no:-1);
 	unused(report);
 	return 0;
 }
 
 static int
-cr_faction(const void * v, char * buffer, const void * userdata)
+cr_faction(variant var, char * buffer, const void * userdata)
 {
 	const faction * report = (const faction*)userdata;
-	faction * f = (faction *)v;
+	faction * f = (faction *)var.v;
 	sprintf(buffer, "%d", f?f->no:-1);
 	unused(report);
 	return 0;
 }
 
 static int
-cr_region(const void * v, char * buffer, const void * userdata)
+cr_region(variant var, char * buffer, const void * userdata)
 {
 	const faction * report = (const faction*)userdata;
-	region * r = (region *)v;
+	region * r = (region *)var.v;
 	if (r) {
 		plane * p = rplane(r);
 		if (!p || !(p->flags & PFL_NOCOORDS)) {
@@ -332,10 +332,10 @@ cr_region(const void * v, char * buffer, const void * userdata)
 }
 
 static int
-cr_resource(const void * v, char * buffer, const void * userdata)
+cr_resource(variant var, char * buffer, const void * userdata)
 {
 	const faction * report = (const faction*)userdata;
-	const resource_type * r = (const resource_type *)v;
+	const resource_type * r = (const resource_type *)var.v;
 	if (r) {
 		const char * key = resourcename(r, 0);
 		sprintf(buffer, "\"%s\"",
@@ -346,10 +346,10 @@ cr_resource(const void * v, char * buffer, const void * userdata)
 }
 
 static int
-cr_race(const void * v, char * buffer, const void * userdata)
+cr_race(variant var, char * buffer, const void * userdata)
 {
 	const faction * report = (const faction*)userdata;
-	const struct race * rc = (const race *)v;
+	const struct race * rc = (const race *)var.v;
 	const char * key = rc_name(rc, 0);
 	sprintf(buffer, "\"%s\"",
 		add_translation(key, locale_string(report->locale, key)));
@@ -357,9 +357,9 @@ cr_race(const void * v, char * buffer, const void * userdata)
 }
 
 static int
-cr_alliance(const void * v, char * buffer, const void * userdata)
+cr_alliance(variant var, char * buffer, const void * userdata)
 {
-	const alliance * al = (const alliance *)v;
+	const alliance * al = (const alliance *)var.v;
 	if (al!=NULL) {
 		sprintf(buffer, "%d", al->id);
 	}
@@ -368,10 +368,10 @@ cr_alliance(const void * v, char * buffer, const void * userdata)
 }
 
 static int
-cr_skill(const void * v, char * buffer, const void * userdata)
+cr_skill(variant var, char * buffer, const void * userdata)
 {
   const faction * report = (const faction*)userdata;
-  skill_t sk = (skill_t)(int)v;
+  skill_t sk = (skill_t)var.i;
   if (sk!=NOSKILL) sprintf(buffer, "\"%s\"",
     add_translation(skillname(sk, NULL), skillname(sk, report->locale)));
   else strcpy(buffer, "\"\"");
@@ -379,9 +379,9 @@ cr_skill(const void * v, char * buffer, const void * userdata)
 }
 
 static int
-cr_order(const void * v, char * buffer, const void * userdata)
+cr_order(variant var, char * buffer, const void * userdata)
 {
-  order * ord = (order*)v;
+  order * ord = (order*)var.v;
   if (ord!=NULL) {
     char * wp = buffer;
     char * cmd = getcommand(ord);
@@ -406,10 +406,10 @@ cr_order(const void * v, char * buffer, const void * userdata)
 }
 
 static int
-cr_spell(const void * v, char * buffer, const void * userdata)
+cr_spell(variant var, char * buffer, const void * userdata)
 {
   const faction * report = (const faction*)userdata;
-  spell * sp = (spell*)v;
+  spell * sp = (spell*)var.v;
   if (sp!=NULL) sprintf(buffer, "\"%s\"", spell_name(sp, report->locale));
   else strcpy(buffer, "\"\"");
   return 0;
diff --git a/src/common/gamecode/gamecode.vcproj b/src/common/gamecode/gamecode.vcproj
index 210592266..fcbbdf9e1 100644
--- a/src/common/gamecode/gamecode.vcproj
+++ b/src/common/gamecode/gamecode.vcproj
@@ -140,6 +140,7 @@
 				ProgramDataBaseFileName=".\Debug/"
 				WarningLevel="4"
 				SuppressStartupBanner="TRUE"
+				Detect64BitPortabilityProblems="TRUE"
 				DebugInformationFormat="1"
 				CompileAs="0"/>
 			<Tool
diff --git a/src/common/gamecode/items.c b/src/common/gamecode/items.c
index 818ff1f8e..fb39167e6 100644
--- a/src/common/gamecode/items.c
+++ b/src/common/gamecode/items.c
@@ -146,6 +146,7 @@ use_bagpipeoffear(struct unit * u, const struct item_type * itype,
                   int amount, struct order * ord)
 {
   int money;
+  variant effect;
 
   if(get_curse(u->region->attribs, ct_find("depression"))) {
     cmistake(u, ord, 58, MSG_MAGIC);
@@ -156,8 +157,9 @@ use_bagpipeoffear(struct unit * u, const struct item_type * itype,
   change_money(u, money);
   rsetmoney(u->region, rmoney(u->region) - money);
 
+  effect.i = 0;
   create_curse(u, &u->region->attribs, ct_find("depression"),
-    20, BAGPIPEDURATION, 0, 0);
+    20, BAGPIPEDURATION, effect, 0);
 
   ADDMSG(&u->faction->msgs, msg_message("bagpipeoffear_faction",
     "unit region command money", u, u->region, ord, money));
diff --git a/src/common/gamecode/laws.c b/src/common/gamecode/laws.c
index 121b400a2..5d1596971 100644
--- a/src/common/gamecode/laws.c
+++ b/src/common/gamecode/laws.c
@@ -599,7 +599,7 @@ migration * free_migrants;
 static migration *
 get_migrants(region * r)
 {
-  int key = region_hashkey(r);
+  int key = reg_hashkey(r);
   int index = key % MSIZE;
   migration * m = migrants[index];
   while (m && m->r != r)
@@ -624,7 +624,7 @@ get_migrants(region * r)
 static void
 migrate(region * r)
 {
-  int key = region_hashkey(r);
+  int key = reg_hashkey(r);
   int index = key % MSIZE;
   migration ** hp = &migrants[index];
   fset(r, RF_MIGRATION);
@@ -1782,9 +1782,8 @@ static void
 deliverMail(faction * f, region * r, unit * u, const char *s, unit * receiver)
 {
   if (!receiver) { /* BOTSCHAFT an PARTEI */
-    char * message = (char*)gc_add(strdup(s));
     add_message(&f->msgs,
-      msg_message("unitmessage", "region unit string", r, u, message));
+      msg_message("unitmessage", "region unit string", r, u, s));
   }
   else {          /* BOTSCHAFT an EINHEIT */
     unit *emp = receiver;
@@ -1842,7 +1841,13 @@ prepare_mail_cmd(unit * u, struct order * ord)
       }
       u2 = findunitr(r,n);
       if(u2 && cansee(u->faction, r, u2, 0)) {
-        handle_event_va(&u2->attribs, "message", "string unit", s, u);
+        event_arg args[3];
+        args[0].data.v = (void*)s;
+        args[0].type = "string";
+        args[1].data.v = (void*)u;
+        args[1].type = "unit";
+        args[2].type = NULL;
+        handle_event(&u2->attribs, "message", args);
       }
     }
     break;
@@ -1863,7 +1868,6 @@ mailunit(region * r, unit * u, int n, struct order * ord, const char * s)
   if (u2 && cansee(u->faction, r, u2, 0)) {
     deliverMail(u2->faction, r, u, s, u2);
     /* now done in prepare_mail_cmd */
-    /* handle_event_va(&u2->attribs, "message", "string unit", s, u); */
   }
   else {
     /* Immer eine Meldung - sonst k�nnte man so getarnte EHs enttarnen:
@@ -2062,8 +2066,8 @@ banner_cmd(unit * u, struct order * ord)
   skip_token();
 
   set_string(&u->faction->banner, getstrtoken());
-  add_message(&u->faction->msgs, new_message(u->faction,
-    "changebanner%s:value", gc_add(strdup(u->faction->banner))));
+  add_message(&u->faction->msgs, msg_message("changebanner", "value",
+    u->faction->banner));
 
   return 0;
 }
@@ -2083,11 +2087,9 @@ email_cmd(unit * u, struct order * ord)
     faction * f = u->faction;
     if (set_email(&f->email, s)!=0) {
       log_error(("Invalid email address for faction %s: %s\n", itoa36(f->no), s));
-      ADDMSG(&f->msgs, msg_message("changemail_invalid", "value",
-        gc_add(strdup(s))));
+      ADDMSG(&f->msgs, msg_message("changemail_invalid", "value", s));
     } else {
-      ADDMSG(&f->msgs, msg_message("changemail", "value",
-        gc_add(strdup(f->email))));
+      ADDMSG(&f->msgs, msg_message("changemail", "value", f->email));
     }
   }
   return 0;
@@ -2127,7 +2129,7 @@ password_cmd(unit * u, struct order * ord)
   set_string(&u->faction->passw, pbuf);
   fset(u->faction, FFL_OVERRIDE);
   ADDMSG(&u->faction->msgs, msg_message("changepasswd",
-    "value", gc_add(strdup(u->faction->passw))));
+    "value", u->faction->passw));
   return 0;
 }
 
@@ -2523,13 +2525,13 @@ group_cmd(unit * u, struct order * ord)
 static int
 origin_cmd(unit * u, struct order * ord)
 {
-  int px, py;
+  short px, py;
 
   init_tokens(ord);
   skip_token();
 
-  px = atoi(getstrtoken());
-  py = atoi(getstrtoken());
+  px = (short)atoi(getstrtoken());
+  py = (short)atoi(getstrtoken());
 
   set_ursprung(u->faction, getplaneid(u->region), px, py);
   return 0;
@@ -3210,9 +3212,11 @@ renumber(void)
 static building *
 age_building(building * b)
 {
-  static const building_type * bt_blessed = (const building_type*)0xdeadbeef;
-  static const curse_type * ct_astralblock = NULL;
-  if (bt_blessed==(const building_type*)0xdeadbeef) {
+  static boolean init = false;
+  static const building_type * bt_blessed;
+  static const curse_type * ct_astralblock;
+  if (!init) {
+    init = true;
     bt_blessed = bt_find("blessedstonecircle");
     ct_astralblock = ct_find("astralblock");
   }
@@ -3260,9 +3264,11 @@ age_building(building * b)
       if (c==NULL) {
         if (mage!=NULL) {
           int sk = effskill(mage, SK_MAGIC);
+          variant effect;
+          effect.i = 100;
           /* the mage reactivates the circle */
           c = create_curse(mage, &rt->attribs, ct_astralblock,
-            sk, sk/2, 100, 0);
+            sk, sk/2, effect, 0);
           ADDMSG(&r->msgs, msg_message("astralshield_activate", 
             "region unit", r, mage));
         }
@@ -3887,8 +3893,8 @@ processorders (void)
 #endif
 
   puts(" - Attackieren");
-  if(nobattle == false) do_battle();
-  if (turn == 0) srand(time((time_t *) NULL));
+  if (nobattle == false) do_battle();
+  if (turn == 0) srand((int)time(0));
   else srand(turn);
 
   puts(" - Belagern");
@@ -3903,7 +3909,7 @@ processorders (void)
   puts(" - Folge auf Einheiten ersetzen");
   follow_unit();
 
-  if (turn == 0) srand(time((time_t *) NULL));
+  if (turn == 0) srand((int)time(0));
   else srand(turn);
 
   puts(" - Zerst�ren, Geben, Rekrutieren, Vergessen");
@@ -3946,7 +3952,7 @@ processorders (void)
   puts(" - Zufallsbegegnungen");
   encounters();
 
-  if (turn == 0) srand(time((time_t *) NULL));
+  if (turn == 0) srand((int)time(0));
   else srand(turn);
 
   puts(" - Monster fressen und vertreiben Bauern");
diff --git a/src/common/gamecode/randenc.c b/src/common/gamecode/randenc.c
index 6d91264f5..843c90980 100644
--- a/src/common/gamecode/randenc.c
+++ b/src/common/gamecode/randenc.c
@@ -930,7 +930,7 @@ move_iceberg(region *r)
 		if (rterrain(rc) == T_OCEAN) {	/* Eisberg treibt */
 			ship *sh, *shn;
 			unit *u;
-			int x, y;
+			short x, y;
 
 
 			for (u=r->units; u; u=u->next) freset(u->faction, FL_DH);
diff --git a/src/common/gamecode/report.c b/src/common/gamecode/report.c
index 451f09433..beb3b42d3 100644
--- a/src/common/gamecode/report.c
+++ b/src/common/gamecode/report.c
@@ -123,7 +123,8 @@ read_datenames(const char *filename)
 {
 	FILE *namesFP;
 	char line[256];
-	int  i, l;
+	int  i;
+  size_t l;
 
 	if( (namesFP=fopen(filename,"r")) == NULL) {
 		log_error(("Kann Datei '%s' nicht �ffnen, Abbruch\n", filename));
@@ -709,7 +710,7 @@ static void
 rps_nowrap(FILE * F, const char *s)
 {
 	const char *x = s;
-	int indent = 0;
+	size_t indent = 0;
 
 	while (*x++ == ' ');
 	indent = x - s - 1;
@@ -1007,13 +1008,14 @@ static void
 eval_trail(struct opstack ** stack, const void * userdata) /* (int, int) -> int */
 {
 	const struct faction * f = (const struct faction *)userdata;
-	const struct locale * lang = opop(stack, const struct locale*);
-	const struct region * r = opop(stack, const struct region*);
+	const struct locale * lang = (const struct locale*)opop(stack).v;
+	const struct region * r = (const struct region*)opop(stack).v;
 	const char * trail = trailinto(r, lang);
 	const char * rn = f_regionid(r, f);
-	char * x = balloc(strlen(trail)+strlen(rn));
+  variant var;
+  char * x = var.v = balloc(strlen(trail)+strlen(rn));
 	sprintf(x, trail, rn);
-	opush(stack, x);
+	opush(stack, var);
 }
 
 static void
@@ -1982,7 +1984,7 @@ report(FILE *F, faction * f, struct seen_region ** seen, const faction_list * ad
 	if (f->age <= 2) {
 		if (f->age <= 1) {
 			ADDMSG(&f->msgs, msg_message("changepasswd",
-				"value", gc_add(strdup(f->passw))));
+				"value", f->passw));
 		}
 		RENDER(f, buf, sizeof(buf), ("newbie_password", "password", f->passw));
 		rnl(F);
@@ -3561,30 +3563,39 @@ static void
 eval_unit(struct opstack ** stack, const void * userdata) /* unit -> string */
 {
   const struct faction * f = (const struct faction *)userdata;
-	const struct unit * u = opop(stack, const struct unit *);
+	const struct unit * u = (const struct unit *)opop(stack).v;
 	const char * c = u?unitname(u):LOC(f->locale, "an_unknown_unit");
 	size_t len = strlen(c);
-	opush(stack, strcpy(balloc(len+1), c));
+  variant var;
+
+  var.v = strcpy(balloc(len+1), c);
+	opush(stack, var);
 }
 
 static void
 eval_spell(struct opstack ** stack, const void * userdata) /* unit -> string */
 {
   const struct faction * f = (const struct faction *)userdata;
-  const struct spell * sp = opop(stack, const struct spell *);
+  const struct spell * sp = (const struct spell *)opop(stack).v;
   const char * c = sp?spell_name(sp, f->locale):LOC(f->locale, "an_unknown_spell");
   size_t len = strlen(c);
-  opush(stack, strcpy(balloc(len+1), c));
+  variant var;
+
+  var.v = strcpy(balloc(len+1), c);
+  opush(stack, var);
 }
 
 static void
 eval_unitname(struct opstack ** stack, const void * userdata) /* unit -> string */
 {
   const struct faction * f = (const struct faction *)userdata;
-	const struct unit * u = opop(stack, const struct unit *);
+	const struct unit * u = (const struct unit *)opop(stack).v;
 	const char * c = u?u->name:LOC(f->locale, "an_unknown_unit");
 	size_t len = strlen(c);
-	opush(stack, strcpy(balloc(len+1), c));
+  variant var;
+
+  var.v = strcpy(balloc(len+1), c);
+  opush(stack, var);
 }
 
 
@@ -3592,127 +3603,188 @@ static void
 eval_unitid(struct opstack ** stack, const void * userdata) /* unit -> int */
 {
   const struct faction * f = (const struct faction *)userdata;
-	const struct unit * u = opop(stack, const struct unit *);
+	const struct unit * u = (const struct unit *)opop(stack).v;
 	const char * c = u?u->name:LOC(f->locale, "an_unknown_unit");
 	size_t len = strlen(c);
-	opush(stack, strcpy(balloc(len+1), c));
+  variant var;
+  
+  var.v = strcpy(balloc(len+1), c);
+  opush(stack, var);
 }
 
 static void
 eval_faction(struct opstack ** stack, const void * userdata) /* faction -> string */
 {
-	const struct faction * f = opop(stack, const struct faction *);
+	const struct faction * f = (const struct faction *)opop(stack).v;
 	const char * c = factionname(f);
 	size_t len = strlen(c);
-	opush(stack, strcpy(balloc(len+1), c));
+  variant var;
+
+  var.v = strcpy(balloc(len+1), c);
+  opush(stack, var);
 }
 
 static void
 eval_alliance(struct opstack ** stack, const void * userdata) /* faction -> string */
 {
-	const struct alliance * al = opop(stack, const struct alliance *);
+	const struct alliance * al = (const struct alliance *)opop(stack).v;
 	const char * c = alliancename(al);
+  variant var;
 	if (c!=NULL) {
 		size_t len = strlen(c);
-		opush(stack, strcpy(balloc(len+1), c));
+    var.v = strcpy(balloc(len+1), c);
 	}
-	else opush(stack, NULL);
+	else var.v = NULL;
+  opush(stack, var);
 }
 
 static void
 eval_region(struct opstack ** stack, const void * userdata) /* region -> string */
 {
 	const struct faction * f = (const struct faction *)userdata;
-	const struct region * r = opop(stack, const struct region *);
+	const struct region * r = (const struct region *)opop(stack).v;
 	const char * c = regionname(r, f);
 	size_t len = strlen(c);
-	opush(stack, strcpy(balloc(len+1), c));
+  variant var;
+
+  var.v = strcpy(balloc(len+1), c);
+  opush(stack, var);
 }
 
 static void
 eval_ship(struct opstack ** stack, const void * userdata) /* ship -> string */
 {
   const struct faction * f = (const struct faction *)userdata;
-	const struct ship * u = opop(stack, const struct ship *);
+	const struct ship * u = (const struct ship *)opop(stack).v;
 	const char * c = u?shipname(u):LOC(f->locale, "an_unknown_ship");
 	size_t len = strlen(c);
-	opush(stack, strcpy(balloc(len+1), c));
+  variant var;
+
+  var.v = strcpy(balloc(len+1), c);
+  opush(stack, var);
 }
 
 static void
 eval_building(struct opstack ** stack, const void * userdata) /* building -> string */
 {
   const struct faction * f = (const struct faction *)userdata;
-	const struct building * u = opop(stack, const struct building *);
+	const struct building * u = (const struct building *)opop(stack).v;
 	const char * c = u?buildingname(u):LOC(f->locale, "an_unknown_building");
 	size_t len = strlen(c);
-	opush(stack, strcpy(balloc(len+1), c));
+  variant var;
+
+  var.v = strcpy(balloc(len+1), c);
+  opush(stack, var);
 }
 
 static void
 eval_resource(struct opstack ** stack, const void * userdata)
 {
 	const faction * report = (const faction*)userdata;
-	int j = opop(stack, int);
-	struct resource_type * res = opop(stack, struct resource_type *);
-
+	int j = opop(stack).i;
+	const struct resource_type * res = (const struct resource_type *)opop(stack).v;
 	const char * c = LOC(report->locale, resourcename(res, j!=1));
-	opush(stack, strcpy(balloc(strlen(c)+1), c));
+	size_t len = strlen(c);
+  variant var;
+
+  var.v = strcpy(balloc(len+1), c);
+  opush(stack, var);
 }
 
 static void
 eval_race(struct opstack ** stack, const void * userdata)
 {
 	const faction * report = (const faction*)userdata;
-	int j = opop(stack, int);
-	const race * r = opop(stack, const race *);
-
+	int j = opop(stack).i;
+	const race * r = (const race *)opop(stack).v;
 	const char * c = LOC(report->locale, rc_name(r, j!=1));
-	opush(stack, strcpy(balloc(strlen(c)+1), c));
+	size_t len = strlen(c);
+  variant var;
+
+  var.v = strcpy(balloc(len+1), c);
+  opush(stack, var);
 }
 
 static void
 eval_order(struct opstack ** stack, const void * userdata) /* order -> string */
 {
 	const faction * report = (const faction*)userdata;
-	struct order * ord = opop(stack, struct order *);
+	const struct order * ord = (const struct order *)opop(stack).v;
 	static char buf[256];
-	write_order(ord, report->locale, buf, sizeof(buf));
-	opush(stack, strcpy(balloc(strlen(buf)+1), buf));
+  size_t len;
+  variant var;
+
+  write_order(ord, report->locale, buf, sizeof(buf));
+  len = strlen(buf);
+  var.v = strcpy(balloc(len+1), buf);
+  opush(stack, var);
 }
 
 static void
 eval_direction(struct opstack ** stack, const void * userdata)
 {
 	const faction * report = (const faction*)userdata;
-	int i = opop(stack, int);
-	const char * c;
-	if (i>=0) {
-		c = LOC(report->locale, directions[i]);
-	} else {
-		c = LOC(report->locale, "unknown_direction");
-	}
-	opush(stack, strcpy(balloc(strlen(c)+1), c));
+	int i = opop(stack).i;
+	const char * c = LOC(report->locale, (i>=0)?directions[i]:"unknown_direction");
+	size_t len = strlen(c);
+  variant var;
+
+  var.v = strcpy(balloc(len+1), c);
+  opush(stack, var);
 }
 
 static void
 eval_skill(struct opstack ** stack, const void * userdata)
 {
 	const faction * report = (const faction*)userdata;
-	skill_t sk = (skill_t)opop(stack, int);
+	skill_t sk = (skill_t)opop(stack).i;
 	const char * c = skillname(sk, report->locale);
-	opush(stack, strcpy(balloc(strlen(c)+1), c));
+	size_t len = strlen(c);
+  variant var;
+
+  var.v = strcpy(balloc(len+1), c);
+  opush(stack, var);
 }
 
 static void
 eval_int36(struct opstack ** stack, const void * userdata)
 {
-	int i = opop(stack, int);
+	int i = opop(stack).i;
 	const char * c = itoa36(i);
-	opush(stack, strcpy(balloc(strlen(c)+1), c));
+	size_t len = strlen(c);
+  variant var;
+
+  var.v = strcpy(balloc(len+1), c);
+  opush(stack, var);
 	unused(userdata);
 }
 
+static variant
+var_copy_string(variant x)
+{
+  x.v = strdup((const char*)x.v);
+  return x;
+}
+
+static void
+var_free_string(variant x)
+{
+  free(x.v);
+}
+
+static variant
+var_copy_order(variant x)
+{
+  x.v = copy_order((order*)x.v);
+  return x;
+}
+
+static void
+var_free_order(variant x)
+{
+  free_order(x.v);
+}
+
 void
 report_init(void)
 {
@@ -3733,8 +3805,21 @@ report_init(void)
 	add_function("trail", &eval_trail);
   add_function("spell", &eval_spell);
 
-  register_argtype("string", free, (void*(*)(void*))strdup);
-  register_argtype("order", (void(*)(void*))free_order, (void*(*)(void*))copy_order);
+  register_argtype("alliance", NULL, NULL, VAR_VOIDPTR);
+  register_argtype("building", NULL, NULL, VAR_VOIDPTR);
+  register_argtype("direction", NULL, NULL, VAR_INT);
+  register_argtype("faction", NULL, NULL, VAR_VOIDPTR);
+  register_argtype("race", NULL, NULL, VAR_VOIDPTR);
+  register_argtype("region", NULL, NULL, VAR_VOIDPTR);
+  register_argtype("resource", NULL, NULL, VAR_VOIDPTR);
+  register_argtype("ship", NULL, NULL, VAR_VOIDPTR);
+  register_argtype("skill", NULL, NULL, VAR_VOIDPTR);
+  register_argtype("spell", NULL, NULL, VAR_VOIDPTR);
+  register_argtype("unit", NULL, NULL, VAR_VOIDPTR);
+  register_argtype("int", NULL, NULL, VAR_INT);
+  register_argtype("string", var_free_string, var_copy_string, VAR_VOIDPTR);
+  register_argtype("order", var_free_order, var_copy_order, VAR_VOIDPTR);
+
   register_function((pf_generic)view_neighbours, "view_neighbours");
 	register_function((pf_generic)view_regatta, "view_regatta");
 }
diff --git a/src/common/items/artrewards.c b/src/common/items/artrewards.c
index 8da51c0e2..fd10699f5 100644
--- a/src/common/items/artrewards.c
+++ b/src/common/items/artrewards.c
@@ -64,9 +64,11 @@ use_hornofdancing(struct unit * u, const struct item_type * itype,
     if(distance(u->region, r) < HORNRANGE) {
       if(a_find(r->attribs, &at_peaceimmune) == NULL) {
         attrib *a;
+        variant effect;
 
+        effect.i = 1;
         create_curse(u, &r->attribs, ct_find("peacezone"),
-          20, HORNDURATION, 1, 0);
+          20, HORNDURATION, effect, 0);
 
         a = a_add(&r->attribs, a_new(&at_peaceimmune));
         a->data.i = HORNIMMUNITY;
@@ -119,6 +121,7 @@ use_trappedairelemental(struct unit * u, int shipId,
 {
   curse  *c;
   ship   *sh;
+  variant effect;
 
   if(shipId <= 0) {
     cmistake(u, ord, 20, MSG_MOVE);
@@ -131,8 +134,9 @@ use_trappedairelemental(struct unit * u, int shipId,
     return -1;
   }
 
+  effect.i = SPEEDUP;
   c = create_curse(u, &sh->attribs, ct_find("shipspeedup"),
-    20, 999999, SPEEDUP, 0);
+    20, 999999, effect, 0);
   curse_setflag(c, CURSE_NOAGE);
 
   ADDMSG(&u->faction->msgs, msg_message("trappedairelemental_success",
diff --git a/src/common/items/items.vcproj b/src/common/items/items.vcproj
index 68d0e8c18..4bd461739 100644
--- a/src/common/items/items.vcproj
+++ b/src/common/items/items.vcproj
@@ -86,6 +86,7 @@
 				ProgramDataBaseFileName=".\Debug/"
 				WarningLevel="4"
 				SuppressStartupBanner="TRUE"
+				Detect64BitPortabilityProblems="TRUE"
 				DebugInformationFormat="1"
 				CompileAs="0"/>
 			<Tool
diff --git a/src/common/kernel/Jamfile b/src/common/kernel/Jamfile
index 56216fe18..c441ebda5 100644
--- a/src/common/kernel/Jamfile
+++ b/src/common/kernel/Jamfile
@@ -26,7 +26,6 @@ SOURCES =
  message.c
  movement.c
  names.c
- objtypes.c
  order.c
  pathfinder.c
  plane.c
diff --git a/src/common/kernel/battle.c b/src/common/kernel/battle.c
index 47de1c938..4e589f3fa 100644
--- a/src/common/kernel/battle.c
+++ b/src/common/kernel/battle.c
@@ -2583,7 +2583,7 @@ aftermath(battle * b)
   cv_foreach(s, b->sides) {
     message * seen = msg_message("battle::army_report", 
       "index abbrev dead flown survived", 
-      s->index, gc_add(strdup(sideabkz(s, false))), s->dead, s->flee, s->alive);
+      s->index, sideabkz(s, false), s->dead, s->flee, s->alive);
     message * unseen = msg_message("battle::army_report", 
       "index abbrev dead flown survived", 
       s->index, "-?-", s->dead, s->flee, s->alive);
@@ -3350,16 +3350,16 @@ join_allies(battle * b)
   * Deshalb mu� das Ende des Vektors vorher gemerkt werden, damit
   * neue Parteien nicht mit betrachtet werden:
   */
-  int size = cv_size(&b->sides);
+  size_t size = cv_size(&b->sides);
   for (u=r->units;u;u=u->next)
     /* Was ist mit Schiffen? */
     if (u->status != ST_FLEE && u->status != ST_AVOID && !fval(u, UFL_LONGACTION) && u->number > 0)
     {
-      int si;
+      size_t si;
       faction * f = u->faction;
       fighter * c = NULL;
       for (si = 0; si != size; ++si) {
-        int se;
+        size_t se;
         side *s = b->sides.begin[si];
         /* Wenn alle attackierten noch FFL_NOAID haben, dann k�mpfe nicht mit. */
         if (fval(s->bf->faction, FFL_NOAID)) continue;
@@ -3593,9 +3593,14 @@ init_battle(region * r, battle **bp)
               continue;
             }
             /* Fehler: "Die Einheit ist mit uns alliert" */
-            if (calm_ct && curse_active(get_cursex(u->attribs, calm_ct, (void*)u2->faction, cmp_curseeffect))) {
-              cmistake(u, ord, 47, MSG_BATTLE);
-              continue;
+
+            if (calm_ct) {
+              variant var;
+              var.i = u2->faction->subscription;
+              if (curse_active(get_cursex(u->attribs, calm_ct, var, cmp_curseeffect_int))) {
+                cmistake(u, ord, 47, MSG_BATTLE);
+                continue;
+              }
             }
             /* Ende Fehlerbehandlung */
 
diff --git a/src/common/kernel/border.c b/src/common/kernel/border.c
index c6e9d3089..ef6db0fc7 100644
--- a/src/common/kernel/border.c
+++ b/src/common/kernel/border.c
@@ -21,6 +21,7 @@
 
 /* libc includes */
 #include <assert.h>
+#include <limits.h>
 #include <stdlib.h>
 #include <string.h>
 
@@ -58,16 +59,16 @@ find_border(unsigned int id)
 }
 
 void *
-resolve_borderid(void * id) {
-   return (void*)find_border((unsigned int)id);
+resolve_borderid(variant id) {
+   return (void*)find_border(id.i);
 }
 
 static border **
 get_borders_i(const region * r1, const region * r2)
 {
   border ** bp;
-  int key = region_hashkey(r1);
-  int k2 = region_hashkey(r2);
+  int key = reg_hashkey(r1);
+  int k2 = reg_hashkey(r2);
 
   key = min(k2, key) % BMAXHASH;
   bp = &borders[key];
@@ -155,15 +156,40 @@ find_bordertype(const char * name)
 void
 b_read(border * b, FILE *f)
 {
-	assert(sizeof(int)==sizeof(b->data));
-	fscanf(f, "%x ", (unsigned int*)&b->data);
+  switch (b->type->datatype) {
+    case VAR_NONE:
+    case VAR_INT:
+      fscanf(f, "%x ", &b->data.i);
+      break;
+    case VAR_VOIDPTR:
+      fscanf(f, "%p ", &b->data.v);
+      break;
+    case VAR_SHORTA:
+      fscanf(f, "%hd %hd ", &b->data.sa[0], &b->data.sa[1]);
+      break;
+    default:
+      assert(!"unhandled variant type in border");
+  }
 }
 
 void
 b_write(const border * b, FILE *f)
 {
 	assert(sizeof(int)==sizeof(b->data));
-	fprintf(f, "%x ", (int)b->data);
+  switch (b->type->datatype) {
+    case VAR_NONE:
+    case VAR_INT:
+      fprintf(f, "%x ", b->data.i);
+      break;
+    case VAR_VOIDPTR:
+      fprintf(f, "%p ", b->data.v);
+      break;
+    case VAR_SHORTA:
+      fprintf(f, "%d %d ", b->data.sa[0], b->data.sa[1]);
+      break;
+    default:
+      assert(!"unhandled variant type in border");
+  }
 }
 
 boolean b_transparent(const border * b, const struct faction * f) { unused(b); unused(f); return true; }
@@ -253,7 +279,7 @@ b_namewall(const border * b, const region * r, const struct faction * f, int gfl
 }
 
 border_type bt_wall = {
-	"wall",
+	"wall", VAR_INT,
 	b_opaque,
 	NULL, /* init */
 	NULL, /* destroy */
@@ -267,7 +293,7 @@ border_type bt_wall = {
 };
 
 border_type bt_noway = {
-	"noway",
+	"noway", VAR_INT,
 	b_transparent,
 	NULL, /* init */
 	NULL, /* destroy */
@@ -300,7 +326,7 @@ b_blockfogwall(const border * b, const unit * u, const region * r)
 }
 
 border_type bt_fogwall = {
-	"fogwall",
+	"fogwall", VAR_INT,
 	b_transparent, /* transparent */
 	NULL, /* init */
 	NULL, /* destroy */
@@ -317,15 +343,15 @@ static const char *
 b_nameillusionwall(const border * b, const region * r, const struct faction * f, int gflags)
 {
 	/* TODO: f->locale bestimmt die Sprache */
-	int fno = (int)b->data;
+	int fno = b->data.i;
 	unused(b);
 	unused(r);
-	if (gflags & GF_ARTICLE) return (f && fno==f->no)?"eine Illusionswand":"eine Wand";
+	if (gflags & GF_ARTICLE) return (f && fno==f->subscription)?"eine Illusionswand":"eine Wand";
 	return (f && fno==f->no)?"Illusionswand":"Wand";
 }
 
 border_type bt_illusionwall = {
-	"illusionwall",
+	"illusionwall", VAR_INT,
 	b_opaque,
 	NULL, /* init */
 	NULL, /* destroy */
@@ -343,7 +369,7 @@ border_type bt_illusionwall = {
  ***/
 
 boolean b_blockquestportal(const border * b, const unit * u, const region * r) {
-	if((int)b->data > 0) return true;
+	if(b->data.i > 0) return true;
 	return false;
 }
 
@@ -351,7 +377,7 @@ static const char *
 b_namequestportal(const border * b, const region * r, const struct faction * f, int gflags)
 {
 	/* TODO: f->locale bestimmt die Sprache */
-	int lock = (int)b->data;
+	int lock = b->data.i;
 	unused(b);
 	unused(r);
 
@@ -371,7 +397,7 @@ b_namequestportal(const border * b, const region * r, const struct faction * f,
 }
 
 border_type bt_questportal = {
-	"questportal",
+	"questportal", VAR_INT,
 	b_opaque,
 	NULL, /* init */
 	NULL, /* destroy */
@@ -392,15 +418,14 @@ static const char *
 b_nameroad(const border * b, const region * r, const struct faction * f, int gflags)
 {
 	region * r2 = (r==b->to)?b->from:b->to;
-	int rval = (int)b->data;
-	int local = (r==b->to)?(rval & 0xFFFF):((rval>>16) & 0xFFFF);
+	int local = (r==b->to)?b->data.sa[0]:b->data.sa[1];
 	static char buffer[64];
 
 	unused(f);
 	if (gflags & GF_ARTICLE) {
 		if (!(gflags & GF_DETAILED)) strcpy(buffer, "eine Stra�e");
 		else if (terrain[rterrain(r)].roadreq<=local) {
-			int remote = (r!=b->to)?(rval & 0xFFFF):((rval>>16) & 0xFFFF);
+      int remote = (r!=b->to)?b->data.sa[0]:b->data.sa[1];
 			if (terrain[rterrain(r2)].roadreq<=remote) {
 				strcpy(buffer, "eine Stra�e");
 			} else {
@@ -423,40 +448,33 @@ b_nameroad(const border * b, const region * r, const struct faction * f, int gfl
 static void
 b_readroad(border * b, FILE *f)
 {
-	int x, y;
-	fscanf(f, "%d %d ", &x, &y);
-	b->data=(void*)((x<<16) | y);
+	fscanf(f, "%hd %hd ", &b->data.sa[0], &b->data.sa[1]);
 }
 
 static void
 b_writeroad(const border * b, FILE *f)
 {
-	int x, y;
-	x = (int)b->data;
-	y = x & 0xFFFF;
-	x = (x >> 16) & 0xFFFF;
-	fprintf(f, "%d %d ", x, y);
+  fprintf(f, "%d %d ", b->data.sa[0], b->data.sa[1]);
 }
 
 static boolean
 b_validroad(const border * b)
 {
-	int x = (int)b->data;
-	if (x==0) return false;
+	if (b->data.sa[0]==SHRT_MAX) return false;
 	return true;
 }
 
 static boolean
 b_rvisibleroad(const border * b, const region * r)
 {
-	int x = (int)b->data;
+	int x = b->data.i;
 	x = (r==b->to)?(x & 0xFFFF):((x>>16) & 0xFFFF);
 	if (x==0) return false;
 	return (boolean)(b->to==r || b->from==r);
 }
 
 border_type bt_road = {
-	"road",
+	"road", VAR_INT,
 	b_transparent,
 	NULL, /* init */
 	NULL, /* destroy */
@@ -496,7 +514,7 @@ void
 read_borders(FILE * f)
 {
   for (;;) {
-    int fx, fy, tx, ty;
+    short fx, fy, tx, ty;
     unsigned int bid = 0;
     char zText[32];
     border * b;
@@ -505,9 +523,7 @@ read_borders(FILE * f)
 
     fscanf(f, "%s", zText);
     if (!strcmp(zText, "end")) break;
-    fscanf(f, "%u %d %d %d %d", &bid, &fx, &fy, &tx, &ty);
-    type = find_bordertype(zText);
-    assert(type || !"border type not registered");
+    fscanf(f, "%u %hd %hd %hd %hd", &bid, &fx, &fy, &tx, &ty);
     from = findregion(fx, fy);
     if (from==NULL) {
       if (!incomplete_data) log_error(("border for unknown region %d,%d\n", fx, fy));
@@ -518,6 +534,13 @@ read_borders(FILE * f)
       if (!incomplete_data) log_error(("border for unknown region %d,%d\n", tx, ty));
       to = new_region(tx, ty);
     }
+
+    type = find_bordertype(zText);
+    if (type==NULL) {
+      log_error(("[read_borders] unknown border type %s in %s\n", zText, regionname(from, NULL)));
+      assert(type || !"border type not registered");
+    }
+
     if (to==from) {
       direction_t dir = (direction_t) (rand() % MAXDIRECTIONS);
       region * r = rconnect(from, dir);
diff --git a/src/common/kernel/border.h b/src/common/kernel/border.h
index e05603c6d..790da5926 100644
--- a/src/common/kernel/border.h
+++ b/src/common/kernel/border.h
@@ -14,6 +14,9 @@
 
 #ifndef H_KRNL_BORDER
 #define H_KRNL_BORDER
+
+#include <util/variant.h>
+
 #ifdef __cplusplus
 extern "C" {
 #endif
@@ -28,7 +31,7 @@ extern "C" {
     struct border * nexthash; /* next border between these regions */
     struct region * from, * to; /* borders can be directed edges */
     attrib * attribs;
-    void * data;
+    variant data;
     unsigned int id; /* unique id */
   } border;
 
@@ -39,6 +42,7 @@ extern "C" {
 
   typedef struct border_type {
     const char* __name; /* internal use only */
+    variant_type datatype;
     boolean (*transparent)(const border *, const struct faction *);
     /* is it possible to see through this? */
     void (*init)(border *);
@@ -85,7 +89,7 @@ extern "C" {
 
 
   extern border * find_border(unsigned int id);
-  void * resolve_borderid(void * data);
+  void * resolve_borderid(variant data);
 
   extern border * get_borders(const struct region * r1, const struct region * r2);
   /* returns the list of borders between r1 and r2 or r2 and r1 */
diff --git a/src/common/kernel/building.c b/src/common/kernel/building.c
index a08d9812c..de6b345c6 100644
--- a/src/common/kernel/building.c
+++ b/src/common/kernel/building.c
@@ -342,8 +342,8 @@ static local_names * bnames;
 const building_type *
 findbuildingtype(const char * name, const struct locale * lang)
 {
+  variant type;
 	local_names * bn = bnames;
-	void * i;
 
 	while (bn) {
 		if (bn->lang==lang) break;
@@ -356,13 +356,14 @@ findbuildingtype(const char * name, const struct locale * lang)
 		bn->lang = lang;
 		while (btl) {
 			const char * n = locale_string(lang, btl->type->_name);
-			addtoken(&bn->names, n, (void*)btl->type);
+      type.v = (void*)btl->type;
+			addtoken(&bn->names, n, type);
 			btl=btl->next;
 		}
 		bnames = bn;
 	}
-	if (findtoken(&bn->names, name, &i)==E_TOK_NOMATCH) return NULL;
-	return (const building_type*)i;
+	if (findtoken(&bn->names, name, &type)==E_TOK_NOMATCH) return NULL;
+	return (const building_type*)type.v;
 }
 
 
@@ -389,8 +390,8 @@ bt_make(const char * name, int flags, int capacity, int maxcapacity, int maxsize
 }
 
 void *
-resolve_building(void * id) {
-   return findbuilding((int)id);
+resolve_building(variant id) {
+   return findbuilding(id.i);
 }
 
 void
@@ -402,17 +403,17 @@ write_building_reference(const struct building * b, FILE * F)
 int
 read_building_reference(struct building ** b, FILE * F)
 {
-	int id;
+	variant var;
 	char zText[10];
 	fscanf(F, "%s ", zText);
-	id = atoi36(zText);
-	if (id==0) {
+	var.i = atoi36(zText);
+	if (var.i==0) {
 		*b = NULL;
 		return AT_READ_FAIL;
 	}
 	else {
-		*b = findbuilding(id);
-		if (*b==NULL) ur_add((void*)id, (void**)b, resolve_building);
+		*b = findbuilding(var.i);
+		if (*b==NULL) ur_add(var, (void**)b, resolve_building);
 		return AT_READ_OK;
 	}
 }
diff --git a/src/common/kernel/building.h b/src/common/kernel/building.h
index ec5852e2e..5b0c31912 100644
--- a/src/common/kernel/building.h
+++ b/src/common/kernel/building.h
@@ -13,6 +13,8 @@
 
 #ifndef H_KRNL_BUILDING
 #define H_KRNL_BUILDING
+
+#include <util/variant.h>
 #ifdef __cplusplus
 extern "C" {
 #endif
@@ -130,7 +132,7 @@ extern struct building_type * bt_make(const char * name, int flags, int capacity
 #include "build.h"
 #define NOBUILDING NULL
 
-extern void * resolve_building(void * data);
+extern void * resolve_building(variant data);
 extern void write_building_reference(const struct building * b, FILE * F);
 extern int read_building_reference(struct building ** b, FILE * F);
 
diff --git a/src/common/kernel/combatspells.c b/src/common/kernel/combatspells.c
index 5709498fc..ae4164f64 100644
--- a/src/common/kernel/combatspells.c
+++ b/src/common/kernel/combatspells.c
@@ -864,7 +864,7 @@ sp_strong_wall(fighter * fi, int level, double power, spell * sp)
 	battle *b = fi->side->battle;
 	unit *mage = fi->unit;
 	building *burg;
-	int effect = (int)(power/4);
+	variant effect;
 	static boolean init = false;
 	static const curse_type * strongwall_ct;
 	if (!init) { init = true; strongwall_ct = ct_find("strongwall"); }
@@ -879,7 +879,8 @@ sp_strong_wall(fighter * fi, int level, double power, spell * sp)
 	}
 	burg = mage->building;
 
-	if (chance(power-effect)) ++effect;
+  effect.i = (int)(power/4);
+	if (chance(power-effect.i)) ++effect.i;
 
 	create_curse(mage, &burg->attribs, strongwall_ct, power, 1, effect, 0);
 
diff --git a/src/common/kernel/curse.c b/src/common/kernel/curse.c
index 9e953773f..7efcd8a5f 100644
--- a/src/common/kernel/curse.c
+++ b/src/common/kernel/curse.c
@@ -39,6 +39,7 @@
 #include <util/base36.h>
 #include <util/rand.h>
 #include <util/goodies.h>
+#include <util/variant.h>
 
 /* libc includes */
 #include <stdio.h>
@@ -123,8 +124,8 @@ curse_done(attrib * a) {
 
 	cunhash(c);
 
-	if( c->data && c->type->typ == CURSETYP_UNIT)
-			free(c->data);
+	if( c->data.v && c->type->typ == CURSETYP_UNIT)
+			free(c->data.v);
 	free(c);
 }
 
@@ -132,7 +133,7 @@ curse_done(attrib * a) {
 
 int
 curse_read(attrib * a, FILE * f) {
-	int mageid;
+	variant mageid;
 	curse * c = (curse*)a->data.v;
 	const curse_type * ct;
 
@@ -140,11 +141,11 @@ curse_read(attrib * a, FILE * f) {
 
 	if(global.data_version >= CURSEVIGOURISFLOAT_VERSION) {
 		fscanf(f, "%d %s %d %d %lf %d %d ", &c->no, cursename, &c->flag,
-			&c->duration, &c->vigour, &mageid, &c->effect.i);
+			&c->duration, &c->vigour, &mageid.i, &c->effect.i);
 	} else {
 		int vigour;
 		fscanf(f, "%d %s %d %d %d %d %d ", &c->no, cursename, &c->flag,
-			&c->duration, &vigour, &mageid, &c->effect.i);
+			&c->duration, &vigour, &mageid.i, &c->effect.i);
 		c->vigour = vigour;
 	}
 	ct = ct_find(cursename);
@@ -164,17 +165,17 @@ curse_read(attrib * a, FILE * f) {
 
 	/* beim Einlesen sind noch nicht alle units da, muss also
 	 * zwischengespeichert werden. */
-	if (mageid == -1){
+	if (mageid.i == -1){
 		c->magician = (unit *)NULL;
 	} else {
-		ur_add((void*)mageid, (void**)&c->magician, resolve_unit);
+		ur_add(mageid, (void**)&c->magician, resolve_unit);
 	}
 
 	if (c->type->read) c->type->read(f, c);
 	else if (c->type->typ==CURSETYP_UNIT) {
 		curse_unit * cc = calloc(1, sizeof(curse_unit));
 
-		c->data = cc;
+		c->data.v = cc;
 		fscanf(f, "%d ", &cc->cursedmen);
 	}
 	chash(c);
@@ -202,7 +203,7 @@ curse_write(const attrib * a, FILE * f) {
 
 	if (c->type->write) c->type->write(f, c);
 	else if (c->type->typ == CURSETYP_UNIT) {
-		curse_unit * cc = (curse_unit*)c->data;
+		curse_unit * cc = (curse_unit*)c->data.v;
 		fprintf(f, "%d ", cc->cursedmen);
 	}
 }
@@ -249,7 +250,7 @@ ct_find(const char *c)
   unsigned int hash = tolower(c[0]);
 	cursetype_list * ctl = cursetypes[hash];
 	while (ctl) {
-		int k = min(strlen(c), strlen(ctl->type->cname));
+		size_t k = min(strlen(c), strlen(ctl->type->cname));
 		if (!strncasecmp(c, ctl->type->cname, k)) return ctl->type;
 		ctl = ctl->next;
 	}
@@ -272,15 +273,21 @@ typedef struct cid {
 } twoids;
 
 boolean
-cmp_curseeffect(const curse * c, const void * data)
+cmp_curseeffect_vptr(const curse * c, variant var)
 {
-	return (c->effect.v==data);
+	return (c->effect.v==var.v);
 }
 
 boolean
-cmp_cursedata(const curse * c, const void * data)
+cmp_curseeffect_int(const curse * c, variant var)
 {
-	return (c->data==data);
+  return (c->effect.i==var.i);
+}
+
+boolean
+cmp_cursedata_int(const curse * c, variant data)
+{
+	return (c->data.i==data.i);
 }
 
 boolean
@@ -303,7 +310,7 @@ cmp_cursetype(const attrib * a, const void * data)
 }
 
 curse *
-get_cursex(attrib *ap, const curse_type * ctype, void * data, boolean(*compare)(const curse *, const void *))
+get_cursex(attrib *ap, const curse_type * ctype, variant data, boolean(*compare)(const curse *, variant))
 {
 	attrib * a = a_select(ap, ctype, cmp_cursetype);
 	while (a) {
@@ -417,8 +424,8 @@ get_cursedmen(unit *u, curse *c)
 	if (!c) return 0;
 
 	/* je nach curse_type andere data struct */
-	if (c->type->typ == CURSETYP_UNIT){
-		curse_unit * cc = (curse_unit*)c->data;
+	if (c->type->typ == CURSETYP_UNIT) {
+		curse_unit * cc = (curse_unit*)c->data.v;
 		cursedmen = cc->cursedmen;
 	}
 
@@ -433,7 +440,7 @@ set_cursedmen(curse *c, int cursedmen)
 
 	/* je nach curse_type andere data struct */
 	if (c->type->typ == CURSETYP_UNIT) {
-		curse_unit * cc = (curse_unit*)c->data;
+		curse_unit * cc = (curse_unit*)c->data.v;
 		cc->cursedmen = cursedmen;
 	}
 }
@@ -449,9 +456,9 @@ curse_setflag(curse *c, int flag)
 /* Legt eine neue Verzauberung an. Sollte es schon einen Zauber
  * dieses Typs geben, gibt es den bestehenden zur�ck.
  */
-curse *
+static curse *
 set_curse(unit *mage, attrib **ap, const curse_type *ct, double vigour,
-		int duration, int effect, int men)
+		int duration, variant effect, int men)
 {
 	curse *c;
 	attrib * a;
@@ -464,7 +471,7 @@ set_curse(unit *mage, attrib **ap, const curse_type *ct, double vigour,
 	c->flag = 0;
 	c->vigour = vigour;
 	c->duration = duration;
-	c->effect.i = effect;
+	c->effect = effect;
 	c->magician = mage;
 
 	c->no = newunitid();
@@ -478,7 +485,7 @@ set_curse(unit *mage, attrib **ap, const curse_type *ct, double vigour,
 		{
 			curse_unit *cc = calloc(1, sizeof(curse_unit));
 			cc->cursedmen += men;
-			c->data = cc;
+			c->data.v = cc;
 			break;
 		}
 
@@ -492,7 +499,7 @@ set_curse(unit *mage, attrib **ap, const curse_type *ct, double vigour,
  */
 curse *
 create_curse(unit *magician, attrib **ap, const curse_type *ct, double vigour,
-		int duration, int effect, int men)
+		int duration, variant effect, int men)
 {
 	curse *c;
 
@@ -515,10 +522,10 @@ create_curse(unit *magician, attrib **ap, const curse_type *ct, double vigour,
 			c->duration += duration;
 		}
 		if(ct->mergeflags & M_SUMEFFECT){
-			c->effect.i += effect;
+			c->effect.i += effect.i;
 		}
 		if(ct->mergeflags & M_MAXEFFECT){
-			c->effect.i = max(c->effect.i, effect);
+			c->effect.i = max(c->effect.i, effect.i);
 		}
 		if(ct->mergeflags & M_VIGOUR){
 			c->vigour = max(vigour, c->vigour);
@@ -530,7 +537,7 @@ create_curse(unit *magician, attrib **ap, const curse_type *ct, double vigour,
 			switch (ct->typ) {
 				case CURSETYP_UNIT:
 				{
-					curse_unit * cc = (curse_unit*)c->data;
+					curse_unit * cc = (curse_unit*)c->data.v;
 					cc->cursedmen += men;
 				}
 			}
@@ -550,10 +557,6 @@ void
 do_transfer_curse(curse *c, unit * u, unit * u2, int n)
 {
 	int flag = c->flag;
-	int duration = c->duration;
-	double vigour = c->vigour;
-	unit *magician = c->magician;
-	int effect = c->effect.i;
 	int cursedmen = 0;
 	int men = 0;
 	boolean dogive = false;
@@ -562,7 +565,7 @@ do_transfer_curse(curse *c, unit * u, unit * u2, int n)
 	switch (ct->typ) {
 		case CURSETYP_UNIT:
 		{
-			curse_unit * cc = (curse_unit*)c->data;
+			curse_unit * cc = (curse_unit*)c->data.v;
 			men = cc->cursedmen;
 			break;
 		}
@@ -601,8 +604,8 @@ do_transfer_curse(curse *c, unit * u, unit * u2, int n)
 	}
 
 	if (dogive == true) {
-		curse * cnew = set_curse(magician, &u2->attribs, c->type, vigour, duration,
-				effect, men);
+		curse * cnew = set_curse(c->magician, &u2->attribs, c->type, c->vigour, 
+      c->duration, c->effect, men);
 		curse_setflag(cnew, flag);
 
 		if (ct->typ == CURSETYP_UNIT) set_cursedmen(cnew, men);
@@ -678,9 +681,9 @@ is_cursed_with(attrib *ap, curse *c)
  */
 
 void *
-resolve_curse(void * id)
+resolve_curse(variant id)
 {
-   return cfindhash((int)id);
+   return cfindhash(id.i);
 }
 
 void
diff --git a/src/common/kernel/curse.h b/src/common/kernel/curse.h
index 19fe8f9fd..3331cda88 100644
--- a/src/common/kernel/curse.h
+++ b/src/common/kernel/curse.h
@@ -13,6 +13,9 @@
 
 #ifndef CURSE_H
 #define CURSE_H
+
+#include <util/variant.h>
+
 #ifdef __cplusplus
 extern "C" {
 #endif
@@ -196,7 +199,7 @@ typedef struct curse {
 	double vigour;        /* St�rke der Verzauberung, Widerstand gegen Antimagie */
 	struct unit *magician;    /* Pointer auf den Magier, der den Spruch gewirkt hat */
 	variant effect;
-	void *data;        /* pointer auf spezielle curse-unterstructs*/
+	variant data;        /* pointer auf spezielle curse-unterstructs*/
 } curse;
 
 /* Die Unterattribute curse->data: */
@@ -244,7 +247,7 @@ extern int curse_read(struct attrib * a,FILE * f);
 */
 
 curse * create_curse(struct unit *magician, struct attrib**ap, const curse_type * ctype,
-		double vigour, int duration, int ceffect, int men);
+		double vigour, int duration, variant ceffect, int men);
 	/* Verzweigt automatisch zum passenden struct-typ. Sollte es schon
 	 * einen Zauber dieses Typs geben, so wird der neue dazuaddiert. Die
 	 * Zahl der verzauberten Personen sollte beim Aufruf der Funktion
@@ -282,8 +285,8 @@ void transfer_curse(struct unit * u, struct unit * u2, int n);
 	 * unterschiedlich gew�nscht sein
 	 * */
 
-extern curse * get_cursex(attrib *ap, const curse_type * ctype, void * data, 
-						  boolean(*compare)(const curse *, const void *));
+extern curse * get_cursex(attrib *ap, const curse_type * ctype, variant data, 
+						  boolean(*compare)(const curse *, variant));
 	/* gibt pointer auf die erste curse-struct zur�ck, deren Typ ctype ist,
 	 * und f�r die compare() true liefert, oder einen NULL-pointer.
 	 * */
@@ -308,10 +311,11 @@ extern int curse_age(struct attrib * a);
 
 extern boolean cmp_curse(const attrib * a, const void * data);
 extern boolean cmp_cursetype(const attrib * a, const void * data);
-extern boolean cmp_curseeffect(const curse * c, const void * data);
-extern boolean cmp_cursedata(const curse * c, const void * data);
+extern boolean cmp_curseeffect_vptr(const curse * c, variant data);
+extern boolean cmp_curseeffect_int(const curse * c, variant data);
+extern boolean cmp_cursedata_int(const curse * c, variant data);
 
-extern void * resolve_curse(void * data);
+extern void * resolve_curse(variant data);
 extern boolean is_cursed_with(attrib *ap, curse *c);
 
 extern boolean curse_active(const curse * c);
diff --git a/src/common/kernel/eressea.c b/src/common/kernel/eressea.c
index 813a531f1..2ca97acdb 100644
--- a/src/common/kernel/eressea.c
+++ b/src/common/kernel/eressea.c
@@ -1179,8 +1179,8 @@ void
 update_lighthouse(building * lh)
 {
 	region * r = lh->region;
-	int d = (int)log10(lh->size) + 1;
-	int x, y;
+	short d = (short)log10(lh->size) + 1;
+	short x, y;
 	static const struct building_type * bt_lighthouse;
 	if (!bt_lighthouse) bt_lighthouse = bt_find("lighthouse");
 	assert(bt_lighthouse);
@@ -1506,10 +1506,10 @@ const struct race *
 findrace(const char * s, const struct locale * lang)
 {
 	struct lstr * lnames = get_lnames(lang);
-	const struct race * rc;
+  variant token;
 
-	if (findtoken(&lnames->races, s, (void **)&rc)==E_TOK_SUCCESS) {
-		return rc;
+	if (findtoken(&lnames->races, s, &token)==E_TOK_SUCCESS) {
+		return (const struct race *)token.v;
 	}
 	return NULL;
 }
@@ -1518,10 +1518,10 @@ int
 findoption(const char *s, const struct locale * lang)
 {
 	struct lstr * lnames = get_lnames(lang);
-	int dir;
+  variant token;
 
-	if (findtoken(&lnames->options, s, (void**)&dir)==E_TOK_SUCCESS) {
-		return (direction_t)dir;
+  if (findtoken(&lnames->options, s, &token)==E_TOK_SUCCESS) {
+		return (direction_t)token.i;
 	}
 	return NODIRECTION;
 }
@@ -1530,23 +1530,23 @@ skill_t
 findskill(const char *s, const struct locale * lang)
 {
 	struct lstr * lnames = get_lnames(lang);
-	int i;
+	variant token;
 
-	if (findtoken(&lnames->skillnames, s, (void**)&i)==E_TOK_NOMATCH) return NOSKILL;
-	return (skill_t)i;
+	if (findtoken(&lnames->skillnames, s, &token)==E_TOK_NOMATCH) return NOSKILL;
+	return (skill_t)token.i;
 }
 
 keyword_t
 findkeyword(const char *s, const struct locale * lang)
 {
 	struct lstr * lnames = get_lnames(lang);
-	int i;
+  variant token;
 #ifdef AT_PERSISTENT
 	if (*s == '@') s++;
 #endif
-	if (findtoken(&lnames->keywords, s, (void**)&i)==E_TOK_NOMATCH) return NOKEYWORD;
-	if (global.disabled[i]) return NOKEYWORD;
-	return (keyword_t) i;
+	if (findtoken(&lnames->keywords, s, &token)==E_TOK_NOMATCH) return NOKEYWORD;
+	if (global.disabled[token.i]) return NOKEYWORD;
+	return (keyword_t) token.i;
 }
 
 param_t
@@ -1554,15 +1554,15 @@ findparam(const char *s, const struct locale * lang)
 {
   struct lstr * lnames = get_lnames(lang);
   const building_type * btype;
-  
-  int i;
-  if (findtoken(&lnames->tokens[UT_PARAM], s, (void**)&i)==E_TOK_NOMATCH) {
-	btype = findbuildingtype(s, lang);
-	if (btype!=NULL) return (param_t) P_GEBAEUDE;
-	return NOPARAM;
+  variant token;
+
+  if (findtoken(&lnames->tokens[UT_PARAM], s, &token)==E_TOK_NOMATCH) {
+    btype = findbuildingtype(s, lang);
+    if (btype!=NULL) return (param_t) P_GEBAEUDE;
+    return NOPARAM;
   }
-  if (i==P_BUILDING) return P_GEBAEUDE;
-  return (param_t)i;
+  if (token.i==P_BUILDING) return P_GEBAEUDE;
+  return (param_t)token.i;
 }
 
 param_t
@@ -2309,7 +2309,9 @@ init_directions(tnode * root, const struct locale * lang)
 	int i;
 	struct lstr * lnames = get_lnames(lang);
 	for (i=0; dirs[i].direction!=NODIRECTION;++i) {
-		addtoken(&lnames->directions, LOC(lang, dirs[i].name), (void*)dirs[i].direction);
+    variant token;
+    token.i = dirs[i].direction;
+		addtoken(&lnames->directions, LOC(lang, dirs[i].name), token);
 	}
 }
 
@@ -2317,10 +2319,10 @@ direction_t
 finddirection(const char *s, const struct locale * lang)
 {
 	struct lstr * lnames = get_lnames(lang);
-	int dir;
+	variant token;
 
-	if (findtoken(&lnames->directions, s, (void**)&dir)==E_TOK_SUCCESS) {
-		return (direction_t)dir;
+	if (findtoken(&lnames->directions, s, &token)==E_TOK_SUCCESS) {
+		return (direction_t)token.i;
 	}
 	return NODIRECTION;
 }
@@ -2329,25 +2331,34 @@ static void
 init_locale(const struct locale * lang)
 {
 	struct lstr * lnames = get_lnames(lang);
+  variant var;
 	int i;
 	const struct race * rc;
 
 	init_directions(&lnames->directions, lang);
 	for (rc=races;rc;rc=rc->next) {
-		addtoken(&lnames->races, LOC(lang, rc_name(rc, 1)), (void*)rc);
-		addtoken(&lnames->races, LOC(lang, rc_name(rc, 0)), (void*)rc);
+    var.v = (void*)rc;
+		addtoken(&lnames->races, LOC(lang, rc_name(rc, 1)), var);
+		addtoken(&lnames->races, LOC(lang, rc_name(rc, 0)), var);
+	}
+  for (i=0;i!=MAXPARAMS;++i) {
+    var.i = i;
+    addtoken(&lnames->tokens[UT_PARAM], LOC(lang, parameters[i]), var);
 	}
-	for (i=0;i!=MAXPARAMS;++i)
-		addtoken(&lnames->tokens[UT_PARAM], LOC(lang, parameters[i]), (void*)i);
 	for (i=0;i!=MAXSKILLS;++i) {
 		if (i!=SK_TRADE || !TradeDisabled()) {
-			addtoken(&lnames->skillnames, skillname((skill_t)i, lang), (void*)i);
+      var.i = i;
+			addtoken(&lnames->skillnames, skillname((skill_t)i, lang), var);
 		}
 	}
-	for (i=0;i!=MAXKEYWORDS;++i)
-		addtoken(&lnames->keywords, LOC(lang, keywords[i]), (void*)i);
-	for (i=0;i!=MAXOPTIONS;++i)
-		addtoken(&lnames->options, LOC(lang, options[i]), (void*)i);
+  for (i=0;i!=MAXKEYWORDS;++i) {
+    var.i = i;
+    addtoken(&lnames->keywords, LOC(lang, keywords[i]), var);
+	}
+  for (i=0;i!=MAXOPTIONS;++i) {
+    var.i = i;
+    addtoken(&lnames->options, LOC(lang, options[i]), var);
+	}
 }
 
 typedef struct param {
@@ -3224,7 +3235,7 @@ kernel_init(void)
 
 	if (!turn) turn = lastturn();
 	if (turn == 0)
-		srand(time((time_t *) NULL));
+		srand((int)time(0));
 	else
 		srand(turn);
 	if (sqlpatch) {
diff --git a/src/common/kernel/eressea.h b/src/common/kernel/eressea.h
index 6d7f01104..9975bfc27 100644
--- a/src/common/kernel/eressea.h
+++ b/src/common/kernel/eressea.h
@@ -84,6 +84,7 @@ struct building_type;
 #include <util/lists.h>
 #include <util/log.h>
 #include <util/umlaut.h>
+#include <util/variant.h>
 #include <util/vmap.h>
 #include <util/vset.h>
 
@@ -368,7 +369,7 @@ extern void plagues(struct region * r, boolean ismagic);
 typedef struct ursprung {
 	struct ursprung *next;
 	int id;
-	int x, y;
+	short x, y;
 } ursprung;
 
 /* ----------------- Befehle ----------------------------------- */
@@ -998,7 +999,6 @@ extern int alliedgroup(const struct plane * pl, const struct faction * f,
 struct faction *findfaction(int n);
 struct faction *getfaction(void);
 
-struct region *findregion(int x, int y);
 struct unit *findunitg(int n, const struct region * hint);
 struct unit *findunit(int n);
 
diff --git a/src/common/kernel/faction.c b/src/common/kernel/faction.c
index 96c8b72c6..0c4a99280 100644
--- a/src/common/kernel/faction.c
+++ b/src/common/kernel/faction.c
@@ -26,6 +26,7 @@
 #include <util/base36.h>
 #include <util/event.h>
 #include <util/goodies.h>
+#include <util/variant.h>
 
 #include <attributes/otherfaction.h>
 
@@ -70,8 +71,8 @@ factionname(const faction * f)
 }
 
 void *
-resolve_faction(void * id) {
-   return findfaction((int)id);
+resolve_faction(variant id) {
+   return findfaction(id.i);
 }
 
 #define MAX_FACTION_ID (36*36*36*36)
diff --git a/src/common/kernel/faction.h b/src/common/kernel/faction.h
index 0f6d57c8c..bf85d8617 100644
--- a/src/common/kernel/faction.h
+++ b/src/common/kernel/faction.h
@@ -112,7 +112,7 @@ typedef struct faction_list {
 
 extern const struct unit * random_unit_in_faction(const struct faction *f);
 extern const char * factionname(const struct faction * f);
-extern void * resolve_faction(void * data);
+extern void * resolve_faction(variant data);
 extern struct unit * addplayer(struct region *r, faction * f);
 extern struct faction * addfaction(const char *email, const char* password, 
                                    const struct race * frace, 
diff --git a/src/common/kernel/group.c b/src/common/kernel/group.c
index 35a4cb7d8..26bf83bd3 100644
--- a/src/common/kernel/group.c
+++ b/src/common/kernel/group.c
@@ -180,16 +180,16 @@ read_groups(FILE * F, faction * f)
 		pa = &g->allies;
 		for (;;) {
 			ally * a;
-			int aid;
+			variant aid;
 			fscanf(F, "%s ", buf);
-			aid = atoi36(buf);
-			if (aid==0) break;
+			aid.i = atoi36(buf);
+			if (aid.i==0) break;
 			a = calloc(sizeof(ally), 1);
 			*pa = a;
 			pa = &a->next;
 			fscanf(F, "%d ", &a->status);
-			a->faction = findfaction(aid);
-			if (!a->faction) ur_add((void*)aid, (void**)&a->faction, resolve_faction);
+			a->faction = findfaction(aid.i);
+			if (!a->faction) ur_add(aid, (void**)&a->faction, resolve_faction);
 		}
 		if(global.data_version >= GROUPATTRIB_VERSION) {
 			a_read(F, &g->attribs);
diff --git a/src/common/kernel/item.c b/src/common/kernel/item.c
index b8c5820ea..c0c380288 100644
--- a/src/common/kernel/item.c
+++ b/src/common/kernel/item.c
@@ -869,7 +869,9 @@ use_antimagiccrystal(region * r, unit * mage, int amount, struct order * ord)
 		}
 
 		if(force > 0) {
-			create_curse(mage, &r->attribs, ct_find("antimagiczone"), force, duration, effect, 0);
+      variant var ;
+      var.i = effect;
+			create_curse(mage, &r->attribs, ct_find("antimagiczone"), force, duration, var, 0);
 		}
 
 	}
@@ -887,14 +889,17 @@ use_tacticcrystal(region * r, unit * u, int amount, struct order * ord)
 {
 	int i;
 	for (i=0;i!=amount;++i) {
-		int effect = rand()%6 - 1;
 		int duration = 1; /* wirkt nur eine Runde */
 		int power = 5; /* Widerstand gegen Antimagiespr�che, ist in diesem
 											Fall egal, da der curse f�r den Kampf gelten soll,
 											der vor den Antimagiezaubern passiert */
-		curse * c = create_curse(u, &u->attribs, ct_find("skillmod"), power,
+		curse * c;
+    variant effect;
+
+    effect.i = rand()%6 - 1;
+    c = create_curse(u, &u->attribs, ct_find("skillmod"), power,
 			duration, effect, u->number);
-		c->data = (void*)SK_TACTICS;
+		c->data.i = SK_TACTICS;
 		unused(ord);
 	}
 	use_pooled(u, u->region, R_TACTICCRYSTAL, amount);
@@ -2261,11 +2266,11 @@ const resource_type *
 findresourcetype(const char * name, const struct locale * lang)
 {
 	local_names * rn = rnames;
-	void * i;
+  variant token;
 
 	while (rn) {
 		if (rn->lang==lang) break;
-		rn=rn->next;
+		rn = rn->next;
 	}
 	if (!rn) {
 		const resource_type * rtl = resourcetypes;
@@ -2273,15 +2278,16 @@ findresourcetype(const char * name, const struct locale * lang)
 		rn->next = rnames;
 		rn->lang = lang;
 		while (rtl) {
-			addtoken(&rn->names, locale_string(lang, rtl->_name[0]), (void*)rtl);
-			addtoken(&rn->names, locale_string(lang, rtl->_name[1]), (void*)rtl);
+      token.v = (void*)rtl;
+			addtoken(&rn->names, locale_string(lang, rtl->_name[0]), token);
+			addtoken(&rn->names, locale_string(lang, rtl->_name[1]), token);
 			rtl=rtl->next;
 		}
 		rnames = rn;
 	}
 
-	if (findtoken(&rn->names, name, &i)==E_TOK_NOMATCH) return NULL;
-	return (const resource_type*)i;
+	if (findtoken(&rn->names, name, &token)==E_TOK_NOMATCH) return NULL;
+	return (const resource_type*)token.v;
 }
 
 attrib_type at_showitem = {
@@ -2315,11 +2321,12 @@ init_itemnames(void)
       for (key=0;key!=IMAXHASH;++key) {
         const item_type * itl;
         for (itl=itemtypes[key];itl;itl=itl->next) {
-          void * result = NULL;
+          variant var;
           const char * iname = locale_string(lang, itl->rtype->_name[0]);
-          if (findtoken(&in->names, iname, &result)==E_TOK_NOMATCH || result!=itl) {
-            addtoken(&in->names, iname, (void*)itl);
-            addtoken(&in->names, locale_string(lang, itl->rtype->_name[1]), (void*)itl);
+          if (findtoken(&in->names, iname, &var)==E_TOK_NOMATCH || var.v!=itl) {
+            var.v = (void*)itl;
+            addtoken(&in->names, iname, var);
+            addtoken(&in->names, locale_string(lang, itl->rtype->_name[1]), var);
           }
         }
       }
@@ -2332,7 +2339,7 @@ const item_type *
 finditemtype(const char * name, const struct locale * lang)
 {
   local_names * in = inames;
-  void * i;
+  variant var;
 
   while (in!=NULL) {
     if (in->lang==lang) break;
@@ -2342,8 +2349,8 @@ finditemtype(const char * name, const struct locale * lang)
     init_itemnames();
     for (in=inames;in->lang!=lang;in=in->next) ;
   }
-  if (findtoken(&in->names, name, &i)==E_TOK_NOMATCH) return NULL;
-  return (const item_type*)i;
+  if (findtoken(&in->names, name, &var)==E_TOK_NOMATCH) return NULL;
+  return (const item_type*)var.v;
 }
 
 static void
diff --git a/src/common/kernel/kernel.vcproj b/src/common/kernel/kernel.vcproj
index 850c497d8..799c65bdf 100644
--- a/src/common/kernel/kernel.vcproj
+++ b/src/common/kernel/kernel.vcproj
@@ -87,6 +87,7 @@
 				ProgramDataBaseFileName=".\Debug/"
 				WarningLevel="4"
 				SuppressStartupBanner="TRUE"
+				Detect64BitPortabilityProblems="TRUE"
 				DebugInformationFormat="1"
 				CompileAs="0"/>
 			<Tool
@@ -352,9 +353,6 @@
 		<File
 			RelativePath=".\names.c">
 		</File>
-		<File
-			RelativePath=".\objtypes.c">
-		</File>
 		<File
 			RelativePath=".\order.c">
 		</File>
diff --git a/src/common/kernel/magic.c b/src/common/kernel/magic.c
index 45fb5528c..5cfa43684 100644
--- a/src/common/kernel/magic.c
+++ b/src/common/kernel/magic.c
@@ -118,12 +118,12 @@ a_readicastle(attrib * a, FILE * f)
 		data->type = NULL;
 		return AT_READ_FAIL;
 	} else {
-		int bno;
-		fscanf(f, "%s %d %d", buf, &bno, &data->time);
-		data->building = findbuilding(bno);
+		variant bno;
+		fscanf(f, "%s %d %d", buf, &bno.i, &data->time);
+		data->building = findbuilding(bno.i);
 		if (!data->building) {
 			/* this shouldn't happen, but just in case it does: */
-			ur_add((void*)bno, (void**)&data->building, resolve_building);
+			ur_add(bno, (void**)&data->building, resolve_building);
 		}
 		data->type = bt_find(buf);
 		return AT_READ_OK;
@@ -1279,6 +1279,7 @@ do_fumble(castorder *co)
   spell * sp = co->sp;
   int level = co->level;
   int duration;
+  variant effect;
   const char * sp_name = spell_name(sp, u->faction->locale);
 
   ADDMSG(&u->faction->msgs, msg_message("patzer", "unit region spell",
@@ -1312,9 +1313,10 @@ do_fumble(castorder *co)
   case 2:
     /* tempor�rer Stufenverlust */
     duration = max(rand()%level/2, 2);
+    effect.i = -(level/2);
     c = create_curse(u, &u->attribs, ct_find("skil"), level, duration,
-      -(level/2), 1);
-    c->data = (void*)SK_MAGIC;
+      effect, 1);
+    c->data.i = SK_MAGIC;
     ADDMSG(&u->faction->msgs, msg_message("patzer2", "unit region", u, r));
     break;
   case 3:
@@ -1805,8 +1807,8 @@ addparam_region(char ** param, spllprm ** spobjp, const unit * u, order * ord)
     return -1;
   } else {
     int tx = atoi(param[0]), ty = atoi(param[1]);
-    int x = rel_to_abs(0, u->faction, tx, 0);
-    int y = rel_to_abs(0, u->faction, ty, 1);
+    short x = rel_to_abs(0, u->faction, (short)tx, 0);
+    short y = rel_to_abs(0, u->faction, (short)ty, 1);
     region *rt = findregion(x,y);
 
     if (rt!=NULL) {
@@ -2168,7 +2170,7 @@ create_newfamiliar(unit * mage, unit * familiar)
 }
 
 static void *
-resolve_familiar(void * data)
+resolve_familiar(variant data)
 {
 	unit * familiar = resolve_unit(data);
 	if (familiar) {
@@ -2184,10 +2186,10 @@ resolve_familiar(void * data)
 static int
 read_familiar(attrib * a, FILE * F)
 {
-	int i;
+	variant id;
 	fscanf(F, "%s", buf);
-	i = atoi36(buf);
-	ur_add((void*)i, &a->data.v, resolve_familiar);
+	id.i = atoi36(buf);
+	ur_add(id, &a->data.v, resolve_familiar);
 	return AT_READ_OK;
 }
 
@@ -2245,7 +2247,7 @@ has_clone(unit *mage)
 }
 
 static void *
-resolve_clone(void * data)
+resolve_clone(variant data)
 {
 	unit * clone = resolve_unit(data);
 	if (clone) {
@@ -2261,17 +2263,17 @@ resolve_clone(void * data)
 static int
 read_clone(attrib * a, FILE * F)
 {
-	int i;
+	variant id;
 	fscanf(F, "%s", buf);
-	i = atoi36(buf);
-	ur_add((void*)i, &a->data.v, resolve_clone);
+	id.i = atoi36(buf);
+	ur_add(id, &a->data.v, resolve_clone);
 	return AT_READ_OK;
 }
 
 /* mages */
 
 static void *
-resolve_mage(void * data)
+resolve_mage(variant data)
 {
 	unit * mage = resolve_unit(data);
 	if (mage) {
@@ -2287,10 +2289,10 @@ resolve_mage(void * data)
 static int
 read_magician(attrib * a, FILE * F)
 {
-	int i;
+	variant id;
 	fscanf(F, "%s", buf);
-	i = atoi36(buf);
-	ur_add((void*)i, &a->data.v, resolve_mage);
+	id.i = atoi36(buf);
+	ur_add(id, &a->data.v, resolve_mage);
 	return AT_READ_OK;
 }
 
@@ -2417,7 +2419,8 @@ magic(void)
   spell *sp;
   const char *s;
   int spellrank;
-  int range, t_x, t_y;
+  int range;
+  short t_x, t_y;
   castorder *co;
   castorder *cll[MAX_SPELLRANK];
   spellparameter *args;
@@ -2477,9 +2480,9 @@ magic(void)
             }
           }
           if (findparam(s, u->faction->locale) == P_REGION) {
-            t_x = atoi(getstrtoken());
+            t_x = (short)atoi(getstrtoken());
             t_x = rel_to_abs(getplane(u->region),u->faction,t_x,0);
-            t_y = atoi(getstrtoken());
+            t_y = (short)atoi(getstrtoken());
             t_y = rel_to_abs(getplane(u->region),u->faction,t_y,1);
             target_r = findregion(t_x, t_y);
             s = getstrtoken();
@@ -2574,7 +2577,7 @@ magic(void)
             if (range > 1024) { /* (2^10) weiter als 10 Regionen entfernt */
               ADDMSG(&u->faction->msgs, msg_message("spellfail::nocontact",
                 "mage region command target", u, u->region, ord, 
-                gc_add(strdup(regionname(target_r, u->faction)))));
+                regionname(target_r, u->faction)));
               continue;
             }
           }
@@ -2627,7 +2630,7 @@ magic(void)
           /* Weitere Argumente zusammenbasten */
           if (sp->parameter) {
             char ** params = malloc(2*sizeof(char*));
-            size_t p = 0, size = 2;
+            int p = 0, size = 2;
             for (;;) {
               s = getstrtoken();
               if (*s==0) break;
diff --git a/src/common/kernel/message.c b/src/common/kernel/message.c
index dd12b9f91..da2cc5587 100644
--- a/src/common/kernel/message.c
+++ b/src/common/kernel/message.c
@@ -90,14 +90,13 @@ mc_add(const char * name)
 }
 
 static void
-arg_set(void * args[], const message_type * mtype, const char * buffer, void * v)
+arg_set(variant args[], const message_type * mtype, const char * buffer, variant v)
 {
 	int i;
 	for (i=0;i!=mtype->nparameters;++i) {
 		if (!strcmp(buffer, mtype->pnames[i])) break;
 	}
   if (i!=mtype->nparameters) {
-    assert(args[i]==NULL);
     args[i] = v;
   } else {
 		fprintf(stderr, "invalid parameter %s for message type %s\n", buffer, mtype->name);
@@ -110,9 +109,10 @@ msg_feedback(const struct unit * u, struct order * ord, const char * name, const
 {
 	va_list marker;
 	const message_type * mtype = mt_find(name);
-	char buffer[64], *oc = buffer;
+	char paramname[64];
 	const char *ic = sig;
-	void * args[16];
+	variant args[16];
+  variant var;
 	memset(args, 0, sizeof(args));
 
 	if (ord==NULL) ord = u->thisorder;
@@ -122,23 +122,42 @@ msg_feedback(const struct unit * u, struct order * ord, const char * name, const
 		return NULL;
 	}
 
-	arg_set(args, mtype, "unit", (void*)u);
-	arg_set(args, mtype, "region", (void*)u->region);
-	arg_set(args, mtype, "command", (void*)ord);
+  var.v = (void*)u;
+	arg_set(args, mtype, "unit", var);
+  var.v = (void*)u->region;
+	arg_set(args, mtype, "region", var);
+  var.v = (void*)ord;
+	arg_set(args, mtype, "command", var);
 
 	va_start(marker, sig);
 	while (*ic && !isalnum(*ic)) ic++;
 	while (*ic) {
-		void * v = va_arg(marker, void *);
-		oc = buffer;
-		while (isalnum(*ic)) *oc++ = *ic++;
+		char * oc = paramname;
+    int i;
+
+    while (isalnum(*ic)) *oc++ = *ic++;
 		*oc = '\0';
-		arg_set(args, mtype, buffer, v);
-		while (*ic && !isalnum(*ic)) ic++;
+
+    for (i=0;i!=mtype->nparameters;++i) {
+      if (!strcmp(paramname, mtype->pnames[i])) break;
+    }
+    if (i!=mtype->nparameters) {
+      if (mtype->types[i]->vtype==VAR_VOIDPTR) {
+        args[i].v = va_arg(marker, void*);
+      } else if (mtype->types[i]->vtype==VAR_INT) {
+        args[i].i = va_arg(marker, int);
+      } else {
+        assert(!"unknown variant type");
+      }
+    } else {
+      log_error(("invalid parameter %s for message type %s\n", paramname, mtype->name));
+      assert(!"program aborted.");
+    }
+    while (*ic && !isalnum(*ic)) ic++;
 	}
 	va_end(marker);
 
-	return msg_create(mtype, (void**)args);
+	return msg_create(mtype, args);
 }
 
 message * 
@@ -147,9 +166,9 @@ msg_message(const char * name, const char* sig, ...)
 {
 	va_list marker;
 	const message_type * mtype = mt_find(name);
-	char buffer[64], *oc = buffer;
+	char paramname[64];
 	const char *ic = sig;
-	void * args[16];
+	variant args[16];
 	memset(args, 0, sizeof(args));
 
 	if (!mtype) {
@@ -160,16 +179,32 @@ msg_message(const char * name, const char* sig, ...)
 	va_start(marker, sig);
 	while (*ic && !isalnum(*ic)) ic++;
 	while (*ic) {
-		void * v = va_arg(marker, void *);
-		oc = buffer;
-		while (isalnum(*ic)) *oc++ = *ic++;
-		*oc = '\0';
-		arg_set(args, mtype, buffer, v);
-		while (*ic && !isalnum(*ic)) ic++;
-	}
-	va_end(marker);
+		char * oc = paramname;
+    int i;
 
-	return msg_create(mtype, (void**)args);
+    while (isalnum(*ic)) *oc++ = *ic++;
+		*oc = '\0';
+
+    for (i=0;i!=mtype->nparameters;++i) {
+      if (!strcmp(paramname, mtype->pnames[i])) break;
+    }
+    if (i!=mtype->nparameters) {
+      if (mtype->types[i]->vtype==VAR_VOIDPTR) {
+        args[i].v = va_arg(marker, void*);
+      } else if (mtype->types[i]->vtype==VAR_INT) {
+        args[i].i = va_arg(marker, int);
+      } else {
+        assert(!"unknown variant type");
+      }
+    } else {
+      log_error(("invalid parameter %s for message type %s\n", paramname, mtype->name));
+      assert(!"program aborted.");
+    }
+    while (*ic && !isalnum(*ic)) ic++;
+  }
+  va_end(marker);
+
+  return msg_create(mtype, args);
 }
 
 message *
@@ -185,7 +220,7 @@ new_message(struct faction * receiver, const char* sig, ...)
 	char buffer[128];
 	int i=0;
 	const char * c = sig;
-	void * args[16];
+	variant args[16];
 
 	memset(args, 0, sizeof(args));
 	assert(signature-sig < sizeof(buffer));
@@ -232,45 +267,43 @@ new_message(struct faction * receiver, const char* sig, ...)
 		}
 		switch(type) {
 			case 's':
-				args[i] = (void*)va_arg(marker, const char *);
-				break;
-			case 'i':
-				args[i] = (void*)va_arg(marker, int);
+				args[i].v = (void*)va_arg(marker, const char *);
 				break;
 			case 'f':
-				args[i] = (void*)va_arg(marker, const struct faction*);
+				args[i].v = (void*)va_arg(marker, const struct faction*);
 				break;
 			case 'u':
-				args[i] = (void*)va_arg(marker, const struct unit*);
+				args[i].v = (void*)va_arg(marker, const struct unit*);
 				break;
 			case 'r':
-				args[i] = (void*)va_arg(marker, const struct region*);
+				args[i].v = (void*)va_arg(marker, const struct region*);
 				break;
 			case 'h':
-				args[i] = (void*)va_arg(marker, const struct ship*);
+				args[i].v = (void*)va_arg(marker, const struct ship*);
 				break;
 			case 'b':
-				args[i] = (void*)va_arg(marker, const struct building*);
+				args[i].v = (void*)va_arg(marker, const struct building*);
 				break;
 			case 'X':
-				args[i] = (void*)va_arg(marker, const resource_type *);
+				args[i].v = (void*)va_arg(marker, const resource_type *);
 				break;
 			case 'x':
-				args[i] = (void*)oldresourcetype[(resource_t)va_arg(marker, int)];
+				args[i].v = oldresourcetype[(resource_t)va_arg(marker, int)];
 				break;
 			case 't':
-				args[i] = (void*)va_arg(marker, int);
+      case 'i':
+				args[i].i = va_arg(marker, int);
 				break;
 			case 'd':
-				args[i] = (void*)i;
+				args[i].i = i;
 				break;
 			case 'S':
 			default:
-				args[i] = NULL;
+				args[i].v = NULL;
 		}
 	}
 	va_end(marker);
-	return msg_create(mtype, (void**)args);
+	return msg_create(mtype, args);
 }
 
 static void
@@ -323,7 +356,7 @@ caddmessage(region * r, faction * f, const char *s, msg_t mtype, int level)
 void
 addmessage(region * r, faction * f, const char *s, msg_t mtype, int level)
 {
-  caddmessage(r, f, gc_add(strdup(s)), mtype, level);
+  caddmessage(r, f, s, mtype, level);
 }
 
 void
diff --git a/src/common/kernel/names.c b/src/common/kernel/names.c
index d9ceaf52f..cde22751e 100644
--- a/src/common/kernel/names.c
+++ b/src/common/kernel/names.c
@@ -645,8 +645,7 @@ abkz(const char *s, size_t max)
 	static char buf[32];
 	const char *p = s;
 	unsigned int c = 0;
-	int   bpt;
-	int   i;
+	size_t bpt, i;
 
 	max = min(max, 79);
 
diff --git a/src/common/kernel/objtypes.c b/src/common/kernel/objtypes.c
deleted file mode 100644
index b24c2bc49..000000000
--- a/src/common/kernel/objtypes.c
+++ /dev/null
@@ -1,215 +0,0 @@
-/* vi: set ts=2:
- *
- *	
- *	Eressea PB(E)M host Copyright (C) 1998-2003
- *      Christian Schlittchen (corwin@amber.kn-bremen.de)
- *      Katja Zedel (katze@felidae.kn-bremen.de)
- *      Henning Peters (faroul@beyond.kn-bremen.de)
- *      Enno Rehling (enno@eressea-pbem.de)
- *      Ingo Wilken (Ingo.Wilken@informatik.uni-oldenburg.de)
- *
- *  based on:
- *
- * Atlantis v1.0  13 September 1993 Copyright 1993 by Russell Wallace
- * Atlantis v1.7                    Copyright 1996 by Alex Schr�der
- *
- * This program may not be used, modified or distributed without
- * prior permission by the authors of Eressea.
- * This program may not be sold or used commercially without prior written
- * permission from the authors.
- */
-
-#include <config.h>
-#include "eressea.h"
-#include "objtypes.h"
-
-/* kernel includes */
-#include "building.h"
-#include "faction.h"
-#include "region.h"
-#include "ship.h"
-#include "unit.h"
-
-/* libc includes */
-#include <assert.h>
-#include <stdlib.h>
-
-obj_ID
-get_ID(void *obj, typ_t typ)
-{
-	ID_fun fun = typdata[typ].getID;
-	return fun(obj);
-}
-
-void
-write_ID(FILE *f, obj_ID id)
-{
-	fprintf(f, "%d:%d ", id.a, id.b);
-}
-
-obj_ID
-read_ID(FILE *f)
-{
-	obj_ID id;
-
-	fscanf(f, "%d:%d", &id.a, &id.b);
-	return id;
-}
-
-/****** Unit ******/
-static obj_ID unit_ID(void *p) {
-	obj_ID id; id.a = p ? ((unit *)p)->no : 0; id.b = 0; return id;
-}
-static void * unit_find(obj_ID id) {
-	return (void *)ufindhash(id.a);
-}
-static attrib ** unit_attribs( void *p ) {
-	return &((unit *)p)->attribs;
-}
-static void unit_set( void *pp, void *p ) {
-	*(unit **)pp = (unit *)p;
-}
-
-/****** Region ******/
-static obj_ID region_ID(void *p) {
-	/* Bei Regionen gibts keine NULL-Pointer */
-	obj_ID id; id.a = ((region *)p)->x; id.b = ((region *)p)->y; return id;
-}
-static void * region_find(obj_ID id) {
-	return (void *)findregion(id.a, id.b);
-}
-static attrib ** region_attribs( void *p ) {
-	return &((region *)p)->attribs;
-}
-static void region_set( void *pp, void *p ) {
-	*(region **)pp = (region *)p;
-}
-
-/****** Building ******/
-static obj_ID building_ID(void *p) {
-	obj_ID id; id.a = p ? ((building *)p)->no : 0; id.b = 0; return id;
-}
-static void * building_find(obj_ID id) {
-	return (void *)findbuilding(id.a);
-}
-static attrib ** building_attribs( void *p ) {
-	return &((building *)p)->attribs;
-}
-static void building_set( void *pp, void *p ) {
-	*(building **)pp = (building *)p;
-}
-
-/****** Ship ******/
-static void * ship_find(obj_ID id) {
-	return (void *)findship(id.a);
-}
-static obj_ID ship_ID(void *p) {
-	obj_ID id; id.a = p ? ((ship *)p)->no : 0; id.b = 0; return id;
-}
-static attrib ** ship_attribs( void *p ) {
-	return &((ship *)p)->attribs;
-}
-static void ship_set( void *pp, void *p ) {
-	*(ship **)pp = (ship *)p;
-}
-
-/****** Faction ******/
-static void * faction_find(obj_ID id) {
-	return (void *)findfaction(id.a);
-}
-static obj_ID faction_ID(void *p) {
-	obj_ID id; id.a = p ? ((faction *)p)->no : 0; id.b = 0; return id;
-}
-static attrib ** faction_attribs( void *p ) {
-	return &((faction *)p)->attribs;
-}
-static void faction_set( void *pp, void *p ) {
-	*(faction **)pp = (faction *)p;
-}
-
-/******* Typ-Funktionstabelle ********/
-
-typdata_t typdata[] = {
-	/* TYP_UNIT */ {
-		(ID_fun)unit_ID,
-		(find_fun)unit_find,
-		(attrib_fun)unit_attribs,
-		(set_fun)unit_set,
-	},
-	/* TYP_REGION */ {
-		(ID_fun)region_ID,
-		(find_fun)region_find,
-		(attrib_fun)region_attribs,
-		(set_fun)region_set,
-	},
-	/* TYP_BUILDING */ {
-		(ID_fun)building_ID,
-		(find_fun)building_find,
-		(attrib_fun)building_attribs,
-		(set_fun)building_set,
-	},
-	/* TYP_SHIP */ {
-		(ID_fun)ship_ID,
-		(find_fun)ship_find,
-		(attrib_fun)ship_attribs,
-		(set_fun)ship_set,
-	},
-	/* TYP_FACTION */ {
-		(ID_fun)faction_ID,
-		(find_fun)faction_find,
-		(attrib_fun)faction_attribs,
-		(set_fun)faction_set,
-	},
-};
-
-/******** Resolver-Funktionen f�r obj_ID ********/
-
-#define tag_t int
-#define TAG_NOTAG (-1)
-
-typedef struct unresolved2 {
-	struct unresolved2 *next;
-
-	obj_ID	id;
-	void *	objPP;
-	typ_t	typ;
-	tag_t	tag; /* completely useless. eliminate */
-} unresolved2;
-
-static unresolved2 *ur2_list;
-
-
-void
-add_ID_resolve2(obj_ID id, void *objPP, typ_t typ, tag_t tag)
-{
-	unresolved2 *ur = calloc(1, sizeof(unresolved2));
-
-	ur->id = id;
-	ur->objPP = objPP;
-	ur->typ = typ;
-	ur->tag = tag;
-	ur->next = ur2_list;
-	ur2_list = ur;
-}
-
-void
-add_ID_resolve(obj_ID id, void *objPP, typ_t typ)
-{
-	add_ID_resolve2(id, objPP, typ, TAG_NOTAG);
-}
-
-void
-resolve_IDs(void)
-{
-	unresolved2 *ur;
-	void *robj;
-
-	while( (ur = ur2_list) != NULL ) {
-		ur2_list = ur->next;
-
-		robj = typdata[ur->typ].find(ur->id);
-		typdata[ur->typ].ppset(ur->objPP, robj);
-		free(ur);
-	}
-}
-
diff --git a/src/common/kernel/objtypes.h b/src/common/kernel/objtypes.h
index 0d5c9360e..5fe147768 100644
--- a/src/common/kernel/objtypes.h
+++ b/src/common/kernel/objtypes.h
@@ -19,10 +19,6 @@
 extern "C" {
 #endif
 
-typedef struct obj_ID {
-	int a, b;
-} obj_ID;
-
 enum {
 	TYP_UNIT,
 	TYP_REGION,
@@ -34,29 +30,6 @@ enum {
 	TYP_TIMEOUT
 };
 
-extern obj_ID get_ID(void *obj, typ_t typ);
-extern void write_ID(FILE *f, obj_ID id);
-extern obj_ID read_ID(FILE *f);
-
-extern void add_ID_resolve(obj_ID id, void *objPP, typ_t typ);
-extern void resolve_IDs(void);
-
-
-typedef obj_ID (*ID_fun)(void *obj);
-typedef void *(*find_fun)(obj_ID id);
-typedef attrib **(*attrib_fun)(void *obj);
-typedef void (*set_fun)(void *ptrptr, void *obj);	/* 	*ptrptr = obj  */
-
-
-typedef struct {
-	ID_fun		getID;		/* liefert obj_ID zu struct unit* */
-	find_fun	find;		/* liefert struct unit* zu obj_ID  */
-	attrib_fun	getattribs;	/* liefert &u->attribs */
-	set_fun		ppset;		/* setzt *(struct unit **) zu struct unit*  */
-} typdata_t;
-
-extern typdata_t typdata[];
-
 #ifdef __cplusplus
 }
 #endif
diff --git a/src/common/kernel/plane.c b/src/common/kernel/plane.c
index be9b75db1..3fd255a71 100644
--- a/src/common/kernel/plane.c
+++ b/src/common/kernel/plane.c
@@ -69,7 +69,7 @@ getplanebyname(const char * name)
 }
 
 plane *
-findplane(int x, int y)
+findplane(short x, short y)
 {
 	plane *pl;
 
@@ -100,7 +100,7 @@ getplaneid(const region *r)
 	return 0;
 }
 
-static int
+static short
 ursprung_x(const faction *f, const plane *pl, const region * rdefault)
 {
 	ursprung *ur;
@@ -121,7 +121,7 @@ ursprung_x(const faction *f, const plane *pl, const region * rdefault)
 	return rdefault->x - plane_center_x(pl);
 }
 
-static int
+static short
 ursprung_y(const faction *f, const plane *pl, const region * rdefault)
 {
 	ursprung *ur;
@@ -142,7 +142,7 @@ ursprung_y(const faction *f, const plane *pl, const region * rdefault)
 	return rdefault->y - plane_center_y(pl);
 }
 
-int
+short 
 plane_center_x(const plane *pl)
 {
 	if(pl == NULL)
@@ -151,7 +151,7 @@ plane_center_x(const plane *pl)
 	return(pl->minx + pl->maxx)/2;
 }
 
-int
+short 
 plane_center_y(const plane *pl)
 {
 	if(pl == NULL)
@@ -160,7 +160,7 @@ plane_center_y(const plane *pl)
 	return(pl->miny + pl->maxy)/2;
 }
 
-int
+short
 region_x(const region *r, const faction *f)
 {
 	plane *pl;
@@ -169,7 +169,7 @@ region_x(const region *r, const faction *f)
 	return r->x - ursprung_x(f, pl, r) - plane_center_x(pl);
 }
 
-int
+short
 region_y(const region *r, const faction *f)
 {
 	plane *pl;
@@ -179,14 +179,14 @@ region_y(const region *r, const faction *f)
 }
 
 void
-set_ursprung(faction *f, int id, int x, int y)
+set_ursprung(faction *f, int id, short x, short y)
 {
 	ursprung *ur;
 	assert(f!=NULL);
 	for(ur=f->ursprung;ur;ur=ur->next) {
-		if(ur->id == id) {
-			ur->x += x;
-			ur->y += y;
+		if (ur->id == id) {
+			ur->x = ur->x + x;
+			ur->y = ur->y + y;
 			return;
 		}
 	}
@@ -200,7 +200,7 @@ set_ursprung(faction *f, int id, int x, int y)
 }
 
 plane *
-create_new_plane(int id, const char *name, int minx, int maxx, int miny, int maxy, int flags)
+create_new_plane(int id, const char *name, short minx, short maxx, short miny, short maxy, int flags)
 {
 	plane *pl = getplanebyid(id);
 
@@ -221,8 +221,8 @@ create_new_plane(int id, const char *name, int minx, int maxx, int miny, int max
 }
 
 /* Umrechnung Relative-Absolute-Koordinaten */
-int
-rel_to_abs(const struct plane *pl, const struct faction * f, int rel, unsigned char index)
+short 
+rel_to_abs(const struct plane *pl, const struct faction * f, short rel, unsigned char index)
 {
 	assert(index == 0 || index == 1);
 
@@ -234,9 +234,9 @@ rel_to_abs(const struct plane *pl, const struct faction * f, int rel, unsigned c
 
 
 void *
-resolve_plane(void * id)
+resolve_plane(variant id)
 {
-   return getplanebyid((int)id);
+   return getplanebyid(id.i);
 }
 
 void
@@ -248,14 +248,14 @@ write_plane_reference(const plane * u, FILE * F)
 int
 read_plane_reference(plane ** pp, FILE * F)
 {
-	int i;
-	fscanf(F, "%d", &i);
-	if (i==0) {
+	variant id;
+	fscanf(F, "%d", &id.i);
+	if (id.i==0) {
 		*pp = NULL;
 		return AT_READ_FAIL;
 	}
-	*pp = getplanebyid(i);
-	if (*pp==NULL) ur_add((void*)i, (void**)pp, resolve_plane);
+	*pp = getplanebyid(id.i);
+	if (*pp==NULL) ur_add(id, (void**)pp, resolve_plane);
 	return AT_READ_OK;
 }
 
diff --git a/src/common/kernel/plane.h b/src/common/kernel/plane.h
index 5c9f3e330..753792960 100644
--- a/src/common/kernel/plane.h
+++ b/src/common/kernel/plane.h
@@ -52,7 +52,7 @@ typedef struct plane {
 	struct watcher * watchers;
 	int id;
 	char *name;
-	int minx,maxx,miny,maxy;
+	short minx, maxx, miny, maxy;
 	unsigned int flags;
 	struct attrib *attribs;
 } plane;
@@ -60,20 +60,20 @@ typedef struct plane {
 extern struct plane *planes;
 
 struct plane *getplane(const struct region *r);
-struct plane *findplane(int x, int y);
+struct plane *findplane(short x, short y);
 void init_planes(void);
 int getplaneid(const struct region *r);
 struct plane * getplanebyid(int id);
-int region_x(const struct region *r, const struct faction *f);
-int region_y(const struct region *r, const struct faction *f);
-int plane_center_x(const struct plane *pl);
-int plane_center_y(const struct plane *pl);
-void set_ursprung(struct faction *f, int id, int x, int y);
-plane * create_new_plane(int id, const char *name, int minx, int maxx, int miny, int maxy, int flags);
+short region_x(const struct region *r, const struct faction *f);
+short region_y(const struct region *r, const struct faction *f);
+short plane_center_x(const struct plane *pl);
+short plane_center_y(const struct plane *pl);
+void set_ursprung(struct faction *f, int id, short x, short y);
+plane * create_new_plane(int id, const char *name, short minx, short maxx, short miny, short maxy, int flags);
 plane * getplanebyname(const char *);
-extern int rel_to_abs(const struct plane *pl, const struct faction * f, int rel, unsigned char index);
+extern short rel_to_abs(const struct plane *pl, const struct faction * f, short rel, unsigned char index);
 extern boolean is_watcher(const struct plane * p, const struct faction * f);
-extern void * resolve_plane(void * data);
+extern void * resolve_plane(variant data);
 extern void write_plane_reference(const plane * p, FILE * F);
 extern int read_plane_reference(plane ** pp, FILE * F);
 
diff --git a/src/common/kernel/region.c b/src/common/kernel/region.c
index 50a309487..0447671a9 100644
--- a/src/common/kernel/region.c
+++ b/src/common/kernel/region.c
@@ -50,12 +50,12 @@ extern int dice_rand(const char *s);
 
 static int g_maxluxuries = 0;
 
-const int delta_x[MAXDIRECTIONS] =
+const short delta_x[MAXDIRECTIONS] =
 {
   -1, 0, 1, 1, 0, -1
 };
 
-const int delta_y[MAXDIRECTIONS] =
+const short delta_y[MAXDIRECTIONS] =
 {
   1, 1, 0, -1, -1, 0
 };
@@ -193,7 +193,7 @@ int
 a_readdirection(attrib *a, FILE *f)
 {
 	spec_direction *d = (spec_direction *)(a->data.v);
-	fscanf(f, "%d %d %d", &d->x, &d->y, &d->duration);
+	fscanf(f, "%hd %hd %d", &d->x, &d->y, &d->duration);
 	fscanf(f, "%s ", buf);
 	d->desc = strdup(cstring(buf));
 	fscanf(f, "%s ", buf);
@@ -279,10 +279,10 @@ attrib_type at_moveblock = {
 region *regionhash[RMAXHASH];
 
 static region *
-rfindhash(int x, int y)
+rfindhash(short x, short y)
 {
 	region *old;
-	for (old = regionhash[abs(x + 0x100 * y) % RMAXHASH]; old; old = old->nexthash)
+	for (old = regionhash[coor_hashkey(x, y) % RMAXHASH]; old; old = old->nexthash)
 		if (old->x == x && old->y == y)
 			return old;
 	return 0;
@@ -291,8 +291,9 @@ rfindhash(int x, int y)
 void
 rhash(region * r)
 {
-	region *old = regionhash[region_hashkey(r) % RMAXHASH];
-	regionhash[region_hashkey(r) % RMAXHASH] = r;
+  int key = coor_hashkey(r->x, r->y) % RMAXHASH;
+	region *old = regionhash[key];
+	regionhash[key] = r;
 	r->nexthash = old;
 }
 
@@ -300,7 +301,7 @@ void
 runhash(region * r)
 {
 	region **show;
-	for (show = &regionhash[abs(r->x + 0x100 * r->y) % RMAXHASH]; *show; show = &(*show)->nexthash) {
+	for (show = &regionhash[coor_hashkey(r->x, r->y) % RMAXHASH]; *show; show = &(*show)->nexthash) {
 		if ((*show)->x == r->x && (*show)->y == r->y)
 			break;
 	}
@@ -339,7 +340,7 @@ r_connect(const region * r, direction_t dir)
 }
 
 region *
-findregion(int x, int y)
+findregion(short x, short y)
 {
 	return rfindhash(x, y);
 }
@@ -553,7 +554,7 @@ rlaen(const region * r)
 /*   at_road   */
 /***************/
 attrib_type at_road = {
-	"road",
+	"road", 
 	DEFAULT_INIT,
 	DEFAULT_FINALIZE,
 	DEFAULT_AGE,
@@ -576,12 +577,12 @@ rsetroad(region * r, direction_t d, int val)
 	b = get_borders(r, r2);
 	while (b && b->type!=&bt_road) b = b->next;
 	if (!b) b = new_border(&bt_road, r, r2);
-	rval = (int)b->data;
+	rval = b->data.i;
 	if (b->from==r)
 		rval = (rval & 0xFFFF) | (val<<16);
 	else
 		rval = (rval & 0xFFFF0000) | val;
-	b->data = (void*)rval;
+	b->data.i = rval;
 }
 
 int
@@ -595,7 +596,7 @@ rroad(const region * r, direction_t d)
 	b = get_borders(r, r2);
 	while (b && b->type!=&bt_road) b = b->next;
 	if (!b) return 0;
-	rval = (int)b->data;
+	rval = b->data.i;
 	if (b->to==r)
 		rval = (rval & 0xFFFF);
 	else
@@ -754,7 +755,7 @@ static region *last;
 static unsigned int max_index = 0;
 #endif
 region *
-new_region(int x, int y)
+new_region(short x, short y)
 {
 	region *r = rfindhash(x, y);
 
@@ -827,7 +828,7 @@ static char *
 makename(void)
 {
 	int s, v, k, e, p = 0, x = 0;
-	int nk, ne, nv, ns;
+	size_t nk, ne, nv, ns;
 	static char name[16];
 	const char *kons = "bcdfghklmnprstvwz",
 		*end = "nlrdst",
@@ -841,19 +842,19 @@ makename(void)
 
 	for (s = rand() % 3 + 2; s > 0; s--) {
 		if (x > 0) {
-			k = rand() % nk;
+			k = rand() % (int)nk;
 			name[p] = kons[k];
 			p++;
 		} else {
-			k = rand() % ns;
+			k = rand() % (int)ns;
 			name[p] = start[k];
 			p++;
 		}
-		v = rand() % nv;
+		v = rand() % (int)nv;
 		name[p] = vokal[v];
 		p++;
 		if (rand() % 3 == 2 || s == 1) {
-			e = rand() % ne;
+			e = rand() % (int)ne;
 			name[p] = end[e];
 			p++;
 			x = 1;
@@ -1112,14 +1113,17 @@ production(const region *r)
 int
 read_region_reference(region ** r, FILE * F)
 {
-	int x[2];
-	fscanf(F, "%d %d", &x[0], &x[1]);
-	if (x[0]==INT_MAX) {
+	variant coor;
+	fscanf(F, "%hd %hd", &coor.sa[0], &coor.sa[1]);
+	if (coor.sa[0]==SHRT_MAX) {
 		*r = NULL;
 		return AT_READ_FAIL;
 	}
-	*r = findregion(x[0], x[1]);
-	if (*r==NULL) ur_add(memcpy(malloc(sizeof(x)), x, sizeof(x)), (void**)r, resolve_region);
+	*r = findregion(coor.sa[0], coor.sa[1]);
+
+  if (*r==NULL) {
+    ur_add(coor, (void**)r, resolve_region);
+  }
 	return AT_READ_OK;
 }
 
@@ -1127,15 +1131,12 @@ void
 write_region_reference(const region * r, FILE * F)
 {
 	if (r) fprintf(F, "%d %d ", r->x, r->y);
-	else fprintf(F, "%d %d ", INT_MAX, INT_MAX);
+	else fprintf(F, "%d %d ", SHRT_MAX, SHRT_MAX);
 }
 
 void *
-resolve_region(void * id) {
-	int * c = (int*)id;
-	int x = c[0], y = c[1];
-	free(c);
-	return findregion(x, y);
+resolve_region(variant id) {
+	return findregion(id.sa[0], id.sa[1]);
 }
 
 
diff --git a/src/common/kernel/region.h b/src/common/kernel/region.h
index acdcc9133..e6d85bc7b 100644
--- a/src/common/kernel/region.h
+++ b/src/common/kernel/region.h
@@ -88,7 +88,7 @@ typedef struct region {
   struct unit *units;
   struct ship *ships;
   struct building *buildings;
-  int x, y;
+  short x, y;
   struct plane *planep;
   char *display;
   unsigned int flags;
@@ -123,8 +123,7 @@ extern struct message_list * r_getmessages(const struct region * r, const struct
 extern struct message * r_addmessage(struct region * r, const struct faction * viewer, struct message * msg);
 
 typedef struct spec_direction {
-  int  x;
-  int  y;
+  short x, y;
   int  duration;
   boolean active;
   char *desc;
@@ -135,11 +134,18 @@ typedef struct {
   direction_t dir;
 } moveblock;
 
-#define region_hashkey(r) (abs((r)->x + 0x100 * (r)->y))
+#ifdef ENUM_REGIONS
+# define reg_hashkey(r) (r->index)
+# define coor_hashkey(x, y) (abs(x + 0x100 * y))
+#else
+# define reg_hashkey(r) (abs((r)->x + 0x100 * (r)->y))
+# define coor_hashkey(x, y) (abs(x + 0x100 * y))
+#endif
+
 int distance(const struct region*, const struct region*);
 int koor_distance(int ax, int ay, int bx, int by) ;
 extern direction_t reldirection(const struct region * from, const struct region * to);
-extern struct region * findregion(int x, int y);
+extern struct region * findregion(short x, short y);
 
 extern attrib_type at_direction;
 extern attrib_type at_moveblock;
@@ -227,12 +233,12 @@ extern void r_setdemand(struct region * r, const struct luxury_type * ltype, int
 extern int r_demand(const struct region * r, const struct luxury_type * ltype);
 
 extern const char * regionname(const struct region * r, const struct faction * f);
-extern void * resolve_region(void * data);
-extern struct region * new_region(int x, int y);
+extern void * resolve_region(variant data);
+extern struct region * new_region(short x, short y);
 extern void terraform(struct region * r, terrain_t terrain);
 
-extern const int delta_x[MAXDIRECTIONS];
-extern const int delta_y[MAXDIRECTIONS];
+extern const short delta_x[MAXDIRECTIONS];
+extern const short delta_y[MAXDIRECTIONS];
 extern direction_t dir_invert(direction_t dir);
 extern int production(const struct region *r);
 extern int read_region_reference(struct region ** r, FILE * F);
diff --git a/src/common/kernel/reports.c b/src/common/kernel/reports.c
index 5512cf037..024acfc61 100644
--- a/src/common/kernel/reports.c
+++ b/src/common/kernel/reports.c
@@ -971,8 +971,8 @@ free_seen(void)
 seen_region *
 find_seen(struct seen_region * seehash[], const region * r)
 {
-	int index = ((int)r) % MAXSEEHASH;
-	seen_region * find=seehash[index];
+  unsigned int index = reg_hashkey(r) % MAXSEEHASH;
+  seen_region * find = seehash[index];
 	while (find) {
 		if (find->r==r) return find;
 		find=find->nextHash;
@@ -1023,7 +1023,7 @@ add_seen(struct seen_region * seehash[], struct region * r, unsigned char mode,
 {
 	seen_region * find = find_seen(seehash, r);
 	if (find==NULL) {
-		int index = ((int)r) % MAXSEEHASH;
+		unsigned int index = reg_hashkey(r) % MAXSEEHASH;
 		if (!reuse) reuse = (seen_region*)calloc(1, sizeof(struct seen_region));
 		find = reuse;
 		reuse = reuse->nextHash;
diff --git a/src/common/kernel/save.c b/src/common/kernel/save.c
index 6673e9ff9..40cf473f1 100644
--- a/src/common/kernel/save.c
+++ b/src/common/kernel/save.c
@@ -535,7 +535,7 @@ unitorders(FILE * F, struct faction * f)
     u->botschaften = NULL;	/* Sicherheitshalber */
 
   } else {
-    /* cmistake(?, gc_add(strdup(buf)), 160, MSG_EVENT); */
+    /* cmistake(?, buf, 160, MSG_EVENT); */
     return NULL;
   }
   return u;
@@ -995,20 +995,20 @@ lastturn(void)
 int
 read_faction_reference(faction ** f, FILE * F)
 {
-	int id;
+	variant id;
 	if (global.data_version >= BASE36IDS_VERSION) {
 		char zText[10];
 		fscanf(F, "%s ", zText);
-		id = atoi36(zText);
+		id.i = atoi36(zText);
 	} else {
-		fscanf(F, "%d ", &id);
+		fscanf(F, "%d ", &id.i);
 	}
-	if (id<0) {
+	if (id.i<0) {
 		*f = NULL;
 		return AT_READ_FAIL;
 	}
-	*f = findfaction(id);
-	if (*f==NULL) ur_add((void*)id, (void**)f, resolve_faction);
+	*f = findfaction(id.i);
+	if (*f==NULL) ur_add(id, (void**)f, resolve_faction);
 	return AT_READ_OK;
 }
 
@@ -1288,7 +1288,7 @@ writeunit(FILE * F, const unit * u)
 }
 
 region *
-readregion(FILE * F, int x, int y)
+readregion(FILE * F, short x, short y)
 {
 	region * r = findregion(x, y);
 	int ter;
@@ -1524,6 +1524,7 @@ addally(const faction * f, ally ** sfp, int aid, int state)
 {
   struct faction * af = findfaction(aid);
   ally * sf;
+
   state &= ~HELP_OBSERVE;
 #ifndef REGIONOWNERS
   state &= ~HELP_TRAVEL;
@@ -1533,7 +1534,11 @@ addally(const faction * f, ally ** sfp, int aid, int state)
 
   sf = calloc(1, sizeof(ally));
   sf->faction = af;
-  if (!sf->faction) ur_add((void*)aid, (void**)&sf->faction, resolve_faction);
+  if (!sf->faction) {
+    variant id;
+    id.i = aid;
+    ur_add(id, (void**)&sf->faction, resolve_faction);
+  }
   sf->status = state & HELP_ALL;
 
   while (*sfp) sfp=&(*sfp)->next;
@@ -1640,8 +1645,8 @@ readfaction(FILE * F)
   planes = ri(F);
   while(--planes >= 0) {
     int id = ri(F);
-    int ux = ri(F);
-    int uy = ri(F);
+    short ux = (short)ri(F);
+    short uy = (short)ri(F);
     set_ursprung(f, id, ux, uy);
   }
   f->newbies = 0;
@@ -1822,20 +1827,21 @@ readgame(const char * filename, int backup)
     plane *pl = calloc(1, sizeof(plane));
     pl->id = ri(F);
     rds(F, &pl->name);
-    pl->minx = ri(F);
-    pl->maxx = ri(F);
-    pl->miny = ri(F);
-    pl->maxy = ri(F);
+    pl->minx = (short)ri(F);
+    pl->maxx = (short)ri(F);
+    pl->miny = (short)ri(F);
+    pl->maxy = (short)ri(F);
     pl->flags = ri(F);
     if (global.data_version>WATCHERS_VERSION) {
       rs(F, buf);
       while (strcmp(buf, "end")!=0) {
         watcher * w = calloc(sizeof(watcher),1);
-        int fno = atoi36(buf);
+        variant fno;
+        fno.i = atoi36(buf);
         w->mode = (unsigned char)ri(F);
         w->next = pl->watchers;
         pl->watchers = w;
-        ur_add((void*)fno, (void**)&w->faction, resolve_faction);
+        ur_add(fno, (void**)&w->faction, resolve_faction);
         rs(F, buf);
       }
     }
@@ -1881,8 +1887,8 @@ readgame(const char * filename, int backup)
   while (--n >= 0) {
     unit **up;
     boolean skip = false;
-    int x = ri(F);
-    int y = ri(F);
+    short x = (short)ri(F);
+    short y = (short)ri(F);
     plane * pl = findplane(x, y);
 
     if (firstx || firsty) {
@@ -2004,7 +2010,6 @@ readgame(const char * filename, int backup)
   /* Unaufgeloeste Zeiger initialisieren */
   printf("\n - Referenzen initialisieren...\n");
   resolve();
-  resolve_IDs();
 
   printf("\n - Leere Gruppen l�schen...\n");
   for (f=factions; f; f=f->next) {
@@ -2018,7 +2023,6 @@ readgame(const char * filename, int backup)
         gp = &g->next;
     }
   }
-  resolve_IDs();
 
   for (r=regions;r;r=r->next) {
     building * b;
diff --git a/src/common/kernel/save.h b/src/common/kernel/save.h
index b37063b5c..a3dd6e6ca 100644
--- a/src/common/kernel/save.h
+++ b/src/common/kernel/save.h
@@ -69,7 +69,7 @@ extern void writeunit(FILE * stream, const struct unit * u);
 extern struct unit * readunit(FILE * stream);
 
 extern void writeregion(FILE * stream, const struct region * r);
-extern struct region * readregion(FILE * stream, int x, int y);
+extern struct region * readregion(FILE * stream, short x, short y);
 
 extern void writefaction(FILE * stream, const struct faction * f);
 extern struct faction * readfaction(FILE * stream);
diff --git a/src/common/kernel/ship.c b/src/common/kernel/ship.c
index 95c762368..4ce512542 100644
--- a/src/common/kernel/ship.c
+++ b/src/common/kernel/ship.c
@@ -42,7 +42,7 @@ const ship_type *
 findshiptype(const char * name, const struct locale * lang)
 {
 	local_names * sn = snames;
-	void * i;
+	variant var;
 
 	while (sn) {
 		if (sn->lang==lang) break;
@@ -54,14 +54,16 @@ findshiptype(const char * name, const struct locale * lang)
 		sn->next = snames;
 		sn->lang = lang;
 		while (stl) {
+      variant var;
 			const char * n = locale_string(lang, stl->type->name[0]);
-			addtoken(&sn->names, n, (void*)stl->type);
-			stl=stl->next;
+      var.v = (void*)stl->type;
+			addtoken(&sn->names, n, var);
+			stl = stl->next;
 		}
 		snames = sn;
 	}
-	if (findtoken(&sn->names, name, &i)==E_TOK_NOMATCH) return NULL;
-	return (const ship_type*)i;
+	if (findtoken(&sn->names, name, &var)==E_TOK_NOMATCH) return NULL;
+	return (const ship_type*)var.v;
 }
 
 const ship_type *
diff --git a/src/common/kernel/skill.c b/src/common/kernel/skill.c
index ee23dc1da..a717126fb 100644
--- a/src/common/kernel/skill.c
+++ b/src/common/kernel/skill.c
@@ -30,7 +30,9 @@
 #include "curse.h"
 #include "region.h"
 #include "karma.h"
-#include "attrib.h"
+
+#include <util/attrib.h>
+#include <util/goodies.h>
 
 /* libc includes */
 #include <assert.h>
@@ -195,7 +197,7 @@ int
 rc_skillmod(const struct race * rc, const region *r, skill_t sk)
 {
 	int mods;
-	unsigned int index = ((unsigned int)rc) % RCMODMAXHASH;
+	unsigned int index = hashstring(rc->_name[0]) % RCMODMAXHASH;
 	struct skillmods **imods = &modhash[index];
 	while (*imods && (*imods)->race!=rc) imods = &(*imods)->next;
 	if (*imods==NULL) {
diff --git a/src/common/kernel/spell.c b/src/common/kernel/spell.c
index fe2062eac..576d04f47 100644
--- a/src/common/kernel/spell.c
+++ b/src/common/kernel/spell.c
@@ -59,6 +59,7 @@
 #include <util/event.h>
 #include <util/language.h>
 #include <util/rand.h>
+#include <util/variant.h>
 
 /* libc includes */
 #include <assert.h>
@@ -83,6 +84,8 @@
 #include <attributes/hate.h>
 /* ----------------------------------------------------------------------- */
 
+static variant zero_effect = { 0 };
+
 attrib_type at_unitdissolve = {
 	"unitdissolve", NULL, NULL, NULL, a_writedefault, a_readdefault
 };
@@ -856,7 +859,7 @@ sp_goodwinds(castorder *co)
 
 	/* keine Probleme mit C_SHIP_SPEEDUP und C_SHIP_FLYING */
 	/* NODRIFT bewirkt auch +1 Geschwindigkeit */
-	create_curse(mage, &sh->attribs, ct_find("nodrift"), power, duration, 0, 0);
+	create_curse(mage, &sh->attribs, ct_find("nodrift"), power, duration, zero_effect, 0);
 
 	/* melden, 1x pro Partei */
 	freset(mage->faction, FL_DH);
@@ -904,7 +907,7 @@ sp_magicstreet(castorder *co)
   }
 
   /* wirkt schon in der Zauberrunde! */
-  create_curse(mage, &r->attribs, ct_find("magicstreet"), co->force, co->level+1, 0, 0);
+  create_curse(mage, &r->attribs, ct_find("magicstreet"), co->force, co->level+1, zero_effect, 0);
 
   /* melden, 1x pro Partei */
   {
@@ -1055,6 +1058,7 @@ sp_maelstrom(castorder *co)
 	int cast_level = co->level;
 	curse * c;
 	double power = co->force;
+  variant effect;
 	int duration = (int)power+1;
 
 	if(rterrain(r) != T_OCEAN) {
@@ -1066,7 +1070,8 @@ sp_maelstrom(castorder *co)
 	/* Attribut auf Region.
 	 * Existiert schon ein curse, so wird dieser verst�rkt
 	 * (Max(Dauer), Max(St�rke))*/
-	c = create_curse(mage, &mage->attribs, ct_find("maelstrom"), power, duration, (int)power, 0);
+  effect.i = (int)power;
+	c = create_curse(mage, &mage->attribs, ct_find("maelstrom"), power, duration, effect, 0);
 	curse_setflag(c, CURSE_ISNEW);
 
 	/* melden, 1x pro Partei */
@@ -1150,11 +1155,13 @@ sp_blessedharvest(castorder *co)
 	int cast_level = co->level;
 	double power = co->force;
 	int duration = (int)power+1;
+  variant effect;
 
 	/* Attribut auf Region.
 	 * Existiert schon ein curse, so wird dieser verst�rkt
 	 * (Max(Dauer), Max(St�rke))*/
-	create_curse(mage,&r->attribs, ct_find("blessedharvest"), power, duration, 1, 0);
+  effect.i = 1;
+	create_curse(mage,&r->attribs, ct_find("blessedharvest"), power, duration, effect, 0);
 	{
 		message * seen = msg_message("harvest_effect", "mage", mage);
 		message * unseen = msg_message("harvest_effect", "mage", NULL);
@@ -1426,7 +1433,7 @@ sp_kaelteschutz(castorder *co)
 	double force = co->force;
 	int duration = max(cast_level, (int)force) + 1;
 	spellparameter *pa = co->par;
-
+  variant effect;
 
 	force*=10;	/* 10 Personen pro Force-Punkt */
 
@@ -1447,8 +1454,9 @@ sp_kaelteschutz(castorder *co)
 			men = u->number;
 		}
 
+    effect.i = 1;
 		create_curse(mage, &u->attribs, ct_find("insectfur"), cast_level,
-				duration, 1, men);
+				duration, effect, men);
 
 		force -= u->number;
 		ADDMSG(&mage->faction->msgs, msg_message(
@@ -1485,6 +1493,7 @@ sp_sparkle(castorder *co)
 	int cast_level = co->level;
 	spellparameter *pa = co->par;
 	int duration = cast_level+1;
+  variant effect;
 
 	/* wenn kein Ziel gefunden, Zauber abbrechen */
 	if(pa->param[0]->flag == TARGET_NOTFOUND) return 0;
@@ -1494,8 +1503,9 @@ sp_sparkle(castorder *co)
 	if(pa->param[0]->flag == TARGET_RESISTS) return cast_level;
 
 	u = pa->param[0]->data.u;
+  effect.i = rand();
 	create_curse(mage, &u->attribs, ct_find("sparkle"), cast_level,
-			duration, rand(), u->number);
+			duration, effect, u->number);
 
 	ADDMSG(&mage->faction->msgs, msg_message(
 		"sparkle_effect", "mage target", mage, u));
@@ -1670,6 +1680,7 @@ sp_great_drought(castorder *co)
 	int cast_level = co->level;
 	double force = co->force;
 	int duration = 2;
+  variant effect;
 
 	if(rterrain(r) == T_OCEAN ) {
 		cmistake(mage, co->order, 189, MSG_MAGIC);
@@ -1689,7 +1700,8 @@ sp_great_drought(castorder *co)
 	rsethorses(r, rhorses(r)/2);
 
 	/* Arbeitslohn = 1/4 */
-	create_curse(mage, &r->attribs, ct_find("drought"), force, duration, 4, 0);
+  effect.i = 4;
+	create_curse(mage, &r->attribs, ct_find("drought"), force, duration, effect, 0);
 
   /* terraforming */
 	if (rand() % 100 < 25){
@@ -2049,7 +2061,7 @@ sp_holyground(castorder *co)
 	msg_release(msg);
 
 	c = create_curse(mage, &r->attribs, ct_find("holyground"),
-		power*power, 1, 0, 0);
+		power*power, 1, zero_effect, 0);
 
 	curse_setflag(c, CURSE_NOAGE);
 
@@ -2080,6 +2092,7 @@ sp_homestone(castorder *co)
 	unit *mage = (unit *)co->magician;
 	int cast_level = co->level;
 	double force = co->force;
+  variant effect;
 
 	if(!mage->building || mage->building->type != bt_find("castle")){
 		cmistake(mage, co->order, 197, MSG_MAGIC);
@@ -2087,7 +2100,7 @@ sp_homestone(castorder *co)
 	}
 
 	c = create_curse(mage, &mage->building->attribs, ct_find("magicwalls"),
-			force*force, 1, 0, 0);
+			force*force, 1, zero_effect, 0);
 
 	if (c==NULL) {
 		cmistake(mage, co->order, 206, MSG_MAGIC);
@@ -2096,8 +2109,9 @@ sp_homestone(castorder *co)
 	curse_setflag(c, CURSE_NOAGE|CURSE_ONLYONE);
 
 	/* Magieresistenz der Burg erh�ht sich um 50% */
+  effect.i = 50;
 	c = create_curse(mage,  &mage->building->attribs,
-		ct_find("magicresistance"), force*force, 1, 50, 0);
+		ct_find("magicresistance"), force*force, 1, effect, 0);
 	curse_setflag(c, CURSE_NOAGE);
 
 	/* melden, 1x pro Partei in der Burg */
@@ -2174,6 +2188,7 @@ sp_drought(castorder *co)
 		c->vigour = max(c->vigour, power);
 		c->duration = max(c->duration, (int)power);
 	} else {
+    variant effect;
 		/* Baeume und Pferde sterben */
 #if GROWING_TREES
 		rsettrees(r, 2, rtrees(r,2)/2);
@@ -2184,7 +2199,8 @@ sp_drought(castorder *co)
 #endif
 		rsethorses(r, rhorses(r)/2);
 
-		create_curse(mage, &r->attribs, ct_find("drought"), power, duration, 4, 0);
+    effect.i = 4;
+		create_curse(mage, &r->attribs, ct_find("drought"), power, duration, effect, 0);
 	}
 	return cast_level;
 }
@@ -2218,11 +2234,13 @@ sp_fog_of_confusion(castorder *co)
 	range = (power-11)/3-1;
 	duration = (int)((power-11)/1.5)+1;
 
-	rl = all_in_range(r, (int)range, NULL);
+	rl = all_in_range(r, (short)range, NULL);
 
 	for(rl2 = rl; rl2; rl2 = rl2->next) {
 		curse * c;
-		if(rterrain(rl2->data) != T_OCEAN
+    variant effect;
+
+    if(rterrain(rl2->data) != T_OCEAN
 				&& !r_isforest(rl2->data)) continue;
 
 		/* Magieresistenz jeder Region pr�fen */
@@ -2231,8 +2249,9 @@ sp_fog_of_confusion(castorder *co)
 			continue;
 		}
 
+    effect.i = cast_level*5;
 		c = create_curse(mage, &rl2->data->attribs,
-			ct_find("disorientationzone"), power, duration, cast_level*5, 0);
+			ct_find("disorientationzone"), power, duration, effect, 0);
 		/* Soll der schon in der Zauberrunde wirken? */
 		curse_setflag(c, CURSE_ISNEW);
 
@@ -2363,7 +2382,7 @@ sp_stormwinds(castorder *co)
 		}
 
 		/* Duration = 1, nur diese Runde */
-		create_curse(mage, &sh->attribs, ct_find("stormwind"), power, 1, 0, 0);
+		create_curse(mage, &sh->attribs, ct_find("stormwind"), power, 1, zero_effect, 0);
 		/* Da der Spruch nur diese Runde wirkt wird er nie im Report
 		 * erscheinen */
 		erfolg++;
@@ -2670,12 +2689,12 @@ sp_fumblecurse(castorder *co)
 	unit *mage = (unit *)co->magician;
 	int cast_level = co->level;
 	double force = co->force;
-  int effect = (int)(force/2);
+  variant effect;
 	curse * c;
 	spellparameter *pa = co->par;
 
 	/* wenn kein Ziel gefunden, Zauber abbrechen */
-	if(pa->param[0]->flag == TARGET_NOTFOUND) return 0;
+	if (pa->param[0]->flag == TARGET_NOTFOUND) return 0;
 
 	target = pa->param[0]->data.u;
 
@@ -2683,8 +2702,9 @@ sp_fumblecurse(castorder *co)
 	sx = cast_level - effskill(target, SK_MAGIC);
 	duration = max(sx, rx) + 1;
 
+  effect.i = (int)(force/2);
 	c = create_curse(mage, &target->attribs, ct_find("fumble"),
-				force, duration, effect, 0);
+    force, duration, effect, 0);
 	if (c == NULL) {
 		report_failure(mage, co->order);
 		return 0;
@@ -2703,10 +2723,11 @@ patzer_fumblecurse(castorder *co)
 	unit *mage = (unit *)co->magician;
 	int cast_level = co->level;
 	double force = co->force;
-	int effect = (int)(force/2);
-	curse * c;
 	int duration = (cast_level/2)+1;
+  variant effect;
+  curse * c;
 
+  effect.i = (int)(force/2);
 	c = create_curse(mage, &mage->attribs, ct_find("fumble"), force,
 				duration, effect, 0);
 	if (c!=NULL) {
@@ -2784,7 +2805,7 @@ sp_summondragon(castorder *co)
 		}
 	}
 
-	rl = all_in_range(r, (int)power, NULL);
+	rl = all_in_range(r, (short)power, NULL);
 
 	for(rl2 = rl; rl2; rl2 = rl2->next) {
 		for(u = rl2->data->units; u; u = u->next) {
@@ -2833,13 +2854,13 @@ typedef struct wallcurse {
 void
 wall_vigour(curse* c, double delta)
 {
-	wallcurse * wc = (wallcurse*)c->data;
+	wallcurse * wc = (wallcurse*)c->data.v;
 	assert(wc->buddy->vigour==c->vigour);
 	wc->buddy->vigour += delta;
 	if (wc->buddy->vigour<=0) {
 		erase_border(wc->wall);
 		wc->wall = NULL;
-		((wallcurse*)wc->buddy->data)->wall = NULL;
+		((wallcurse*)wc->buddy->data.v)->wall = NULL;
 	}
 }
 
@@ -2856,12 +2877,12 @@ cw_init(attrib * a) {
 	curse * c;
 	curse_init(a);
 	c = (curse*)a->data.v;
-	c->data = calloc(sizeof(wallcurse), 1);
+	c->data.v = calloc(sizeof(wallcurse), 1);
 }
 
 void
 cw_write(const attrib * a, FILE * f) {
-	border * b = ((wallcurse*)((curse*)a->data.v)->data)->wall;
+	border * b = ((wallcurse*)((curse*)a->data.v)->data.v)->wall;
 	curse_write(a, f);
 	fprintf(f, "%d ", b->id);
 }
@@ -2871,15 +2892,15 @@ typedef struct bresvole {
 	curse * self;
 } bresolve;
 
-void *
-resolve_buddy(void * data) {
-	bresolve * br = (bresolve*)data;
+static void *
+resolve_buddy(variant data) {
+	bresolve * br = (bresolve*)data.v;
 	border * b = find_border(br->id);
 	if (b && b->from && b->to) {
 		attrib * a = a_find(b->from->attribs, &at_cursewall);
 		while (a && a->data.v!=br->self) {
 			curse * c = (curse*)a->data.v;
-			wallcurse * wc = (wallcurse*)c->data;
+			wallcurse * wc = (wallcurse*)c->data.v;
 			if (wc->wall->id==br->id) break;
 			a = a->nexttype;
 		}
@@ -2887,7 +2908,7 @@ resolve_buddy(void * data) {
 			a = a_find(b->to->attribs, &at_cursewall);
 			while (a && a->data.v!=br->self) {
 				curse * c = (curse*)a->data.v;
-				wallcurse * wc = (wallcurse*)c->data;
+				wallcurse * wc = (wallcurse*)c->data.v;
 				if (wc->wall->id==br->id) break;
 				a = a->nexttype;
 			}
@@ -2906,13 +2927,18 @@ cw_read(attrib * a, FILE * f)
 {
 	bresolve * br = calloc(sizeof(bresolve), 1);
 	curse * c = (curse*)a->data.v;
-	wallcurse * wc = (wallcurse*)c->data;
+	wallcurse * wc = (wallcurse*)c->data.v;
+  variant var;
 
 	curse_read(a, f);
 	br->self = c;
 	fscanf(f, "%u ", &br->id);
-	ur_add((void *)br->id, (void**)&wc->wall, resolve_borderid);
-	ur_add((void *)br, (void**)&wc->buddy, resolve_buddy);
+
+  var.i = br->id;
+	ur_add(var, (void**)&wc->wall, resolve_borderid);
+
+  var.v = br;
+  ur_add(var, (void**)&wc->buddy, resolve_buddy);
 	return AT_READ_OK;
 }
 
@@ -2942,39 +2968,40 @@ fire_name(const border * b, const region * r, const faction * f, int gflags)
 static void
 wall_init(border * b)
 {
-	b->data = calloc(sizeof(wall_data), 1);
+	b->data.v = calloc(sizeof(wall_data), 1);
 }
 
 static void
 wall_destroy(border * b)
 {
-	free(b->data);
+	free(b->data.v);
 }
 
 static void
 wall_read(border * b, FILE * f)
 {
-	wall_data * fd = (wall_data*)b->data;
-	int mno;
+	wall_data * fd = (wall_data*)b->data.v;
+	variant mno;
 	assert(fd);
-	fscanf(f, "%d %d ", &mno, &fd->force);
-	fd->mage = findunitg(mno, NULL);
+	fscanf(f, "%d %d ", &mno.i, &fd->force);
+	fd->mage = findunitg(mno.i, NULL);
 	fd->active = true;
-	if (!fd->mage)
-		ur_add((void*)mno, (void**)&fd->mage, resolve_unit);
+  if (!fd->mage) {
+    ur_add(mno, (void**)&fd->mage, resolve_unit);
+	}
 }
 
 static void
 wall_write(const border * b, FILE * f)
 {
-	wall_data * fd = (wall_data*)b->data;
+	wall_data * fd = (wall_data*)b->data.v;
 	fprintf(f, "%d %d ", fd->mage?fd->mage->no:0, fd->force);
 }
 
 static region *
 wall_move(const border * b, struct unit * u, struct region * from, struct region * to, boolean routing)
 {
-  wall_data * fd = (wall_data*)b->data;
+  wall_data * fd = (wall_data*)b->data.v;
   if (routing) return to;
   if (fd->active) {
     int hp = dice(3, fd->force) * u->number;
@@ -2994,7 +3021,7 @@ wall_move(const border * b, struct unit * u, struct region * from, struct region
 }
 
 border_type bt_firewall = {
-  "firewall",
+  "firewall", VAR_VOIDPTR,
   b_transparent, /* transparent */
   wall_init, /* init */
   wall_destroy, /* destroy */
@@ -3043,12 +3070,12 @@ sp_firewall(castorder *co)
   }
   if (b==NULL) {
     b = new_border(&bt_firewall, r, r2);
-    fd = (wall_data*)b->data;
+    fd = (wall_data*)b->data.v;
     fd->force = (int)(force/2+0.5);
     fd->mage = mage;
     fd->active = false;
   } else {
-    fd = (wall_data*)b->data;
+    fd = (wall_data*)b->data.v;
     fd->force = (int)max(fd->force, force/2+0.5);
   }
 
@@ -3090,7 +3117,7 @@ static region *
 wisps_move(const border * b, struct unit * u, struct region * from, struct region * next, boolean routing)
 {
   direction_t reldir = reldirection(from, next);
-  wall_data * wd = (wall_data*)b->data;
+  wall_data * wd = (wall_data*)b->data.v;
   assert(reldir!=D_SPECIAL);
 
   if (!routing) return NULL;
@@ -3106,7 +3133,7 @@ wisps_move(const border * b, struct unit * u, struct region * from, struct regio
 }
 
 border_type bt_wisps = {
-	"wisps",
+	"wisps", VAR_VOIDPTR,
 	b_transparent, /* transparent */
 	wall_init, /* init */
 	wall_destroy, /* destroy */
@@ -3143,7 +3170,7 @@ sp_wisps(castorder *co)
 	}
 
 	b = new_border(&bt_wisps, r, r2);
-	fd = (wall_data*)b->data;
+	fd = (wall_data*)b->data.v;
 	fd->force = (int)(force/2+0.5);
 	fd->mage = mage;
 	fd->active = false;
@@ -3655,6 +3682,8 @@ sp_magicboost(castorder *co)
 	unit *mage = (unit *)co->magician;
 	int cast_level = co->level;
 	double power = co->force;
+  variant effect;
+  trigger * tsummon;
 
 	/* fehler, wenn schon ein boost */
 	if(is_cursed(mage->attribs, C_MBOOST, 0) == true){
@@ -3662,21 +3691,19 @@ sp_magicboost(castorder *co)
 		return 0;
 	}
 
-	c = create_curse(mage, &mage->attribs, ct_find("magicboost"), power, 10, 6, 1);
+  effect.i = 6;
+	c = create_curse(mage, &mage->attribs, ct_find("magicboost"), power, 10, effect, 1);
 	/* kann nicht durch Antimagie beeinflusst werden */
 	curse_setflag(c, CURSE_IMMUNE);
 
-	c = create_curse(mage, &mage->attribs, ct_find("aura"), power, 4, 200, 1);
+  effect.i = 200;
+	c = create_curse(mage, &mage->attribs, ct_find("aura"), power, 4, effect, 1);
 
-	{
-		trigger * tsummon = trigger_createcurse(mage, mage, c->type, power, 6, 50, 1);
-		add_trigger(&mage->attribs, "timer", trigger_timeout(5, tsummon));
-	}
+	tsummon = trigger_createcurse(mage, mage, c->type, power, 6, 50, 1);
+  add_trigger(&mage->attribs, "timer", trigger_timeout(5, tsummon));
 
-
-	ADDMSG(&mage->faction->msgs, msg_message(
-		"magicboost_effect", "unit region command",
-		mage, mage->region, co->order));
+	ADDMSG(&mage->faction->msgs, msg_message("magicboost_effect", 
+    "unit region command", mage, mage->region, co->order));
 
 	return cast_level;
 }
@@ -4087,7 +4114,7 @@ sp_charmingsong(castorder *co)
 		add_trigger(&mage->faction->attribs, "destroy", trigger_killunit(target));
 	}
 	/* sperre ATTACKIERE, GIB PERSON und �berspringe Migranten */
-	create_curse(mage, &target->attribs, ct_find("slavery"), force, duration, 0, 0);
+	create_curse(mage, &target->attribs, ct_find("slavery"), force, duration, zero_effect, 0);
 
 	/* setze Partei um und l�sche langen Befehl aus Sicherheitsgr�nden */
 	u_setfaction(target,mage->faction);
@@ -4120,13 +4147,14 @@ sp_charmingsong(castorder *co)
 static int
 sp_song_resistmagic(castorder *co)
 {
-	int mr_bonus = 15;
+	variant mr_bonus;
 	region *r = co->rt;
 	unit *mage = (unit *)co->magician;
 	int cast_level = co->level;
 	double force = co->force;
 	int duration = (int)force+1;
 
+  mr_bonus.i = 15;
 	create_curse(mage, &r->attribs, ct_find("goodmagicresistancezone"),
 			force, duration, mr_bonus, 0);
 
@@ -4151,13 +4179,14 @@ sp_song_resistmagic(castorder *co)
 static int
 sp_song_susceptmagic(castorder *co)
 {
-	int mr_malus = 15;
+  variant mr_malus;
 	region *r = co->rt;
 	unit *mage = (unit *)co->magician;
 	int cast_level = co->level;
 	double force = co->force;
 	int duration = (int)force+1;
 
+  mr_malus.i = 15;
 	create_curse(mage, &r->attribs, ct_find("badmagicresistancezone"),
 			force, duration, mr_malus, 0);
 
@@ -4251,16 +4280,16 @@ sp_raisepeasantmob(castorder *co)
 	unit *u;
 	attrib *a;
 	int n;
-	int anteil = 6;
+	variant anteil;
 	region *r = co->rt;
 	unit *mage = (unit *)co->magician;
 	int cast_level = co->level;
 	double force = co->force;
 	int duration = (int)force+1;
 
-	anteil += rand()%4;
+  anteil.i = 6 + (rand()%4);
 
-	n = rpeasants(r) * anteil / 10;
+	n = rpeasants(r) * anteil.i / 10;
 	n = max(0, n);
 	n = min(n, rpeasants(r));
 
@@ -4424,15 +4453,13 @@ static int
 sp_song_of_peace(castorder *co)
 {
 	unit *u;
-	int duration;
 	region *r = co->rt;
 	unit *mage = (unit *)co->magician;
 	int cast_level = co->level;
 	double force = co->force;
-
-	duration = 2 + lovar(force/2);
-
-	create_curse(mage,&r->attribs, ct_find("peacezone"), force, duration, 1,0);
+	int duration = 2 + lovar(force/2);
+	
+	create_curse(mage,&r->attribs, ct_find("peacezone"), force, duration, zero_effect, 0);
 
 	for (u = r->units; u; u = u->next) freset(u->faction, FL_DH);
 	for (u = r->units; u; u = u->next ) {
@@ -4472,6 +4499,7 @@ sp_generous(castorder *co)
 	int cast_level = co->level;
 	double force = co->force;
 	int duration = (int)force+1;
+  variant effect;
 
 	if(is_cursed(r->attribs, C_DEPRESSION, 0)){
 		sprintf(buf, "%s in %s: Die Stimmung in %s ist so schlecht, das "
@@ -4480,7 +4508,9 @@ sp_generous(castorder *co)
 		addmessage(0, mage->faction, buf, MSG_MAGIC, ML_MISTAKE);
 		return 0;
 	}
-	create_curse(mage,&r->attribs, ct_find("generous"), force,duration,2,0);
+
+  effect.i = 2;
+	create_curse(mage,&r->attribs, ct_find("generous"), force, duration, effect, 0);
 
 	for (u = r->units; u; u = u->next) freset(u->faction, FL_DH);
 	for (u = r->units; u; u = u->next ) {
@@ -4802,6 +4832,7 @@ sp_calm_monster(castorder *co)
 	int cast_level = co->level;
 	double force = co->force;
 	spell *sp = co->sp;
+  variant effect;
 
 	/* wenn kein Ziel gefunden, Zauber abbrechen */
 	if(pa->param[0]->flag == TARGET_NOTFOUND) return 0;
@@ -4815,8 +4846,9 @@ sp_calm_monster(castorder *co)
 		return 0;
 	}
 
+  effect.i = mage->faction->subscription;
 	c = create_curse(mage, &target->attribs, ct_find("calmmonster"), force,
-    (int)force, (int)mage->faction, 0);
+    (int)force, effect, 0);
 	if (c==NULL) {
 		report_failure(mage, co->order);
 		return 0;
@@ -4965,7 +4997,7 @@ sp_depression(castorder *co)
 	double force = co->force;
 	int duration = (int)force+1;
 
-	create_curse(mage,&r->attribs, ct_find("depression"), force, duration, 0, 0);
+  create_curse(mage,&r->attribs, ct_find("depression"), force, duration, zero_effect, 0);
 
 	for (u = r->units; u; u = u->next) freset(u->faction, FL_DH);
 	for (u = r->units; u; u = u->next ) {
@@ -5347,6 +5379,7 @@ sp_baddreams(castorder *co)
 	double power = co->force;
 	region *r = co->rt;
 	curse * c;
+  variant effect;
 
 	/* wirkt erst in der Folgerunde, soll mindestens eine Runde wirken,
 	 * also duration+2 */
@@ -5354,7 +5387,8 @@ sp_baddreams(castorder *co)
 	duration = 2 + rand()%duration;
 
 	/* Nichts machen als ein entsprechendes Attribut in die Region legen. */
-	c = create_curse(mage, &r->attribs, ct_find("gbdream"), power, duration, -1, 0);
+  effect.i = -1;
+	c = create_curse(mage, &r->attribs, ct_find("gbdream"), power, duration, effect, 0);
 	curse_setflag(c, CURSE_ISNEW);
 
 	/* Erfolg melden*/
@@ -5386,12 +5420,14 @@ sp_gooddreams(castorder *co)
 	unit *mage = (unit *)co->magician;
 	int cast_level = co->level;
 	double power = co->force;
+  variant effect;
 
 	/* wirkt erst in der Folgerunde, soll mindestens eine Runde wirken,
 	 * also duration+2 */
 	duration = (int)max(1, power/2); /* Stufe 1 macht sonst mist */
 	duration = 2 + rand()%duration;
-	c = create_curse(mage, &r->attribs, ct_find("gbdream"), power, duration, 1, 0);
+  effect.i = 1;
+	c = create_curse(mage, &r->attribs, ct_find("gbdream"), power, duration, effect, 0);
 	curse_setflag(c, CURSE_ISNEW);
 
 	/* Erfolg melden*/
@@ -5506,6 +5542,7 @@ sp_sweetdreams(castorder *co)
 	for (n = 0; n < pa->length; n++) {
 		curse * c;
 		unit *u;
+    variant effect;
 		/* sollte nie negativ werden */
 		if (opfer < 1) break;
 
@@ -5520,7 +5557,8 @@ sp_sweetdreams(castorder *co)
 		opfer -= men;
 
 		/* Nichts machen als ein entsprechendes Attribut an die Einheit legen. */
-		c = create_curse(mage,&u->attribs, ct_find("orcish"), power,duration,5,men);
+    effect.i = 5;
+		c = create_curse(mage,&u->attribs, ct_find("orcish"), power, duration, effect, men);
 		curse_setflag(c, CURSE_ISNEW);
 
 		sprintf(buf, "%s verschafft %s ein interessanteres Nachtleben.",
@@ -5551,7 +5589,11 @@ sp_disturbingdreams(castorder *co)
 	int cast_level = co->level;
 	double power = co->force;
 	int duration = 1 + (int)(power/6);
-	curse * c = create_curse(mage, &r->attribs, ct_find("badlearn"), power, duration, 10, 0);
+  variant effect;
+	curse * c;
+  
+  effect.i = 10;
+  c = create_curse(mage, &r->attribs, ct_find("badlearn"), power, duration, effect, 0);
 	curse_setflag(c, CURSE_ISNEW);
 
 	sprintf(buf, "%s sorgt f�r schlechten Schlaf in %s.",
@@ -5573,10 +5615,11 @@ sp_dream_of_confusion(castorder *co)
 	double range = (power-14)/2-1;
 	int duration = (int)(power-14)+1;
 
-	rl = all_in_range(r, (int)range, NULL);
+	rl = all_in_range(r, (short)range, NULL);
 
 	for(rl2 = rl; rl2; rl2 = rl2->next) {
     region * r2 = rl2->data;
+    variant effect;
 		curse * c;
 		/* Magieresistenz jeder Region pr�fen */
 		if (target_resists_magic(mage, r2, TYP_REGION, 0)){
@@ -5584,8 +5627,9 @@ sp_dream_of_confusion(castorder *co)
 			continue;
 		}
 
+    effect.i = cast_level*5;
 		c = create_curse(mage, &r2->attribs,
-			ct_find("disorientationzone"), power, duration, cast_level*5, 0);
+			ct_find("disorientationzone"), power, duration, effect, 0);
 		/* soll der Zauber schon in der Zauberrunde wirken? */
 		curse_setflag(c, CURSE_ISNEW);
 
@@ -5693,7 +5737,7 @@ sp_itemcloak(castorder *co)
 	/* Zieleinheit */
 	target = pa->param[0]->data.u;
 
-	create_curse(mage,&target->attribs, ct_find("itemcloak"), power,duration,0,0);
+	create_curse(mage,&target->attribs, ct_find("itemcloak"), power, duration, zero_effect, 0);
 	ADDMSG(&mage->faction->msgs, msg_message(
 		"itemcloak", "mage target", mage, target));
 
@@ -5720,7 +5764,7 @@ sp_resist_magic_bonus(castorder *co)
 {
 	unit *u;
 	int n, m, opfer;
-	int resistbonus = 20;
+	variant resistbonus;
 	int duration = 6;
 	unit *mage = (unit *)co->magician;
 	int cast_level = co->level;
@@ -5751,6 +5795,7 @@ sp_resist_magic_bonus(castorder *co)
 		m = min(u->number,opfer);
 		opfer -= m;
 
+    resistbonus.i = 20;
 		create_curse(mage, &u->attribs, ct_find("magicresistance"),
 			power, duration, resistbonus, m);
 
@@ -6404,10 +6449,11 @@ sp_disruptastral(castorder *co)
 		return 0;
 	}
 
-	rl = all_in_range(rt, (int)(power/5), NULL);
+	rl = all_in_range(rt, (short)(power/5), NULL);
 
 	for (rl2=rl; rl2!=NULL; rl2=rl2->next) {
 		attrib *a, *a2;
+    variant effect;
     region * r2 = rl2->data;
 		spec_direction *sd;
     int inhab_regions = 0;
@@ -6457,8 +6503,9 @@ sp_disruptastral(castorder *co)
     }
 
 		/* Kontakt unterbinden */
+    effect.i = 100;
 		create_curse(mage, &rl2->data->attribs, ct_find("astralblock"),
-			power, duration, 100, 0);
+			power, duration, effect, 0);
 		addmessage(r2, 0, "M�chtige Magie verhindert den Kontakt zur Realit�t.",
 				MSG_COMMENT, ML_IMPORTANT);
 	}
@@ -6515,7 +6562,7 @@ sp_eternizewall(castorder *co)
 
 	b = pa->param[0]->data.b;
 	c = create_curse(mage, &b->attribs, ct_find("nocost"),
-		power*power, 1, 0, 0);
+		power*power, 1, zero_effect, 0);
 
 	if(c==NULL) {	/* ist bereits verzaubert */
 		cmistake(mage, co->order, 206, MSG_MAGIC);
@@ -6734,7 +6781,7 @@ sp_flying_ship(castorder *co)
 	/* mit C_SHIP_NODRIFT haben wir kein Problem */
 
 	/* Duration = 1, nur diese Runde */
-	create_curse(mage, &sh->attribs, ct_find("flyingship"), power, 1, 0, 0);
+	create_curse(mage, &sh->attribs, ct_find("flyingship"), power, 1, zero_effect, 0);
 	/* Da der Spruch nur diese Runde wirkt, brauchen wir kein
 	 * set_cursedisplay() zu benutzten - es sieht eh niemand...
 	 */
@@ -6862,7 +6909,7 @@ int
 sp_antimagiczone(castorder *co)
 {
 	double power;
-	int effect;
+	variant effect;
 	region *r = co->rt;
 	unit *mage = (unit *)co->magician;
 	int cast_level = co->level;
@@ -6875,7 +6922,7 @@ sp_antimagiczone(castorder *co)
 	power = force * 10;
 
 	/* Reduziert die St�rke jedes Spruchs um effect */
-	effect = cast_level;
+	effect.i = cast_level;
 
 	create_curse(mage, &r->attribs, ct_find("antimagiczone"), power, duration,
 			effect, 0);
@@ -6927,8 +6974,10 @@ sp_magicrunes(castorder *co)
 	int cast_level = co->level;
 	double force = co->force;
 	spellparameter *pa = co->par;
+  variant effect;
 
 	duration = 3 + rand()%cast_level;
+  effect.i = 20;
 
 	switch(pa->param[0]->typ){
 		case SPP_BUILDING:
@@ -6938,7 +6987,7 @@ sp_magicrunes(castorder *co)
 
 			/* Magieresistenz der Burg erh�ht sich um 20% */
 			create_curse(mage, &b->attribs, ct_find("magicrunes"), force,
-					duration, 20, 0);
+					duration, effect, 0);
 
 			/* Erfolg melden */
 			ADDMSG(&mage->faction->msgs, msg_message(
@@ -6952,7 +7001,7 @@ sp_magicrunes(castorder *co)
 			sh = pa->param[0]->data.sh;
 			/* Magieresistenz des Schiffs erh�ht sich um 20% */
 			create_curse(mage, &sh->attribs, ct_find("magicrunes"), force,
-					duration, 20, 0);
+					duration, effect, 0);
 
 			/* Erfolg melden */
 			ADDMSG(&mage->faction->msgs, msg_message(
@@ -6991,6 +7040,7 @@ sp_speed2(castorder *co)
 	dur = max(1, cast_level/2);
 
 	for (n = 0; n < pa->length; n++) {
+    variant effect;
 		/* sollte nie negativ werden */
 		if (maxmen < 1)
 			break;
@@ -7002,7 +7052,8 @@ sp_speed2(castorder *co)
 		u = pa->param[n]->data.u;
 
 		men = min(maxmen,u->number);
-		create_curse(mage, &u->attribs, ct_find("speed"), force, dur, 2, men);
+    effect.i = 2;
+		create_curse(mage, &u->attribs, ct_find("speed"), force, dur, effect, men);
 		maxmen -= men;
 		used += men;
 	}
@@ -7643,9 +7694,11 @@ init_spellnames(const struct locale * lang, magic_t mtype)
   for (slist=spells;slist!=NULL;slist=slist->next) {
     spell * sp = slist->data;
     const char * n = sp->sname;
+    variant token;
     if (sp->magietyp!=mtype) continue;
     if (sp->info==NULL) n = locale_string(lang, mkname("spell", n));
-    addtoken(&sn->names, n, (void*)sp);
+    token.v = sp;
+    addtoken(&sn->names, n, token);
   }
   return spellnames = sn;
 }
@@ -7665,20 +7718,20 @@ get_spellnames(const struct locale * lang, magic_t mtype)
 static spell *
 find_spellbyname_i(const char *name, const struct locale * lang, magic_t mtype)
 {
-  spell * sp = NULL;
+  variant token = { 0 };
   spell_names * sn;
 
   sn = get_spellnames(lang, mtype);
-  if (findtoken(&sn->names, name, (void**)&sp)==E_TOK_NOMATCH) {
+  if (findtoken(&sn->names, name, &token)==E_TOK_NOMATCH) {
     magic_t mt;
     /* if we could not find it in the main magic type, we look through all the others */
     for (mt=0;mt!=MAXMAGIETYP;++mt) {
       sn = get_spellnames(lang, mt);
-      if (findtoken(&sn->names, name, (void**)&sp)!=E_TOK_NOMATCH) break;
+      if (findtoken(&sn->names, name, &token)!=E_TOK_NOMATCH) break;
     }
   }
 
-  if (sp!=NULL) return sp;
+  if (token.v!=NULL) return (spell*)token.v;
   if (lang==default_locale) return NULL;
   return find_spellbyname_i(name, default_locale, mtype);
 }
@@ -10560,7 +10613,7 @@ chaosgate_move(const border * b, struct unit * u, struct region * from, struct r
 }
 
 border_type bt_chaosgate = {
-  "chaosgate",
+  "chaosgate", VAR_NONE,
   b_transparent, /* transparent */
   NULL, /* init */
   NULL, /* destroy */
diff --git a/src/common/kernel/teleport.c b/src/common/kernel/teleport.c
index ed880ace0..cf9856386 100644
--- a/src/common/kernel/teleport.c
+++ b/src/common/kernel/teleport.c
@@ -43,8 +43,8 @@
 #define TP_RADIUS 2
 #define TP_DISTANCE 4
 
-static int
-real2tp(int rk) {
+static short
+real2tp(short rk) {
   /* in C:
   * -4 / 5 = 0;
   * +4 / 5 = 0;
@@ -64,7 +64,7 @@ region_list *
 astralregions(const region * r, boolean (*valid)(const region *))
 {
   region_list * rlist = NULL;
-  int x, y;
+  short x, y;
 
   assert(rplane(r) == get_astralplane());
   if (rplane(r) != get_astralplane()) {
@@ -103,7 +103,7 @@ r_standard_to_astral(const region *r)
 region *
 r_astral_to_standard(const region *r)
 {
-  int x, y;
+  short x, y;
   region *r2;
 
   assert(rplane(r) == get_astralplane());
@@ -117,9 +117,9 @@ r_astral_to_standard(const region *r)
 }
 
 region_list *
-all_in_range(const region *r, int n, boolean (*valid)(const region *))
+all_in_range(const region *r, short n, boolean (*valid)(const region *))
 {
-  int x,y;
+  short x, y;
   region_list *rlist = NULL;
 
   if (r == NULL) return NULL;
@@ -127,7 +127,7 @@ all_in_range(const region *r, int n, boolean (*valid)(const region *))
   for (x = r->x-n; x <= r->x+n; x++) {
     for (y = r->y-n; y <= r->y+n; y++) {
       if (koor_distance(r->x, r->y, x, y) <= n) {
-        region * r2 = findregion(x,y);
+        region * r2 = findregion(x, y);
         if (r2!=NULL && (valid==NULL || valid(r2))) add_regionlist(&rlist, r2);
       }
     }
@@ -199,8 +199,8 @@ create_teleport_plane(void)
   for (r=regions;r;r=r->next) if (r->planep == NULL) {
     region *ra = tpregion(r);
     if (ra==NULL) {
-      int x = TE_CENTER_X+real2tp(r->x);
-      int y = TE_CENTER_Y+real2tp(r->y);
+      short x = TE_CENTER_X+real2tp(r->x);
+      short y = TE_CENTER_Y+real2tp(r->y);
       plane * pl = findplane(x, y);
 
       if (pl==aplane) {
diff --git a/src/common/kernel/teleport.h b/src/common/kernel/teleport.h
index 8b8db74a4..f729174f0 100644
--- a/src/common/kernel/teleport.h
+++ b/src/common/kernel/teleport.h
@@ -21,7 +21,7 @@ extern "C" {
   struct region *r_standard_to_astral(const struct region *r);
   struct region *r_astral_to_standard(const struct region *);
   extern struct region_list *astralregions(const struct region * rastral, boolean (*valid)(const struct region *));
-  extern struct region_list *all_in_range(const struct region *r, int n, boolean (*valid)(const struct region *));
+  extern struct region_list *all_in_range(const struct region *r, short n, boolean (*valid)(const struct region *));
   extern boolean inhabitable(const struct region * r);
   extern struct plane * get_astralplane(void);
   extern struct plane * get_normalplane(void);
diff --git a/src/common/kernel/unit.c b/src/common/kernel/unit.c
index 65a40fdbd..4465ad856 100644
--- a/src/common/kernel/unit.c
+++ b/src/common/kernel/unit.c
@@ -44,6 +44,7 @@
 #include <event.h>
 #include <goodies.h>
 #include <resolve.h>
+#include <variant.h>
 
 /* libc includes */
 #include <assert.h>
@@ -436,13 +437,6 @@ ucontact(const unit * u, const unit * u2)
 	return false;
 }
 
-void *
-resolve_unit(void * id)
-{
-   return ufindhash((int)id);
-}
-
-
 /***
  ** init & cleanup module
  **/
@@ -464,21 +458,27 @@ write_unit_reference(const unit * u, FILE * F)
 	fprintf(F, "%s ", (u!=NULL && u->no!=0)?itoa36(u->no):"0");
 }
 
+void *
+resolve_unit(variant id)
+{
+  return ufindhash(id.i);
+}
+
 int
 read_unit_reference(unit ** up, FILE * F)
 {
   char zId[10];
-  int i;
+  variant var;
 
   assert(up!=NULL);
   fscanf(F, "%s", zId);
-  i = atoi36(zId);
-  if (i==0) {
-	*up = NULL;
-	return AT_READ_FAIL;
+  var.i = atoi36(zId);
+  if (var.i==0) {
+    *up = NULL;
+    return AT_READ_FAIL;
   }
-  *up = findunit(i);
-  if (*up==NULL) ur_add((void*)i, (void**)up, resolve_unit);
+  *up = findunit(var.i);
+  if (*up==NULL) ur_add(var, (void**)up, resolve_unit);
   return AT_READ_OK;
 }
 
@@ -995,7 +995,10 @@ att_modification(const unit *u, skill_t sk)
 
 	result += get_curseeffect(u->attribs, C_ALLSKILLS, 0);
 	if (skillmod_ct) {
-		curse * c = get_cursex(u->attribs, skillmod_ct, (void*)(int)sk, cmp_cursedata);
+    curse * c;
+    variant var;
+    var.i = sk;
+		c = get_cursex(u->attribs, skillmod_ct, var, cmp_cursedata_int);
 		result += curse_geteffect(c);
 	}
 
diff --git a/src/common/kernel/unit.h b/src/common/kernel/unit.h
index 0183044ae..834b931ae 100644
--- a/src/common/kernel/unit.h
+++ b/src/common/kernel/unit.h
@@ -21,6 +21,9 @@
 
 #ifndef H_KRNL_UNIT_H
 #define H_KRNL_UNIT_H
+
+#include <util/variant.h>
+
 #ifdef __cplusplus
 extern "C" {
 #endif
@@ -185,7 +188,7 @@ extern int get_modifier(const struct unit * u, skill_t sk, int lvl, const struct
 extern void destroy_unit(struct unit * u);
 
 /* see resolve.h */
-extern void * resolve_unit(void * data);
+extern void * resolve_unit(variant data);
 extern void write_unit_reference(const struct unit * u, FILE * F);
 extern int read_unit_reference(unit ** up, FILE * F);
 
diff --git a/src/common/modules/arena.c b/src/common/modules/arena.c
index 90a553117..5f168adcc 100644
--- a/src/common/modules/arena.c
+++ b/src/common/modules/arena.c
@@ -386,9 +386,9 @@ guardian_faction(plane * pl, int id)
 }
 
 static void 
-block_create(int x1, int y1, char terrain)
+block_create(short x1, short y1, char terrain)
 {
-	int x, y;
+	short x, y;
 	for (x=0;x!=BLOCKSIZE;++x) {
 		for (y=0;y!=BLOCKSIZE;++y) {
 			region * r = new_region(x1 + x, y1 + y);
@@ -448,12 +448,12 @@ static int
 caldera_read(trigger * t, FILE * F)
 {
 	char zText[128];
-	int i;
+	variant var;
 
 	fscanf(F, "%s", zText);
-	i = atoi36(zText);
-	t->data.v = findbuilding(i);
-	if (t->data.v==NULL) ur_add((void*)i, &t->data.v, resolve_building);
+	var.i = atoi36(zText);
+	t->data.v = findbuilding(var.i);
+	if (t->data.v==NULL) ur_add(var, &t->data.v, resolve_building);
 
 	return AT_READ_OK;
 }
@@ -495,7 +495,7 @@ init_volcano(void)
 void
 create_arena(void)
 {
-	int x;
+	short x;
 	arena_id = hashstring("arena");
 	arena = getplanebyid(arena_id);
 	if (arena!=NULL) return;
@@ -508,7 +508,7 @@ create_arena(void)
 		block_create(arena->minx, arena->miny, T_OCEAN);
 		arena_center = findregion(plane_center_x(arena), plane_center_y(arena));
 		for (x=0;x!=BLOCKSIZE;++x) {
-			int y;
+			short y;
 			for (y=0;y!=BLOCKSIZE;++y) {
 				region * r = findregion(arena->minx+x, arena->miny+y);
 				freset(r, RF_ENCOUNTER);
diff --git a/src/common/modules/autoseed.c b/src/common/modules/autoseed.c
index 92f756fb5..ed0a87b2f 100644
--- a/src/common/modules/autoseed.c
+++ b/src/common/modules/autoseed.c
@@ -414,7 +414,7 @@ get_island(region * root, region_list ** rlist)
 int
 autoseed(newfaction ** players, int nsize)
 {
-	int x = 0, y = 0;
+	short x = 0, y = 0;
 	region * r = NULL;
 	region_list * rlist = NULL;
 	int rsize, tsize = 0;
@@ -626,7 +626,7 @@ autoseed(newfaction ** players, int nsize)
       direction_t d;
       rbegin=&(*rbegin)->next;
       for (d=0;d!=MAXDIRECTIONS;++d) if (rconnect(r, d)==NULL) {
-        int i;
+        short i;
         for (i=1;i!=MAXFILLDIST;++i) {
           if (findregion(r->x + i*delta_x[d], r->y + i*delta_y[d]))
             break;
diff --git a/src/common/modules/gmcmd.c b/src/common/modules/gmcmd.c
index d49018961..fa3e1d76d 100644
--- a/src/common/modules/gmcmd.c
+++ b/src/common/modules/gmcmd.c
@@ -176,8 +176,8 @@ gm_gate(const tnode * tnext, const char * str, void * data, struct order * ord)
   unit * u = (unit*)data;
   const struct plane * p = rplane(u->region);
   int id = atoi36(igetstrtoken(str));
-	int x = rel_to_abs(p, u->faction, atoi(getstrtoken()), 0);
-	int y = rel_to_abs(p, u->faction, atoi(getstrtoken()), 1);
+	short x = rel_to_abs(p, u->faction, (short)atoi(getstrtoken()), 0);
+	short y = rel_to_abs(p, u->faction, (short)atoi(getstrtoken()), 1);
 	region * r = findregion(x, y);
 	building * b = findbuilding(id);
 	if (b==NULL || r==NULL || p!=rplane(b->region) || p!=rplane(r)) {
@@ -208,8 +208,8 @@ gm_terraform(const tnode * tnext, const char * str, void * data, struct order *
 {
   unit * u = (unit*)data;
 	const struct plane * p = rplane(u->region);
-	int x = rel_to_abs(p, u->faction, atoi(igetstrtoken(str)), 0);
-	int y = rel_to_abs(p, u->faction, atoi(getstrtoken()), 1);
+	short x = rel_to_abs(p, u->faction, (short)atoi(igetstrtoken(str)), 0);
+	short y = rel_to_abs(p, u->faction, (short)atoi(getstrtoken()), 1);
 	const char * c = getstrtoken();
 	region * r = findregion(x, y);
 	terrain_t t;
@@ -237,8 +237,8 @@ gm_teleport(const tnode * tnext, const char * str, void * data, struct order * o
   unit * u = (unit*)data;
 	const struct plane * p = rplane(u->region);
 	unit * to = findunit(atoi36(igetstrtoken(str)));
-	int x = rel_to_abs(p, u->faction, atoi(getstrtoken()), 0);
-	int y = rel_to_abs(p, u->faction, atoi(getstrtoken()), 1);
+	short x = rel_to_abs(p, u->faction, (short)atoi(getstrtoken()), 0);
+	short y = rel_to_abs(p, u->faction, (short)atoi(getstrtoken()), 1);
 	region * r = findregion(x, y);
 
 	if (r==NULL || p!=rplane(r)) {
@@ -331,8 +331,8 @@ gm_messageregion(const tnode * tnext, const char * str, void * data, struct orde
 {
   unit * u = (unit*)data;
   const struct plane * p = rplane(u->region);
-  int x = rel_to_abs(p, u->faction, atoi(igetstrtoken(str)), 0);
-	int y = rel_to_abs(p, u->faction, atoi(getstrtoken()), 1);
+  short x = rel_to_abs(p, u->faction, (short)atoi(igetstrtoken(str)), 0);
+	short y = rel_to_abs(p, u->faction, (short)atoi(getstrtoken()), 1);
 	const char * msg = getstrtoken();
 	region * r = findregion(x, y);
 
@@ -403,10 +403,9 @@ gm_killfaction(const tnode * tnext, const char * str, void * data, struct order
 			unit * target;
 			for (target=r->units;target;target=target->next) {
 				if (target->faction==f) {
-					char * zmsg = (char*)gc_add(strdup(msg));
 					scale_number(target, 0);
 					ADDMSG(&target->faction->msgs, msg_message("killedbygm", 
-						"region unit string", r, target, zmsg));
+						"region unit string", r, target, msg));
 					return;
 				}
 			}
@@ -609,7 +608,7 @@ gmcommands(void)
 #define EXTENSION 10000
 
 faction *
-gm_addquest(const char * email, const char * name, int radius, unsigned int flags)
+gm_addquest(const char * email, const char * name, short radius, unsigned int flags)
 {
 	plane * p;
 	attrib * a;
@@ -617,8 +616,9 @@ gm_addquest(const char * email, const char * name, int radius, unsigned int flag
 	watcher * w = calloc(sizeof(watcher), 1);
 	region * center;
 	boolean invalid = false;
-	int minx, miny, maxx, maxy, cx, cy;
-	int x, y, i;
+	short minx, miny, maxx, maxy, cx, cy;
+	short x;
+  int i;
 	faction * f = calloc(1, sizeof(faction));
 
 	/* GM faction */
@@ -651,9 +651,10 @@ gm_addquest(const char * email, const char * name, int radius, unsigned int flag
 
 	/* GM playfield */
 	do {
-		minx = (rand() % (2*EXTENSION)) - EXTENSION;
-		miny = (rand() % (2*EXTENSION)) - EXTENSION;
+		minx = (short)((rand() % (2*EXTENSION)) - EXTENSION);
+		miny = (short)((rand() % (2*EXTENSION)) - EXTENSION);
 		for (x=0;!invalid && x<=radius*2;++x) {
+      short y;
 			for (y=0;!invalid && y<=radius*2;++y) {
 				region * r = findregion(minx+x, miny+y);
 				if (r) invalid = true;
@@ -665,7 +666,7 @@ gm_addquest(const char * email, const char * name, int radius, unsigned int flag
 	p = create_new_plane(rand(), name, minx, maxx, miny, maxy, flags);
 	center = new_region(cx, cy);
 	for (x=0;x<=2*radius;++x) {
-		int y;
+		short y;
 		for (y=0;y<=2*radius;++y) {
 			region * r = findregion(minx+x, miny+y);
 			if (!r) r = new_region(minx+x, miny+y);
@@ -783,19 +784,20 @@ gm_addfaction(const char * email, plane * p, region * r)
 }
 
 plane *
-gm_addplane(int radius, unsigned int flags, const char * name)
+gm_addplane(short radius, unsigned int flags, const char * name)
 {
 	region * center;
 	plane * p;
 	boolean invalid = false;
-	int minx, miny, maxx, maxy, cx, cy;
-	int x, y;
+	short minx, miny, maxx, maxy, cx, cy;
+	short x;
 
 	/* GM playfield */
 	do {
-		minx = (rand() % (2*EXTENSION)) - EXTENSION;
-		miny = (rand() % (2*EXTENSION)) - EXTENSION;
+		minx = (short)(rand() % (2*EXTENSION)) - EXTENSION;
+		miny = (short)(rand() % (2*EXTENSION)) - EXTENSION;
 		for (x=0;!invalid && x<=radius*2;++x) {
+      short y;
 			for (y=0;!invalid && y<=radius*2;++y) {
 				region * r = findregion(minx+x, miny+y);
 				if (r) invalid = true;
@@ -807,7 +809,7 @@ gm_addplane(int radius, unsigned int flags, const char * name)
 	p = create_new_plane(rand(), name, minx, maxx, miny, maxy, flags);
 	center = new_region(cx, cy);
 	for (x=0;x<=2*radius;++x) {
-		int y;
+		short y;
 		for (y=0;y<=2*radius;++y) {
 			region * r = findregion(minx+x, miny+y);
 			if (!r) r = new_region(minx+x, miny+y);
diff --git a/src/common/modules/gmcmd.h b/src/common/modules/gmcmd.h
index cc2991afa..260619d8e 100644
--- a/src/common/modules/gmcmd.h
+++ b/src/common/modules/gmcmd.h
@@ -31,7 +31,7 @@ extern void gmcommands(void);
 /* execute commands */
 
 extern struct faction * gm_addfaction(const char * email, struct plane * p, struct region * r);
-extern struct plane * gm_addplane(int radius, unsigned int flags, const char * name);
+extern struct plane * gm_addplane(short radius, unsigned int flags, const char * name);
 
 /*
  * doesn't belong in here:
diff --git a/src/common/modules/modules.vcproj b/src/common/modules/modules.vcproj
index 76a8d0b02..00235e2de 100644
--- a/src/common/modules/modules.vcproj
+++ b/src/common/modules/modules.vcproj
@@ -35,6 +35,7 @@
 				ProgramDataBaseFileName=".\Debug/"
 				WarningLevel="4"
 				SuppressStartupBanner="TRUE"
+				Detect64BitPortabilityProblems="TRUE"
 				DebugInformationFormat="1"
 				CompileAs="0"/>
 			<Tool
diff --git a/src/common/races/races.vcproj b/src/common/races/races.vcproj
index 24f0bdd09..16a617385 100644
--- a/src/common/races/races.vcproj
+++ b/src/common/races/races.vcproj
@@ -35,6 +35,7 @@
 				ProgramDataBaseFileName=".\Debug/"
 				WarningLevel="4"
 				SuppressStartupBanner="TRUE"
+				Detect64BitPortabilityProblems="TRUE"
 				DebugInformationFormat="1"
 				CompileAs="0"/>
 			<Tool
diff --git a/src/common/spells/alp.c b/src/common/spells/alp.c
index 989f2f635..21499e842 100644
--- a/src/common/spells/alp.c
+++ b/src/common/spells/alp.c
@@ -137,6 +137,7 @@ alp_findet_opfer(unit *alp, region *r)
 	alp_data * ad = (alp_data*)a->data.v;
 	unit *mage = ad->mage;
 	unit *opfer = ad->target;
+  variant effect;
 
 	assert(opfer);
 	assert(mage);
@@ -155,8 +156,10 @@ alp_findet_opfer(unit *alp, region *r)
 	 * beim destroy_unit(alp) ausgel�st.
 	 */
 	a_removeall(&alp->attribs, &at_eventhandler);
-	/* Alp umwandeln in Curse */
-	c = create_curse(mage, &opfer->attribs, ct_find("worse"), 2, 2, -2, opfer->number);
+
+  /* Alp umwandeln in Curse */
+  effect.i = -2;
+	c = create_curse(mage, &opfer->attribs, ct_find("worse"), 2, 2, effect, opfer->number);
 	/* solange es noch keine spezielle alp-Antimagie gibt, reagiert der
 	 * auch auf normale */
 	/* set_curseflag(opfer->attribs, C_ALLSKILLS, 0, CURSE_NOAGE+CURSE_IMMUN); */
diff --git a/src/common/spells/spells.vcproj b/src/common/spells/spells.vcproj
index 4e4a365f3..9c4d248b6 100644
--- a/src/common/spells/spells.vcproj
+++ b/src/common/spells/spells.vcproj
@@ -86,6 +86,7 @@
 				ProgramDataBaseFileName=".\Debug/"
 				WarningLevel="4"
 				SuppressStartupBanner="TRUE"
+				Detect64BitPortabilityProblems="TRUE"
 				DebugInformationFormat="1"
 				CompileAs="0"/>
 			<Tool
diff --git a/src/common/spells/unitcurse.c b/src/common/spells/unitcurse.c
index 50240ef5d..b6f0ed029 100644
--- a/src/common/spells/unitcurse.c
+++ b/src/common/spells/unitcurse.c
@@ -197,7 +197,7 @@ cinfo_speed(const struct locale * lang, const void * obj, typ_t typ, struct curs
 
 	assert(typ == TYP_UNIT);
 	u = (unit *)obj;
-	cu = (curse_unit *)c->data;
+	cu = (curse_unit *)c->data.v;
 
 	if (self != 0){
 		sprintf(buf, "%d Person%s von %s %s noch %d Woche%s beschleunigt. (%s)",
@@ -259,7 +259,7 @@ cinfo_kaelteschutz(const struct locale * lang, const void * obj, typ_t typ, stru
 
 	assert(typ == TYP_UNIT);
 	u = (unit *)obj;
-	cu = (curse_unit *)c->data;
+	cu = (curse_unit *)c->data.v;
 
 	if (self != 0){
 		sprintf(buf, "%d Person%s von %s %s sich vor K�lte gesch�tzt. (%s)",
@@ -474,13 +474,13 @@ read_skill(FILE * F, curse * c)
 	} else {
 		fscanf(F, "%d", &skill);
 	}
-	c->data = (void*)skill;
+	c->data.i = skill;
 	return 0;
 }
 static int
 write_skill(FILE * F, const curse * c)
 {
-	fprintf(F, "%d ", (int)c->data);
+	fprintf(F, "%d ", c->data.i);
 	return 0;
 }
 
@@ -488,7 +488,7 @@ static int
 cinfo_skill(const struct locale * lang, const void * obj, typ_t typ, struct curse *c, int self)
 {
 	unit *u = (unit *)obj;
-	int sk = (int)c->data;
+	int sk = c->data.i;
 
 	unused(typ);
 
diff --git a/src/common/triggers/createcurse.c b/src/common/triggers/createcurse.c
index a107a0832..d65f1cc89 100644
--- a/src/common/triggers/createcurse.c
+++ b/src/common/triggers/createcurse.c
@@ -66,8 +66,10 @@ createcurse_handle(trigger * t, void * data)
 	 */
 	createcurse_data * td = (createcurse_data*)t->data.v;
 	if (td->mage!=NULL && td->target!=NULL) {
+    variant var;
+    var.i = td->effect;
 		create_curse(td->mage, &td->target->attribs,
-			td->type, td->vigour, td->duration, td->effect, td->men);
+			td->type, td->vigour, td->duration, var, td->men);
 	} else {
 		log_error(("could not perform createcurse::handle()\n"));
 	}
@@ -89,17 +91,17 @@ createcurse_read(trigger * t, FILE * F)
 {
 	createcurse_data * td = (createcurse_data*)t->data.v;
 	char zText[128];
-	int i;
+	variant var;
 
 	fscanf(F, "%s", zText);
-	i = atoi36(zText);
-	td->mage = findunit(i);
-	if (td->mage==NULL) ur_add((void*)i, (void**)&td->mage, resolve_unit);
+	var.i = atoi36(zText);
+	td->mage = findunit(var.i);
+	if (td->mage==NULL) ur_add(var, (void**)&td->mage, resolve_unit);
 
 	fscanf(F, "%s", zText);
-	i = atoi36(zText);
-	td->target = findunit(i);
-	if (td->target==NULL) ur_add((void*)i, (void**)&td->target, resolve_unit);
+	var.i = atoi36(zText);
+	td->target = findunit(var.i);
+	if (td->target==NULL) ur_add(var, (void**)&td->target, resolve_unit);
 
 	if (global.data_version<CURSETYPE_VERSION) {
 		int id1, id2;
diff --git a/src/common/triggers/giveitem.c b/src/common/triggers/giveitem.c
index d0eadc315..c54f6daed 100644
--- a/src/common/triggers/giveitem.c
+++ b/src/common/triggers/giveitem.c
@@ -80,12 +80,12 @@ giveitem_read(trigger * t, FILE * F)
 {
 	giveitem_data * td = (giveitem_data*)t->data.v;
 	char zText[128];
-	int i;
+	variant var;
 
 	fscanf(F, "%s", zText);
-	i = atoi36(zText);
-	td->u = findunit(i);
-	if (td->u==NULL) ur_add((void*)i, (void**)&td->u, resolve_unit);
+	var.i = atoi36(zText);
+	td->u = findunit(var.i);
+	if (td->u==NULL) ur_add(var, (void**)&td->u, resolve_unit);
 
 	fscanf(F, "%d %s", &td->number, zText);
 	td->itype = it_find(zText);
diff --git a/src/common/triggers/removecurse.c b/src/common/triggers/removecurse.c
index 8916dc2d9..849a1386d 100644
--- a/src/common/triggers/removecurse.c
+++ b/src/common/triggers/removecurse.c
@@ -83,16 +83,16 @@ removecurse_read(trigger * t, FILE * F)
 {
 	removecurse_data * td = (removecurse_data*)t->data.v;
 	char zText[128];
-	int i;
+	variant var;
 
 	fscanf(F, "%s", zText);
-	i = atoi36(zText);
-	td->target = findunit(i);
-	if (td->target==NULL) ur_add((void*)i, (void**)&td->target, resolve_unit);
+	var.i = atoi36(zText);
+	td->target = findunit(var.i);
+	if (td->target==NULL) ur_add(var, (void**)&td->target, resolve_unit);
 
-	fscanf(F, "%d", &i);
-	td->curse = cfindhash(i);
-	if (td->curse==NULL) ur_add((void*)i, (void**)&td->curse, resolve_curse);
+	fscanf(F, "%d", &var.i);
+	td->curse = cfindhash(var.i);
+	if (td->curse==NULL) ur_add(var, (void**)&td->curse, resolve_curse);
 
 	return AT_READ_OK;
 }
diff --git a/src/common/triggers/triggers.vcproj b/src/common/triggers/triggers.vcproj
index a350a7836..4ac8d7784 100644
--- a/src/common/triggers/triggers.vcproj
+++ b/src/common/triggers/triggers.vcproj
@@ -35,6 +35,7 @@
 				ProgramDataBaseFileName=".\Debug/"
 				WarningLevel="4"
 				SuppressStartupBanner="TRUE"
+				Detect64BitPortabilityProblems="TRUE"
 				DebugInformationFormat="1"
 				CompileAs="0"/>
 			<Tool
diff --git a/src/common/triggers/unitmessage.c b/src/common/triggers/unitmessage.c
index 3de07ff5b..1722fa55b 100644
--- a/src/common/triggers/unitmessage.c
+++ b/src/common/triggers/unitmessage.c
@@ -85,12 +85,12 @@ unitmessage_read(trigger * t, FILE * F)
 {
 	unitmessage_data * td = (unitmessage_data*)t->data.v;
 	char zText[256];
-	int i;
+	variant var;
 
 	fscanf(F, "%s", zText);
-	i = atoi36(zText);
-	td->target = findunit(i);
-	if (td->target==NULL) ur_add((void*)i, (void**)&td->target, resolve_unit);
+	var.i = atoi36(zText);
+	td->target = findunit(var.i);
+	if (td->target==NULL) ur_add(var, (void**)&td->target, resolve_unit);
 
   freadstr(F, zText, sizeof(zText));
 	fscanf(F, "%d %d ", &td->type, &td->level);
diff --git a/src/common/util/attrib.c b/src/common/util/attrib.c
index 3852a3ee6..5bb34b6e8 100644
--- a/src/common/util/attrib.c
+++ b/src/common/util/attrib.c
@@ -28,7 +28,7 @@ static unsigned int
 __at_hashkey(const char* s)
 {
 	int key = 0;
-	int i = strlen(s);
+	size_t i = strlen(s);
 
 	while (i) {
 		--i;
diff --git a/src/common/util/command.c b/src/common/util/command.c
index 51fe3a0b5..1af090c61 100644
--- a/src/common/util/command.c
+++ b/src/common/util/command.c
@@ -57,18 +57,21 @@ add_command(struct tnode * keys, struct tnode * tnext,
 				const char * str, parser fun)
 {
 	command * cmd = (command *)malloc(sizeof(command));
-	cmd->fun = fun;
+  variant var;
+
+  cmd->fun = fun;
 	cmd->nodes = tnext;
-	addtoken(keys, str, (void*)cmd);
+  var.v = cmd;
+	addtoken(keys, str, var);
 }
 
 static void
 do_command_i(const struct tnode * keys, void * u, const char * str, struct order * ord)
 {
-	int i;
+	size_t i;
 	char zText[16];
 	const char * c;
-	command * cmd;
+  variant var;
 
 	while (isspace(*str)) ++str;
 	c = str;
@@ -76,7 +79,8 @@ do_command_i(const struct tnode * keys, void * u, const char * str, struct order
 	i = min(16, c-str);
 	strncpy(zText, str, i);
 	zText[i]=0;
-	if (findtoken(keys, zText, (void**)&cmd)==E_TOK_SUCCESS) {
+	if (findtoken(keys, zText, &var)==E_TOK_SUCCESS) {
+    command * cmd = (command *)var.v;
 		if (cmd->nodes) {
 			assert(!cmd->fun);
 			do_command_i(cmd->nodes, u, ++c, ord);
diff --git a/src/common/util/crmessage.c b/src/common/util/crmessage.c
index fa3433a92..5c02db4b2 100644
--- a/src/common/util/crmessage.c
+++ b/src/common/util/crmessage.c
@@ -105,7 +105,7 @@ crt_register(const struct message_type * mtype)
     
     /* can be scrapped for memory vs. speed */
     for (i=0;i!=mtype->nparameters;++i) {
-      crt->renderers[i] = tsf_find(mtype->types[i]);
+      crt->renderers[i] = tsf_find(mtype->types[i]->name);
     }
   }
 }
@@ -121,7 +121,7 @@ cr_render(const message * msg, char * buffer, const void * userdata)
 	for (i=0;i!=msg->type->nparameters;++i) {
 		if (crt->renderers[i]==NULL) {
 			log_error(("No renderer for argument %s:%s of \"%s\"\n",
-				msg->type->pnames[i], msg->type->types[i], msg->type->name));
+				msg->type->pnames[i], msg->type->types[i]->name, msg->type->name));
 			continue; /* strcpy(c, (const char*)msg->locale_string(u->faction->locale, parameters[i])); */
 		} else {
 			if (crt->renderers[i](msg->parameters[i], c, userdata)!=0) continue;
@@ -134,25 +134,25 @@ cr_render(const message * msg, char * buffer, const void * userdata)
 }
 
 int
-cr_string(const void * v, char * buffer, const void * userdata)
+cr_string(variant var, char * buffer, const void * userdata)
 {
-	sprintf(buffer, "\"%s\"", (const char *)v);
+	sprintf(buffer, "\"%s\"", (const char *)var.v);
 	unused(userdata);
 	return 0;
 }
 
 int
-cr_int(const void * v, char * buffer, const void * userdata)
+cr_int(variant var, char * buffer, const void * userdata)
 {
-	sprintf(buffer, "%d", (int)v);
+	sprintf(buffer, "%d", var.i);
 	unused(userdata);
 	return 0;
 }
 
 int
-cr_ignore(const void * v, char * buffer, const void * userdata)
+cr_ignore(variant var, char * buffer, const void * userdata)
 {
-	unused(v);
+	unused(var);
 	unused(buffer);
 	unused(userdata);
 	return -1;
diff --git a/src/common/util/crmessage.h b/src/common/util/crmessage.h
index 6df6cc29c..8b5972dbd 100644
--- a/src/common/util/crmessage.h
+++ b/src/common/util/crmessage.h
@@ -12,6 +12,8 @@
 
 #ifndef H_UTIL_CRMESSAGE
 #define H_UTIL_CRMESSAGE
+
+#include "variant.h"
 #ifdef __cplusplus
 extern "C" {
 #endif
@@ -20,13 +22,13 @@ struct locale;
 struct message;
 struct message_type;
 
-typedef int (*tostring_f)(const void * data, char * buffer, const void * userdata);
+typedef int (*tostring_f)(variant data, char * buffer, const void * userdata);
 extern void tsf_register(const char * name, tostring_f fun);
 	/* registers a new type->string-function */
 
-extern int cr_string(const void * v, char * buffer, const void * userdata);
-extern int cr_int(const void * v, char * buffer, const void * userdata);
-extern int cr_ignore(const void * v, char * buffer, const void * userdata);
+extern int cr_string(variant v, char * buffer, const void * userdata);
+extern int cr_int(variant v, char * buffer, const void * userdata);
+extern int cr_ignore(variant v, char * buffer, const void * userdata);
 
 extern void crt_register(const struct message_type * mtype);
 extern int cr_render(const struct message * msg, char * buffer, const void * userdata);
diff --git a/src/common/util/cvector.c b/src/common/util/cvector.c
index 747df849a..500f8d0de 100644
--- a/src/common/util/cvector.c
+++ b/src/common/util/cvector.c
@@ -103,9 +103,9 @@ __cv_scramblecmp(const void *p1, const void *p2)
 #define addptr(p,i)         ((void *)(((char *)p) + i))
 
 void
-__cv_scramble(void *v1, int n, size_t width)
+__cv_scramble(void *v1, size_t n, size_t width)
 {
-	int i;
+	size_t i;
 	static size_t s = 0;
 	static void *v = 0;
 
diff --git a/src/common/util/event.c b/src/common/util/event.c
index f66fc8b9b..75c16667e 100644
--- a/src/common/util/event.c
+++ b/src/common/util/event.c
@@ -200,28 +200,6 @@ add_trigger(struct attrib ** ap, const char * eventname, struct trigger * t)
 	*tp = t;
 }
 
-void
-handle_event_va(attrib ** attribs, const char * eventname, const char * format, ...)
-{
-  event_arg args[9];
-  int argc = 0;
-  va_list marker;
-  char * toks = strdup(format);
-  char * tok = strtok(toks, " ");
-
-  va_start(marker, format);
-  while (tok && argc!=8) {
-    args[argc].data = va_arg(marker, void *);
-    args[argc].type = tok;
-    ++argc;
-    tok = strtok(NULL, " ");
-  }
-  args[argc].type=NULL;
-  va_end(marker);
-  handle_event(attribs, eventname, args);
-  free (toks);
-}
-
 void
 handle_event(attrib ** attribs, const char * eventname, void * data)
 {
diff --git a/src/common/util/event.h b/src/common/util/event.h
index b846649a0..eefc4a7d9 100644
--- a/src/common/util/event.h
+++ b/src/common/util/event.h
@@ -45,8 +45,8 @@ typedef struct trigger {
 } trigger;
 
 typedef struct event_arg {
-  char * type;
-  void * data;
+  const char * type;
+  variant data;
 } event_arg;
 
 extern trigger * t_new(trigger_type * ttype);
@@ -60,7 +60,6 @@ extern void remove_triggers(struct attrib ** ap, const char * eventname, const t
 extern struct trigger ** get_triggers(struct attrib * ap, const char * eventname);
 /* calls handle() for each of these. e.g. used in timeout */
 extern void handle_event(struct attrib ** attribs, const char * eventname, void * data);
-extern void handle_event_va(struct attrib ** attribs, const char * eventname, const char * format, ...);
 
 /* functions for making complex triggers: */
 extern void free_triggers(trigger * triggers); /* release all these triggers */
diff --git a/src/common/util/goodies.c b/src/common/util/goodies.c
index 6b95bdeef..540a81643 100644
--- a/src/common/util/goodies.c
+++ b/src/common/util/goodies.c
@@ -30,23 +30,6 @@
 
 /* Simple Integer-Liste */
 
-char *
-fstrncat(char * buffer, const char * str, unsigned int size)
-{
-	static char * b = NULL;
-	static char * end = NULL;
-	int n = 0;
-	if (b==buffer) {
-		end += strlen(end);
-		size -= (end-b);
-	} else {
-		end = b = buffer;
-	}
-	while (size-- > 0 && (*end++=*str++)!=0) ++n;
-	*end='\0';
-	return b;
-}
-	  
 int *
 intlist_init(void)
 {
@@ -78,7 +61,7 @@ unsigned int
 hashstring(const char* s)
 {
 	unsigned int key = 0;
-	int i = strlen(s);
+	size_t i = strlen(s);
 
 	while (i>0) {
 		key = (s[--i] + key*37);
diff --git a/src/common/util/goodies.h b/src/common/util/goodies.h
index 55ce3f6b2..4aa60ea50 100644
--- a/src/common/util/goodies.h
+++ b/src/common/util/goodies.h
@@ -25,7 +25,6 @@ extern unsigned int hashstring(const char* s);
 
 extern const char *escape_string(const char * str, char * buffer, unsigned int len);
 extern boolean locale_check(void);
-extern char *fstrncat(char * buffer, const char * str, unsigned int size);
 
 extern int set_email(char** pemail, const char *newmail);
 /* fast strncat */
diff --git a/src/common/util/lists.c b/src/common/util/lists.c
index dc0140382..070dbcc7b 100644
--- a/src/common/util/lists.c
+++ b/src/common/util/lists.c
@@ -139,13 +139,13 @@ invert_list(void * heap)
 	*(void **)heap = x;
 }
 
-size_t
+unsigned int
 listlen(void *l)
 {
 
 	/* count entries p in list l */
 
-	size_t i;
+	unsigned int i;
 	void_list *p;
 
 	for (p = (void_list *)l, i = 0; p; p = p->next, i++);
diff --git a/src/common/util/lists.h b/src/common/util/lists.h
index 1fa610b42..4db07c8d2 100644
--- a/src/common/util/lists.h
+++ b/src/common/util/lists.h
@@ -48,7 +48,7 @@ void removelist(void *l, void *p);
 #define removelist(l,p) { choplist(l, p); free(p); }
 #endif
 
-size_t listlen(void *l);
+unsigned int listlen(void *l);
 void invert_list(void * heap);
 #define addlist2(l, p)       (*l = p, l = &p->next)
 
diff --git a/src/common/util/message.c b/src/common/util/message.c
index 857f5d960..e7299eae9 100644
--- a/src/common/util/message.c
+++ b/src/common/util/message.c
@@ -47,7 +47,7 @@ mt_new(const char * name, const char * args[])
   mtype->nparameters = nparameters;
   if (nparameters > 0) {
     mtype->pnames = (const char**)malloc(sizeof(char*) * nparameters);
-    mtype->types = (const char**)malloc(sizeof(char*) * nparameters);
+    mtype->types = (const arg_type**)malloc(sizeof(arg_type*) * nparameters);
   } else {
     mtype->pnames = NULL;
     mtype->types = NULL;
@@ -63,7 +63,7 @@ mt_new(const char * name, const char * args[])
       cp[spos-x] = '\0';
       mtype->pnames[i] = cp;
       /* optimierung: Typ-Strings zentral verwalten. */
-      mtype->types[i] = strdup(spos+1);
+      mtype->types[i] = find_argtype(spos+1);
     }
   }
   return mtype;
@@ -86,27 +86,21 @@ mt_new_va(const char * name, ...)
 	return mt_new(name, args);
 }
 
-typedef struct arg_type {
-  struct arg_type * next;
-  const char * name;
-  void  (*release)(void*);
-  void* (*copy)(void*);
-} arg_type;
-
 arg_type * argtypes = NULL;
 
 void
-register_argtype(const char * name, void(*free_arg)(void*), void*(*copy_arg)(void*))
+register_argtype(const char * name, void(*free_arg)(variant), variant (*copy_arg)(variant), variant_type type)
 {
   arg_type * atype = (arg_type *)malloc(sizeof(arg_type));
   atype->name = name;
   atype->next = argtypes;
   atype->release = free_arg;
   atype->copy = copy_arg;
+  atype->vtype = type;
   argtypes = atype;
 }
 
-static arg_type *
+const arg_type *
 find_argtype(const char * name)
 {
   arg_type * atype = argtypes;
@@ -117,57 +111,41 @@ find_argtype(const char * name)
   return NULL;
 }
 
-static void *
-copy_arg(const char * type, void * data)
+static variant
+copy_arg(const arg_type * atype, variant data)
 {
-  arg_type * atype = find_argtype(type);
-  if (atype==NULL) return data;
+  assert(atype!=NULL);
   if (atype->copy==NULL) return data;
   return atype->copy(data);
 }
 
 static void
-free_arg(const char * type, void * data)
+free_arg(const arg_type * atype, variant data)
 {
-  arg_type * atype = find_argtype(type);
-  if (atype && atype->release) atype->release(data);
+  assert(atype!=NULL);
+  if (atype->release) atype->release(data);
 }
 
 message *
-msg_create(const struct message_type * type, void * args[])
+msg_create(const struct message_type * mtype, variant args[])
 {
   int i;
   message * msg = (message *)malloc(sizeof(message));
 
-  assert(type!=NULL);
-  if (type==NULL) {
+  assert(mtype!=NULL);
+  if (mtype==NULL) {
     log_error(("Trying to create message with type=0x0\n"));
     return NULL;
   }
-  msg->type = type;
-  msg->parameters = (void**)calloc(type->nparameters, sizeof(void*));
+  msg->type = mtype;
+  msg->parameters = (variant*)calloc(mtype->nparameters, sizeof(variant));
   msg->refcount=1;
-  for (i=0;i!=type->nparameters;++i) {
-    msg->parameters[i] = copy_arg(type->types[i], args[i]);
+  for (i=0;i!=mtype->nparameters;++i) {
+    msg->parameters[i] = copy_arg(mtype->types[i], args[i]);
   }
   return msg;
 }
 
-message *
-msg_create_va(const struct message_type * type, ...)
-/* sets a messages parameters */
-{
-	void * args[16];
-	va_list marker;
-	int i;
-	va_start(marker, type);
-	for (i=0;i!=type->nparameters;++i) {
-		args[i] = va_arg(marker, void*);
-	}
-	va_end(marker);
-	return msg_create(type, args);
-}
-
 typedef struct messagetype_list {
 	struct messagetype_list * next;
 	const struct message_type * data;
diff --git a/src/common/util/message.h b/src/common/util/message.h
index 199a7d505..c765a55a3 100644
--- a/src/common/util/message.h
+++ b/src/common/util/message.h
@@ -11,22 +11,33 @@
 */
 #ifndef UTIL_MESSAGE_H
 #define UTIL_MESSAGE_H
+
+#include "variant.h"
+
 #ifdef __cplusplus
 extern "C" {
 #endif
 
 struct locale;
 
+typedef struct arg_type {
+  struct arg_type * next;
+  variant_type vtype;
+  const char * name;
+  void  (*release)(variant);
+  variant (*copy)(variant);
+} arg_type;
+
 typedef struct message_type {
 	const char * name;
 	int nparameters;
 	const char ** pnames;
-	const char ** types;
+	const struct arg_type ** types;
 } message_type;
 
 typedef struct message {
 	const struct message_type * type;
-	void ** parameters;
+	variant * parameters;
 	int refcount;
 } message;
 
@@ -35,8 +46,7 @@ extern struct message_type * mt_new_va(const char * name, ...);
 	/* mt_new("simple_sentence", "subject:string", "predicate:string", 
     *        "object:string", "lang:locale", NULL); */
 
-extern struct message * msg_create(const struct message_type * type, void * args[]);
-extern struct message * msg_create_va(const struct message_type * type, ...);
+extern struct message * msg_create(const struct message_type * type, variant args[]);
 	/* msg_create(&mt_simplesentence, "enno", "eats", "chocolate", &locale_de); 
 	 * parameters must be in the same order as they were for mt_new! */
 
@@ -49,7 +59,8 @@ extern const char * mt_name(const struct message_type* mtype);
 extern const struct message_type * mt_register(const struct message_type *);
 extern const struct message_type * mt_find(const char *);
 
-extern void register_argtype(const char * name, void(*free_arg)(void*), void*(*copy_arg)(void*));
+extern void register_argtype(const char * name, void(*free_arg)(variant), variant (*copy_arg)(variant), variant_type);
+extern const struct arg_type * find_argtype(const char * name);
 
 #ifdef __cplusplus
 }
diff --git a/src/common/util/resolve.c b/src/common/util/resolve.c
index 2471669fb..613b319ae 100644
--- a/src/common/util/resolve.c
+++ b/src/common/util/resolve.c
@@ -23,13 +23,14 @@
 #include <assert.h>
 #include <stdlib.h>
 #include "resolve.h"
+#include "variant.h"
 
 typedef struct unresolved {
 	struct unresolved * next;
 	void ** ptrptr;
 		/* pointer to the location where the unresolved object
 		 * should be, or NULL if special handling is required */
-	void * data;
+	variant data;
 		/* information on how to resolve the missing object */
 	resolve_fun resolve;
 		/* function to resolve the unknown object */
@@ -38,7 +39,7 @@ typedef struct unresolved {
 unresolved * ur_list;
 
 void
-ur_add(void * data, void ** ptrptr, resolve_fun fun) {
+ur_add(variant data, void ** ptrptr, resolve_fun fun) {
    unresolved * ur = malloc(sizeof(unresolved));
    ur->data = data;
    ur->resolve = fun;
diff --git a/src/common/util/resolve.h b/src/common/util/resolve.h
index e97c58dbb..e58b0a011 100644
--- a/src/common/util/resolve.h
+++ b/src/common/util/resolve.h
@@ -14,14 +14,16 @@
 
 #ifndef RESOLVE_H
 #define RESOLVE_H
+
+#include <util/variant.h>
+
 #ifdef __cplusplus
 extern "C" {
 #endif
 
-typedef void * (*resolve_fun)(void * data);
-
-extern void ur_add(void * data, void ** ptrptr, resolve_fun fun);
-extern void resolve(void);
+  typedef void * (*resolve_fun)(variant data);
+  extern void ur_add(variant data, void ** ptrptr, resolve_fun fun);
+  extern void resolve(void);
 
 #ifdef __cplusplus
 }
diff --git a/src/common/util/translation.c b/src/common/util/translation.c
index 5539b5c0d..324d59d4d 100644
--- a/src/common/util/translation.c
+++ b/src/common/util/translation.c
@@ -27,14 +27,14 @@
 
 typedef struct opstack {
 	struct opstack * next;
-	void * data;
+	variant data;
 } opstack;
 
-void * 
+variant
 opstack_pop(opstack ** stack)
 {
 	opstack * os;
-	void * data;
+	variant data;
 
 	assert(stack);
 	os = *stack;
@@ -46,7 +46,7 @@ opstack_pop(opstack ** stack)
 }
 
 void
-opstack_push(opstack ** stack, void * data)
+opstack_push(opstack ** stack, variant data)
 {
 	opstack * os = (opstack*)malloc(sizeof(opstack));
 	os->next = *stack;
@@ -107,7 +107,7 @@ brelease(void)
 typedef struct variable {
 	struct variable * next;
 	const char * symbol;
-	const void * value;
+	variant value;
 } variable;
 
 static variable * variables;
@@ -119,7 +119,7 @@ free_variables(void)
 }
 
 static void
-add_variable(const char * symbol, const void * value)
+add_variable(const char * symbol, variant value)
 {
 	variable * var = (variable*)balloc(sizeof(variable));
 
@@ -241,6 +241,7 @@ parse_string(opstack ** stack, const char* in, const void * userdata) /* (char*)
 	/* mode flags */
 	boolean f_escape = false;
 	boolean bDone = false;
+  variant var;
 
 	while (*ic && !bDone) {
 		if (f_escape) {
@@ -269,7 +270,7 @@ parse_string(opstack ** stack, const char* in, const void * userdata) /* (char*)
 			case '$':
 				ic = parse_symbol(stack, ++ic, userdata);
 				if (ic==NULL) return NULL;
-				c = opop(stack, char*);
+				c = (char*)opop_v(stack);
 				oc += strlen(strcpy(oc, c));
 				bfree(c);
 				break;
@@ -280,7 +281,8 @@ parse_string(opstack ** stack, const char* in, const void * userdata) /* (char*)
 	}
 	*oc++ = '\0';
 	bfree(oc);
-	opush(stack, buffer);
+  var.v = buffer;
+	opush(stack, var);
 	return ic;
 }
 
@@ -290,6 +292,7 @@ parse_int(opstack ** stack, const char * in)
 	int k = 0;
 	int vz = 1;
 	boolean ok = false;
+  variant var;
 	do {
 		switch (*in) {
 		case '+':
@@ -306,7 +309,8 @@ parse_int(opstack ** stack, const char * in)
 	while (isdigit(*in)) {
 		k = k * 10 + (*in++)-'0';
 	}
-	opush(stack, k*vz);
+  var.i = k*vz;
+	opush(stack, var);
 	return in;
 }
 
@@ -335,7 +339,7 @@ parse(opstack ** stack, const char* inn, const void * userdata)
 }
 
 const char * 
-translate(const char* format, const void * userdata, const char* vars, void* args[])
+translate(const char* format, const void * userdata, const char* vars, variant args[])
 {
 	int i = 0;
 	const char *ic = vars;
@@ -350,7 +354,7 @@ translate(const char* format, const void * userdata, const char* vars, void* arg
 	while (*ic) {
 		*oc++ = *ic++;
 		if (!isalnum(*ic)) {
-			const void * x = args[i++];
+			variant x = args[i++];
 			*oc = '\0';
 			oc = symbol;
 			add_variable(strcpy(balloc(strlen(symbol)+1), symbol), x);
@@ -359,80 +363,51 @@ translate(const char* format, const void * userdata, const char* vars, void* arg
 	}
 
 	if (parse(&stack, format, userdata)==NULL) return NULL;
-	return opop(&stack, const char*);
-}
-
-const char *
-translate_va(const char* format, const void * userdata, const char* vars, ...)
-{
-	va_list marker;
-	const char *ic = vars;
-	char symbol[32];
-	char *oc = symbol;
-	opstack * stack = NULL;
-	brelease();
-	free_variables();
-
-   va_start(marker, vars);     /* Initialize variable arguments. */
-	assert(isalnum(*ic));
-   while (*ic) {
-		*oc++ = *ic++;
-		if (!isalnum(*ic)) {
-			void * x = va_arg(marker, void *);
-			*oc = '\0';
-			oc = symbol;
-			add_variable(strcpy(balloc(strlen(symbol)+1), symbol), x);
-			while (*ic && !isalnum(*ic)) ++ic;
-		}
-   }
-   va_end(marker);              /* Reset variable arguments.      */
-
-	if (parse(&stack, format, userdata)==NULL) return NULL;
-	return opop(&stack, const char*);
+	return (const char*)opop(&stack).v;
 }
 
 static void
 eval_eq(opstack ** stack, const void * userdata) /* (int, int) -> int */
 {
-	int a = opop(stack, int);
-	int b = opop(stack, int);
+	int a = opop_i(stack);
+	int b = opop_i(stack);
 	int rval = (a==b)?1:0;
-	opush(stack, rval);
+	opush_i(stack, rval);
 	unused(userdata);
 }
 
 static void
 eval_add(opstack ** stack, const void * userdata) /* (int, int) -> int */
 {
-	int a = opop(stack, int);
-	int b = opop(stack, int);
-	opush(stack, a+b);
+	int a = opop_i(stack);
+	int b = opop_i(stack);
+	opush_i(stack, a+b);
 	unused(userdata);
 }
 
 static void
 eval_isnull(opstack ** stack, const void * userdata) /* (int, int) -> int */
 {
-	void * a = opop(stack, void *);
-	opush(stack, (a==NULL)?1:0);
+	void * a = opop_v(stack);
+	opush_i(stack, (a==NULL)?1:0);
 	unused(userdata);
 }
 
 static void
 eval_if(opstack ** stack, const void * userdata) /* (int, int) -> int */
 {
-	void * a = opop(stack, void *);
-	void * b = opop(stack, void *);
-	int cond = opop(stack, int);
-	opush(stack, cond?b:a);
+	void * a = opop_v(stack);
+	void * b = opop_v(stack);
+	int cond = opop_i(stack);
+	opush_v(stack, cond?b:a);
 	unused(userdata);
 }
 
 static void
 eval_strlen(opstack ** stack, const void * userdata) /* string -> int */
 {
-	const char * c = opop(stack, const char *);
-	opush(stack, c?strlen(c):0);
+	const char * c = (const char *)opop_v(stack);
+	opush_i(stack, c?(int)strlen(c):0);
 	unused(userdata);
 }
 
@@ -440,29 +415,32 @@ eval_strlen(opstack ** stack, const void * userdata) /* string -> int */
 static void
 eval_int(opstack ** stack, const void * userdata)
 {
-	int i = opop(stack, int);
+	int i = opop_i(stack);
 	const char * c = itoa10(i);
-	opush(stack, strcpy(balloc(strlen(c)+1), c));
-	unused(userdata);
+  size_t len = strlen(c);
+  variant var;
+
+  var.v = strcpy(balloc(len+1), c);
+  opush(stack, var);
 }
 
 #include "language.h"
 static void
 eval_localize(opstack ** stack, const void * userdata) /* (string, locale) -> string */
 {
-	const struct locale *lang = opop(stack, const struct locale *);
-	const char *c = opop(stack, const char *);
+	const struct locale *lang = (const struct locale *)opop_v(stack);
+	const char *c = (const char *)opop_v(stack);
 	c = locale_string(lang, c);
-	opush(stack, strcpy(balloc(strlen(c)+1), c));
+	opush_v(stack, strcpy(balloc(strlen(c)+1), c));
 	unused(userdata);
 }
 
 static void
 eval_locale(opstack ** stack, const void * userdata) /* (string) -> locale */
 {
-	const char *c = opop(stack, const char *);
-	const struct locale *lang = find_locale(c);
-	opush(stack, lang);
+	const char *c = (const char *)opop_v(stack);
+  struct locale * lang = find_locale(c);
+	opush_v(stack, lang);
 	unused(userdata);
 }
 
diff --git a/src/common/util/translation.h b/src/common/util/translation.h
index 916df2944..61ca5fce9 100644
--- a/src/common/util/translation.h
+++ b/src/common/util/translation.h
@@ -16,16 +16,21 @@
 extern "C" {
 #endif
 
+#include "variant.h"
 struct opstack;
-extern void * opstack_pop(struct opstack ** stack);
-extern void opstack_push(struct opstack ** stack, void * data);
-#define opush(stack, i) opstack_push(stack, (void *)(i))
-#define opop(stack, T) (T)opstack_pop(stack)
+extern void opstack_push(struct opstack ** stack, variant data);
+#define opush_i(stack, x) { variant localvar; localvar.i = x; opstack_push(stack, localvar); }
+#define opush_v(stack, x) { variant localvar; localvar.v = x; opstack_push(stack, localvar); }
+#define opush(stack, i) opstack_push(stack, i)
+
+extern variant opstack_pop(struct opstack ** stack);
+#define opop_v(stack) opstack_pop(stack).v
+#define opop_i(stack) opstack_pop(stack).i
+#define opop(stack) opstack_pop(stack)
 
 extern void translation_init(void);
 extern void translation_done(void);
-extern const char * translate_va(const char* format, const void * userdata, const char* vars, ...);
-extern const char * translate(const char* format, const void * userdata, const char* vars, void* args[]);
+extern const char * translate(const char* format, const void * userdata, const char* vars, variant args[]);
 
 /* eval_x functions */
 typedef void (*evalfun)(struct opstack ** stack, const void *);
diff --git a/src/common/util/umlaut.c b/src/common/util/umlaut.c
index 1f2f9c8ed..4f0355827 100644
--- a/src/common/util/umlaut.c
+++ b/src/common/util/umlaut.c
@@ -37,7 +37,7 @@ typedef struct tref {
 #define SHARED 2 /* at least two words share the node */
 
 void
-addtoken(tnode * root, const char* str, void * id)
+addtoken(tnode * root, const char* str, variant id)
 {
 	static struct replace {
 		char c;
@@ -86,7 +86,7 @@ addtoken(tnode * root, const char* str, void * id)
 			next=ref;
 		} else {
 			next->node->flags |= SHARED;
-			if ((next->node->flags & LEAF) == 0) next->node->id = NULL;
+			if ((next->node->flags & LEAF) == 0) next->node->id.v = NULL; /* why?*/
 		}
 		addtoken(next->node, str+1, id);
 		while (replace[i].str) {
@@ -102,7 +102,7 @@ addtoken(tnode * root, const char* str, void * id)
 }
 
 int
-findtoken(const tnode * tk, const char * str, void **result)
+findtoken(const tnode * tk, const char * str, variant* result)
 {
 	if (!str) return E_TOK_NOMATCH;
 	if (*str == 0) return E_TOK_NOMATCH;
diff --git a/src/common/util/umlaut.h b/src/common/util/umlaut.h
index 65ae5eca1..b753081c8 100644
--- a/src/common/util/umlaut.h
+++ b/src/common/util/umlaut.h
@@ -14,6 +14,9 @@
 
 #ifndef _UMLAUT_H
 #define _UMLAUT_H
+
+#include "variant.h"
+
 #ifdef __cplusplus
 extern "C" {
 #endif
@@ -26,11 +29,11 @@ struct tref;
 typedef struct tnode {
 	struct tref * next[NODEHASHSIZE];
 	unsigned char flags;
-	void * id;
+	variant id;
 } tnode;
 
-int findtoken(const struct tnode * tk, const char * str, void** result);
-void addtoken(struct tnode * root, const char* str, void * id);
+int findtoken(const struct tnode * tk, const char * str, variant* result);
+void addtoken(struct tnode * root, const char* str, variant id);
 
 #ifdef __cplusplus
 }
diff --git a/src/common/util/util.vcproj b/src/common/util/util.vcproj
index b4cac96d9..941d140b4 100644
--- a/src/common/util/util.vcproj
+++ b/src/common/util/util.vcproj
@@ -139,6 +139,7 @@
 				ProgramDataBaseFileName=".\Debug/"
 				WarningLevel="4"
 				SuppressStartupBanner="TRUE"
+				Detect64BitPortabilityProblems="TRUE"
 				DebugInformationFormat="1"
 				CompileAs="0"/>
 			<Tool
@@ -234,6 +235,9 @@
 			<File
 				RelativePath=".\umlaut.h">
 			</File>
+			<File
+				RelativePath=".\variant.h">
+			</File>
 			<File
 				RelativePath=".\vmap.h">
 			</File>
diff --git a/src/common/util/variant.h b/src/common/util/variant.h
index 4f900aa20..726d1f70a 100644
--- a/src/common/util/variant.h
+++ b/src/common/util/variant.h
@@ -4,16 +4,19 @@
 extern "C" {
 #endif
 
-typedef union {
+typedef union variant {
 	void *v;
-	int   i;
+  int   i;
 	char  c;
 	short s;
 	short sa[2];
 	char  ca[4];
+  float f;
 } variant;
 
-#define VAR(x) ()
+typedef enum variant_type {
+  VAR_NONE, VAR_INT, VAR_VOIDPTR, VAR_CHAR, VAR_SHORT, VAR_SHORTA, VAR_CHARA, VAR_FLOAT 
+} variant_type;
 
 #ifdef __cplusplus
 }
diff --git a/src/common/util/vmap.c b/src/common/util/vmap.c
index d681fdcf8..8665af97b 100644
--- a/src/common/util/vmap.c
+++ b/src/common/util/vmap.c
@@ -29,7 +29,7 @@
 #include <config.h>
 #include "vmap.h"
 
-unsigned int
+size_t
 vmap_lowerbound(const vmap * vm, const int key)
 /* returns the index of the entry which has the greatest key  that is less or
  * equal to 'key' */
@@ -57,7 +57,7 @@ vmap_init(vmap * map)
 	map->data = calloc(4, sizeof(vmapentry));
 }
 
-unsigned int
+size_t
 vmap_upperbound(const vmap * vm, const int key)
 /* returns the index of the entry which has the smallest key  that is greater
  * or equal to 'key' */
@@ -78,10 +78,10 @@ vmap_upperbound(const vmap * vm, const int key)
 	return first - vm->data;
 }
 
-unsigned int
+size_t
 vmap_get(vmap * vm, const int key)
 {
-	unsigned int insert = vmap_lowerbound(vm, key);
+	size_t insert = vmap_lowerbound(vm, key);
 	vmapentry *at;
 
 	/* make sure it's a unique key: */
@@ -101,12 +101,12 @@ vmap_get(vmap * vm, const int key)
 	return insert;
 }
 
-unsigned int
+size_t
 vmap_insert(vmap * vm, const int key, void *data)
 /* inserts an object into the vmap, identifies it with the 'key' which must be
  * unique, and returns the vmapentry it created. */
 {
-	unsigned int insert = vmap_lowerbound(vm, key);
+	size_t insert = vmap_lowerbound(vm, key);
 	vmapentry *at;
 
 	/* make sure it's a unique key: */
@@ -125,7 +125,7 @@ vmap_insert(vmap * vm, const int key, void *data)
 	return insert;
 }
 
-unsigned int
+size_t
 vmap_find(const vmap * vm, const int key)
 /* returns the index of the vmapentry that's identified by the key or size (a
  * past-the-end value) if it is not found. */
diff --git a/src/common/util/vmap.h b/src/common/util/vmap.h
index d6f58d245..716c591bc 100644
--- a/src/common/util/vmap.h
+++ b/src/common/util/vmap.h
@@ -30,11 +30,11 @@ struct vmap {
 	unsigned int maxsize;
 };
 
-unsigned int vmap_lowerbound(const vmap * vm, const int key);
-unsigned int vmap_upperbound(const vmap * vm, const int key);
-unsigned int vmap_insert(vmap * vm, const int key, void *data);
-unsigned int vmap_find(const vmap * vm, const int key);
-unsigned int vmap_get(vmap * vm, const int key);
+size_t vmap_lowerbound(const vmap * vm, const int key);
+size_t vmap_upperbound(const vmap * vm, const int key);
+size_t vmap_insert(vmap * vm, const int key, void *data);
+size_t vmap_find(const vmap * vm, const int key);
+size_t vmap_get(vmap * vm, const int key);
 void vmap_init(vmap * vm);
 
 #ifdef __cplusplus
diff --git a/src/common/util/vset.c b/src/common/util/vset.c
index dd2d43a3a..62ad2dad9 100644
--- a/src/common/util/vset.c
+++ b/src/common/util/vset.c
@@ -52,7 +52,7 @@ vset_erase(vset * s, void *item)
 	return 0;
 }
 
-unsigned int
+size_t
 vset_add(vset * s, void *item)
 {
 	size_t i;
diff --git a/src/common/util/vset.h b/src/common/util/vset.h
index d9f716df0..785c80178 100644
--- a/src/common/util/vset.h
+++ b/src/common/util/vset.h
@@ -27,7 +27,7 @@ struct vset {
 };
 extern void vset_init(vset * s);
 extern void vset_destroy(vset * s);
-extern unsigned int vset_add(vset * s, void *);
+extern size_t vset_add(vset * s, void *);
 extern int vset_erase(vset * s, void *);
 extern int vset_count(vset *s, void * i);
 extern void *vset_pop(vset *s);
diff --git a/src/common/util/windir.h b/src/common/util/windir.h
index bd045fb0d..711754385 100644
--- a/src/common/util/windir.h
+++ b/src/common/util/windir.h
@@ -33,7 +33,7 @@ typedef struct dirent {
 	char d_drive[_MAX_DRIVE];
 	char d_dir[_MAX_DIR];
 	char d_ext[_MAX_EXT];
-	long hnd;
+	intptr_t hnd;
 } dirent;
 
 DIR *opendir(const char *name);
diff --git a/src/eressea/eressea-lua.vcproj b/src/eressea/eressea-lua.vcproj
index b0efd7fe3..03d7ff882 100644
--- a/src/eressea/eressea-lua.vcproj
+++ b/src/eressea/eressea-lua.vcproj
@@ -164,6 +164,7 @@
 				ProgramDataBaseFileName=".\Debug/"
 				WarningLevel="4"
 				SuppressStartupBanner="TRUE"
+				Detect64BitPortabilityProblems="TRUE"
 				DebugInformationFormat="4"
 				CompileAs="0"
 				DisableSpecificWarnings="4505"/>
diff --git a/src/eressea/eressea.vcproj b/src/eressea/eressea.vcproj
index c560f5f50..3b71a8ce7 100644
--- a/src/eressea/eressea.vcproj
+++ b/src/eressea/eressea.vcproj
@@ -163,6 +163,7 @@
 				ProgramDataBaseFileName=".\Debug/"
 				WarningLevel="4"
 				SuppressStartupBanner="TRUE"
+				Detect64BitPortabilityProblems="TRUE"
 				DebugInformationFormat="4"
 				CompileAs="0"/>
 			<Tool
diff --git a/src/eressea/korrektur.c b/src/eressea/korrektur.c
index 5914fbe53..66a49c398 100644
--- a/src/eressea/korrektur.c
+++ b/src/eressea/korrektur.c
@@ -112,8 +112,10 @@ curse_emptiness(void)
 				}
 			}
 			if (d!=MAXDIRECTIONS) {
-				curse * c = create_curse(NULL, &r->attribs, ct,
-										 100, 100, 0, 0);
+        variant effect;
+				curse * c;
+        effect.i = 0;
+        c = create_curse(NULL, &r->attribs, ct, 100, 100, effect, 0);
 				curse_setflag(c, CURSE_ISNEW|CURSE_IMMUNE);
 			}
 			freset(r, FL_MARK);
@@ -841,7 +843,7 @@ fix_road_borders(void)
       border * b;
       for (b=bhash;b && i!=MAXDEL;b=b->next) {
         if (b->type == &bt_road) {
-          int x1, x2, y1, y2;
+          short x1, x2, y1, y2;
           region *r1, *r2;
 
           x1 = b->from->x;
diff --git a/src/eressea/lua/eressea.cpp b/src/eressea/lua/eressea.cpp
index 0aadf3c43..e2b49249a 100644
--- a/src/eressea/lua/eressea.cpp
+++ b/src/eressea/lua/eressea.cpp
@@ -142,7 +142,7 @@ lua_planmonsters(void)
   faction * f = findfaction(MONSTER_FACTION);
 
   if (f==NULL) return;
-  if (turn == 0) srand(time((time_t *) NULL));
+  if (turn == 0) srand((int)time(0));
   else srand(turn);
   plan_monsters();
   for (u=f->units;u;u=u->nextF) {
diff --git a/src/eressea/lua/event.cpp b/src/eressea/lua/event.cpp
index e8f71af60..797f9b695 100644
--- a/src/eressea/lua/event.cpp
+++ b/src/eressea/lua/event.cpp
@@ -25,19 +25,19 @@ event::get_type(int i) const
 struct unit * 
 event::get_unit(int i) const 
 {
-  return (struct unit *)args[i].data; 
+  return (struct unit *)args[i].data.v; 
 }
 
 const char * 
 event::get_string(int i) const 
 { 
-  return (const char*)args[i].data; 
+  return (const char*)args[i].data.v; 
 }
 
 int 
 event::get_int(int i) const 
 {
-  return (int)args[i].data; 
+  return args[i].data.i;
 }
 
 void
diff --git a/src/eressea/lua/region.cpp b/src/eressea/lua/region.cpp
index 59d25a291..36ae963ba 100644
--- a/src/eressea/lua/region.cpp
+++ b/src/eressea/lua/region.cpp
@@ -130,7 +130,7 @@ region_getroad(region& r, int dir)
 }
 
 static region *
-terraform_region(int x, int y, const char * tname)
+terraform_region(short x, short y, const char * tname)
 {
   terrain_t t;
 
@@ -204,7 +204,7 @@ region_remove(region& r)
 }
 
 void
-region_move(region& r, int x, int y)
+region_move(region& r, short x, short y)
 {
   if (findregion(x,y)) {
     log_error(("Bei %d, %d gibt es schon eine Region.\n", x, y));
diff --git a/src/eressea/main.c b/src/eressea/main.c
index 8c410af3e..5ca586696 100644
--- a/src/eressea/main.c
+++ b/src/eressea/main.c
@@ -260,7 +260,7 @@ processturn(char *filename)
   newfaction * players;
 	int i;
 
-  if (turn == 0) srand(time((time_t *) NULL));
+  if (turn == 0) srand((int)time(0));
   else srand(turn);
 
 #ifdef SHORTPWDS
@@ -272,7 +272,7 @@ processturn(char *filename)
 	turn++;
 	if ((i=readorders(filename))!=0) return i;
   if (!nomonsters) {
-    if (turn == 0) srand(time((time_t *) NULL));
+    if (turn == 0) srand((int)time(0));
     else srand(turn);
     puts(" - Monster KI...");
     plan_monsters();
@@ -660,7 +660,7 @@ main(int argc, char *argv[])
 		return crwritemap(); 
 	}
 
-  if (turn == 0) srand(time((time_t *) NULL));
+  if (turn == 0) srand((int)time(0));
   else srand(turn);
 
 
diff --git a/src/eressea/server.cpp b/src/eressea/server.cpp
index 5a8e74667..4b59b6bb7 100644
--- a/src/eressea/server.cpp
+++ b/src/eressea/server.cpp
@@ -354,7 +354,7 @@ update_subscriptions(void)
 int
 process_orders()
 {
-  if (turn == 0) srand(time((time_t *) NULL));
+  if (turn == 0) srand((int)time(0));
   else srand(turn);
 
 #ifdef SHORTPWDS
diff --git a/src/mapper/map_region.c b/src/mapper/map_region.c
index e06d8e29d..bc4d57883 100644
--- a/src/mapper/map_region.c
+++ b/src/mapper/map_region.c
@@ -144,6 +144,8 @@ void
 SpecialFunction(region *r)
 {
 	WINDOW *win;
+  variant zero_effect;
+  zero_effect.i = 0;
 
 	win = openwin(60, 5, "< Specials Regions >");
 	wmove(win, 1, 2);
@@ -154,14 +156,14 @@ SpecialFunction(region *r)
 	case '1':
 		if (get_curse(r->attribs, ct_find("godcursezone"))==NULL) {
 			curse * c = create_curse(NULL, &r->attribs, ct_find("godcursezone"),
-				100, 100, 0, 0);
+				100, 100, zero_effect, 0);
 			curse_setflag(c, CURSE_ISNEW|CURSE_IMMUNE);
 			modified = 1;
 			break;
 		}
 	case '2':
 		if(!is_cursed_internal(r->attribs, ct_find("peacezone"))) {
-			curse * c = create_curse(NULL, &r->attribs, ct_find("peacezone"), 100, 2, 0, 0);
+			curse * c = create_curse(NULL, &r->attribs, ct_find("peacezone"), 100, 2, zero_effect, 0);
 			curse_setflag(c, CURSE_IMMUNE);
 			modified = 1;
 		}
diff --git a/src/mapper/mapper.vcproj b/src/mapper/mapper.vcproj
index 25a7b281c..88f142bb7 100644
--- a/src/mapper/mapper.vcproj
+++ b/src/mapper/mapper.vcproj
@@ -98,6 +98,7 @@
 				ProgramDataBaseFileName=".\Debug/"
 				WarningLevel="4"
 				SuppressStartupBanner="TRUE"
+				Detect64BitPortabilityProblems="FALSE"
 				DebugInformationFormat="4"
 				CompileAs="0"/>
 			<Tool