diff --git a/polymer/build/include/build.h b/polymer/build/include/build.h
index 019527b03..3a33968b3 100644
--- a/polymer/build/include/build.h
+++ b/polymer/build/include/build.h
@@ -588,6 +588,27 @@ int loaddefinitionsfile(char *fn);
 extern int mapversion;	// if loadboard() fails with -2 return, try loadoldboard(). if it fails with -2, board is dodgy
 int loadoldboard(char *filename, char fromwhere, int *daposx, int *daposy, int *daposz, short *daang, short *dacursectnum);
 
+// Hash functions
+struct HASH_item // size is 12/24 bits.
+{
+    const char *string;
+    int key;
+    struct HASH_item *next;
+};
+
+struct HASH_table
+{
+    int size;
+    struct HASH_item **items;
+};
+
+void HASH_init(struct HASH_table *t);
+void HASH_free(struct HASH_table *t);
+int  HASH_findcase(struct HASH_table *t, const char *s);
+int  HASH_find(struct HASH_table *t, const char *s);
+void HASH_replace(struct HASH_table *t, const char *s, int key);
+void HASH_add(struct HASH_table *t, const char *s, int key);
+
 #ifdef _MSC_VER
 #pragma pack()
 #endif
diff --git a/polymer/build/src/engine.c b/polymer/build/src/engine.c
index 66b967e17..d08c0ee59 100644
--- a/polymer/build/src/engine.c
+++ b/polymer/build/src/engine.c
@@ -12163,6 +12163,157 @@ void setpolymost2dview(void)
 #endif
 }
 
+void HASH_init(struct HASH_table *t)
+{
+    HASH_free(t);
+    t->items=Bcalloc(1,t->size * sizeof(struct HASH_item));
+    Bmemset(t->items,0,t->size * sizeof(struct HASH_item));
+}
+
+void HASH_free(struct HASH_table *t)
+{
+    struct HASH_item *cur, *tmp;
+    int i;
+    int num;
+
+    if (t->items==NULL)return;
+//    initprintf("*free\n");
+    i=t->size-1;
+    do
+    {
+        cur=t->items[i];
+        num=0;
+        while (cur)
+        {
+            tmp=cur;
+            cur=cur->next;
+//          initprintf("Free %4d '%s'\n",tmp->key,(tmp->string)?tmp->string:".");
+            Bfree(tmp);
+            num++;
+        }
+//      initprintf("Bucket #%4d: %3d\n",i,num);
+    }
+    while (--i>=0);
+    Bfree(t->items);
+    t->items=0;
+}
+
+inline int HASH_getcode(const char *s)
+{
+    int i=0, fact=1;
+    while (*s)
+    {
+        i+=*s;
+        i+=1<<fact;
+        s++;
+    }
+    return i;
+}
+
+void HASH_add(struct HASH_table *t, const char *s, int key)
+{
+    struct HASH_item *cur, *prev=NULL;
+    int code;
+
+    if (!s)return;
+    if (t->items==NULL) {initprintf("HASH_add: not initalized\n");return;}
+    code=HASH_getcode(s)%t->size;
+    cur=t->items[code];
+
+    if (!cur)
+    {
+        cur=Bcalloc(1,sizeof(struct HASH_item));
+        cur->string=s;
+        cur->key=key;
+        cur->next=NULL;
+        t->items[code]=cur;
+        return;
+    }
+
+    do
+    {
+        if (Bstrcmp(s,cur->string)==0)return;
+        prev=cur;
+        cur=cur->next;
+    }
+    while (cur);
+
+    cur=Bcalloc(1,sizeof(struct HASH_item));
+    cur->string=s;
+    cur->key=key;
+    cur->next=NULL;
+    prev->next=cur;
+}
+
+void HASH_replace(struct HASH_table *t, const char *s, int key)
+{
+    struct HASH_item *cur, *prev=NULL;
+    int code;
+
+    if (t->items==NULL) {initprintf("HASH_add: not initalized\n");return;}
+    code=HASH_getcode(s)%t->size;
+    cur=t->items[code];
+
+    if (!cur)
+    {
+        cur=Bcalloc(1,sizeof(struct HASH_item));
+        cur->string=s;
+        cur->key=key;
+        cur->next=NULL;
+        t->items[code]=cur;
+        return;
+    }
+
+    do
+    {
+        if (Bstrcmp(s,cur->string)==0)
+        {
+            cur->key=key;
+            return;
+        }
+        prev=cur;
+        cur=cur->next;
+    }
+    while (cur);
+
+    cur=Bcalloc(1,sizeof(struct HASH_item));
+    cur->string=s;
+    cur->key=key;
+    cur->next=NULL;
+    prev->next=cur;
+}
+
+int HASH_find(struct HASH_table *t, const char *s)
+{
+    struct HASH_item *cur;
+
+//    initprintf("{");
+    if (t->items==NULL) {initprintf("HASH_findyy: not initalized\n");return -1;}
+    cur=t->items[HASH_getcode(s)%t->size];
+    while (cur)
+    {
+        if (Bstrcmp(s,cur->string)==0)return cur->key;
+        cur=cur->next;
+    }
+//    initprintf("}");
+    return -1;
+}
+
+int HASH_findcase(struct HASH_table *t, const char *s)
+{
+    struct HASH_item *cur;
+
+//    initprintf("{");
+    if (t->items==NULL) {initprintf("HASH_findcase: not initalized\n");return -1;}
+    cur=t->items[HASH_getcode(s)%t->size];
+    while (cur)
+    {
+        if (Bstrcasecmp(s,cur->string)==0)return cur->key;
+        cur=cur->next;
+    }
+//    initprintf("}");
+    return -1;
+}
 
 /*
  * vim:ts=8:
diff --git a/polymer/build/src/osd.c b/polymer/build/src/osd.c
index e32c466b8..d0f92c175 100644
--- a/polymer/build/src/osd.c
+++ b/polymer/build/src/osd.c
@@ -101,6 +101,12 @@ static int  osdtextpal=0;
 /* static int  osdcursorshade=0;
 static int  osdcursorpal=0; */
 
+#define MAXSYMBOLS 256
+
+static symbol_t *osdsymbptrs[MAXSYMBOLS];
+static int osdnumsymbols = 0;
+static struct HASH_table osdsymbolsH    = { MAXSYMBOLS, NULL };
+
 // application callbacks
 static void (*drawosdchar)(int, int, char, int, int) = _internal_drawosdchar;
 static void (*drawosdstr)(int, int, char*, int, int, int) = _internal_drawosdstr;
@@ -617,6 +623,8 @@ void OSD_Cleanup(void)
 {
     symbol_t *s;
 
+    HASH_free(&osdsymbolsH);
+
     for (; symbols; symbols=s)
     {
         s=symbols->next;
@@ -637,6 +645,12 @@ void OSD_Init(void)
 {
     Bmemset(osdtext, 32, TEXTSIZE);
     Bmemset(osdfmt, osdtextpal+(osdtextshade<<5), TEXTSIZE);
+    Bmemset(osdsymbptrs, 0, sizeof(osdsymbptrs));
+
+    osdnumsymbols = 0;
+
+    HASH_init(&osdsymbolsH);
+
     osdlines=1;
 
     osdinited=1;
@@ -1764,10 +1778,12 @@ void OSD_SetVersionString(const char *version, int shade, int pal)
 // addnewsymbol() -- Allocates space for a new symbol and attaches it
 //   appropriately to the lists, sorted.
 //
+
 static symbol_t *addnewsymbol(const char *name)
 {
     symbol_t *newsymb, *s, *t;
 
+    if (osdnumsymbols >= MAXSYMBOLS) return NULL;
     newsymb = (symbol_t *)Bmalloc(sizeof(symbol_t));
     if (!newsymb) { return NULL; }
     Bmemset(newsymb, 0, sizeof(symbol_t));
@@ -1798,7 +1814,8 @@ static symbol_t *addnewsymbol(const char *name)
             newsymb->next = t;
         }
     }
-
+    HASH_add(&osdsymbolsH,name,osdnumsymbols);
+    osdsymbptrs[osdnumsymbols++] = newsymb;
     return newsymb;
 }
 
@@ -1823,14 +1840,12 @@ static symbol_t *findsymbol(const char *name, symbol_t *startingat)
 //
 static symbol_t *findexactsymbol(const char *name)
 {
-    symbol_t *startingat;
+    int symb;
     if (!symbols) return NULL;
 
-    startingat = symbols;
-
-    for (; startingat; startingat=startingat->next)
-        if (startingat->func != (void *)OSD_UNALIASED && !Bstrcasecmp(name, startingat->name)) return startingat;
-
+    symb = HASH_find(&osdsymbolsH,name);
+    if (symb > -1)
+        return osdsymbptrs[symb];
     return NULL;
 }
 
diff --git a/polymer/eduke32/source/duke3d.h b/polymer/eduke32/source/duke3d.h
index 4428dddac..16b56db7e 100644
--- a/polymer/eduke32/source/duke3d.h
+++ b/polymer/eduke32/source/duke3d.h
@@ -1060,26 +1060,6 @@ extern char *mousenames[];
 extern char *duke3dgrp, *duke3dgrpstring;
 extern char mod_dir[BMAX_PATH];
 
-// Hash functions
-struct HASH_item // size is 12/24 bits.
-{
-    const char *string;
-    int key;
-    struct HASH_item *next;
-};
-
-struct HASH_table
-{
-    int size;
-    struct HASH_item **items;
-};
-void HASH_init(struct HASH_table *t);
-void HASH_free(struct HASH_table *t);
-int  HASH_findcase(struct HASH_table *t, const char *s);
-int  HASH_find(struct HASH_table *t, const char *s);
-void HASH_replace(struct HASH_table *t, const char *s, int key);
-void HASH_add(struct HASH_table *t, const char *s, int key);
-
 struct HASH_table gamevarH;
 struct HASH_table arrayH;
 struct HASH_table keywH;
diff --git a/polymer/eduke32/source/gamedef.c b/polymer/eduke32/source/gamedef.c
index 0d4aec44d..e53436932 100644
--- a/polymer/eduke32/source/gamedef.c
+++ b/polymer/eduke32/source/gamedef.c
@@ -942,172 +942,21 @@ int  HASH_find(struct HASH_table *t, const char *s);
 void HASH_replace(struct HASH_table *t, const char *s, int key);
 void HASH_add(struct HASH_table *t, const char *s, int key);
 */
-void HASH_init(struct HASH_table *t)
-{
-    HASH_free(t);
-    t->items=Bcalloc(1,t->size * sizeof(struct HASH_item));
-    Bmemset(t->items,0,t->size * sizeof(struct HASH_item));
-}
 
-void HASH_free(struct HASH_table *t)
-{
-    struct HASH_item *cur, *tmp;
-    int i;
-    int num;
+struct HASH_table gamevarH    = { MAXGAMEVARS, NULL };
+struct HASH_table arrayH      = { MAXGAMEARRAYS, NULL };
+struct HASH_table labelH      = { 11264, NULL };
+struct HASH_table keywH       = { CON_END, NULL };
 
-    if (t->items==NULL)return;
-    initprintf("*free\n");
-    i=t->size-1;
-    do
-    {
-        cur=t->items[i];
-        num=0;
-        while (cur)
-        {
-            tmp=cur;
-            cur=cur->next;
-//          initprintf("Free %4d '%s'\n",tmp->key,(tmp->string)?tmp->string:".");
-            Bfree(tmp);
-            num++;
-        }
-//      initprintf("Bucket #%4d: %3d\n",i,num);
-    }
-    while (--i>=0);
-    Bfree(t->items);
-    t->items=0;
-}
+struct HASH_table sectorH     = { SECTOR_END, NULL };
+struct HASH_table wallH       = { WALL_END, NULL };
+struct HASH_table userdefH    = { USERDEFS_END, NULL };
 
-inline int HASH_getcode(const char *s)
-{
-    int i=0, fact=1;
-    while (*s)
-    {
-        i+=*s;
-        i+=1<<fact;
-        s++;
-    }
-    return i;
-}
-
-void HASH_add(struct HASH_table *t, const char *s, int key)
-{
-    struct HASH_item *cur, *prev=NULL;
-    int code;
-
-    if (!s)return;
-    if (t->items==NULL) {initprintf("HASH_add: not initalized\n");return;}
-    code=HASH_getcode(s)%t->size;
-    cur=t->items[code];
-
-    if (!cur)
-    {
-        cur=Bcalloc(1,sizeof(struct HASH_item));
-        cur->string=s;
-        cur->key=key;
-        cur->next=NULL;
-        t->items[code]=cur;
-        return;
-    }
-
-    do
-    {
-        if (Bstrcmp(s,cur->string)==0)return;
-        prev=cur;
-        cur=cur->next;
-    }
-    while (cur);
-
-    cur=Bcalloc(1,sizeof(struct HASH_item));
-    cur->string=s;
-    cur->key=key;
-    cur->next=NULL;
-    prev->next=cur;
-}
-
-void HASH_replace(struct HASH_table *t, const char *s, int key)
-{
-    struct HASH_item *cur, *prev=NULL;
-    int code;
-
-    if (t->items==NULL) {initprintf("HASH_add: not initalized\n");return;}
-    code=HASH_getcode(s)%t->size;
-    cur=t->items[code];
-
-    if (!cur)
-    {
-        cur=Bcalloc(1,sizeof(struct HASH_item));
-        cur->string=s;
-        cur->key=key;
-        cur->next=NULL;
-        t->items[code]=cur;
-        return;
-    }
-
-    do
-    {
-        if (Bstrcmp(s,cur->string)==0)
-        {
-            cur->key=key;
-            return;
-        }
-        prev=cur;
-        cur=cur->next;
-    }
-    while (cur);
-
-    cur=Bcalloc(1,sizeof(struct HASH_item));
-    cur->string=s;
-    cur->key=key;
-    cur->next=NULL;
-    prev->next=cur;
-}
-
-int HASH_find(struct HASH_table *t, const char *s)
-{
-    struct HASH_item *cur;
-
-//    initprintf("{");
-    if (t->items==NULL) {initprintf("HASH_findyy: not initalized\n");return -1;}
-    cur=t->items[HASH_getcode(s)%t->size];
-    while (cur)
-    {
-        if (Bstrcmp(s,cur->string)==0)return cur->key;
-        cur=cur->next;
-    }
-//    initprintf("}");
-    return -1;
-}
-
-int HASH_findcase(struct HASH_table *t, const char *s)
-{
-    struct HASH_item *cur;
-
-//    initprintf("{");
-    if (t->items==NULL) {initprintf("HASH_findcase: not initalized\n");return -1;}
-    cur=t->items[HASH_getcode(s)%t->size];
-    while (cur)
-    {
-        if (Bstrcasecmp(s,cur->string)==0)return cur->key;
-        cur=cur->next;
-    }
-//    initprintf("}");
-    return -1;
-}
-
-struct HASH_table gamevarH    ={8096,NULL};
-struct HASH_table arrayH      ={2096,NULL};
-struct HASH_table labelH      ={8096,NULL};
-struct HASH_table keywH       ={ 800,NULL};
-
-struct HASH_table sectorH     ={ 200,NULL};
-struct HASH_table wallH       ={ 200,NULL};
-struct HASH_table userdefH    ={ 200,NULL};
-
-struct HASH_table projectileH ={ 500,NULL};
-struct HASH_table playerH     ={ 500,NULL};
-struct HASH_table inputH      ={ 100,NULL};
-struct HASH_table actorH      ={ 500,NULL};
-struct HASH_table tspriteH    ={ 400,NULL};
+struct HASH_table projectileH = { PROJ_END, NULL };
+struct HASH_table playerH     = { PLAYER_END, NULL };
+struct HASH_table inputH      = { INPUT_END, NULL };
+struct HASH_table actorH      = { ACTOR_END, NULL };
+struct HASH_table tspriteH    = { ACTOR_END, NULL };
 
 void inithash()
 {
@@ -1147,6 +996,7 @@ void inithash()
     for (i=0;tsprlabels[i].lId >=0 ; i++)
         HASH_add(&tspriteH,tsprlabels[i].name,i);
 }
+
 void freehash()
 {
     HASH_free(&gamevarH);
diff --git a/polymer/eduke32/source/gamedef.h b/polymer/eduke32/source/gamedef.h
index 487b6a4e9..7b9a65c5f 100644
--- a/polymer/eduke32/source/gamedef.h
+++ b/polymer/eduke32/source/gamedef.h
@@ -248,7 +248,8 @@ enum playerlabels
     PLAYER_TEAM,
     PLAYER_MAX_PLAYER_HEALTH,
     PLAYER_MAX_SHIELD_AMOUNT,
-    PLAYER_MAX_AMMO_AMOUNT
+    PLAYER_MAX_AMMO_AMOUNT,
+    PLAYER_END
 };
 
 enum userdefslabels
@@ -344,7 +345,8 @@ enum userdefslabels
     USERDEFS_LEVELSTATS,
     USERDEFS_CROSSHAIRSCALE,
     USERDEFS_ALTHUD,
-    USERDEFS_DISPLAY_BONUS_SCREEN
+    USERDEFS_DISPLAY_BONUS_SCREEN,
+    USERDEFS_END
 };
 
 enum sectorlabels
@@ -371,7 +373,8 @@ enum sectorlabels
     SECTOR_ALIGNTO,
     SECTOR_LOTAG,
     SECTOR_HITAG,
-    SECTOR_EXTRA
+    SECTOR_EXTRA,
+    SECTOR_END
 };
 
 enum walllabels
@@ -392,7 +395,8 @@ enum walllabels
     WALL_YPANNING,
     WALL_LOTAG,
     WALL_HITAG,
-    WALL_EXTRA
+    WALL_EXTRA,
+    WALL_END
 };
 
 enum actorlabels
@@ -448,6 +452,7 @@ enum actorlabels
     ACTOR_XPANNING,
     ACTOR_YPANNING,
     ACTOR_HTFLAGS,
+    ACTOR_END
 };
 
 enum inputlabels
@@ -457,7 +462,8 @@ enum inputlabels
     INPUT_FVEL,
     INPUT_SVEL,
     INPUT_BITS,
-    INPUT_EXTBITS
+    INPUT_EXTBITS,
+    INPUT_END
 };
 
 enum projectilelabels
@@ -489,7 +495,8 @@ enum projectilelabels
     PROJ_OFFSET,
     PROJ_BOUNCES,
     PROJ_BSOUND,
-    PROJ_RANGE // 28
+    PROJ_RANGE, // 28
+    PROJ_END
 };
 
 enum keywords
@@ -831,4 +838,5 @@ enum keywords
     CON_SETGAMEPALETTE,     // 334
     CON_SETDEFNAME,         // 335
     CON_SETCFGNAME,         // 336
+    CON_END
 };