diff --git a/sourcepawn/compiler/sc.h b/sourcepawn/compiler/sc.h
index ecd01dd0..ffac5b94 100644
--- a/sourcepawn/compiler/sc.h
+++ b/sourcepawn/compiler/sc.h
@@ -567,9 +567,13 @@ SC_FUNC char *itoh(ucell val);
 SC_FUNC int check_userop(void (*oper)(void),int tag1,int tag2,int numparam,
                          value *lval,int *resulttag);
 SC_FUNC int matchtag(int formaltag,int actualtag,int allowcoerce);
+SC_FUNC int checktag(int tags[],int numtags,int exprtag);
 SC_FUNC int expression(cell *val,int *tag,symbol **symptr,int chkfuncresult);
 SC_FUNC int sc_getstateid(constvalue **automaton,constvalue **state);
 SC_FUNC cell array_totalsize(symbol *sym);
+SC_FUNC int matchtag_string(int ident, int tag);
+SC_FUNC int checktag_string(value *sym1, value *sym2);
+SC_FUNC int checktags_string(int tags[], int numtags, value *sym1);
 
 /* function prototypes in SC4.C */
 SC_FUNC void writeleader(symbol *root);
@@ -809,6 +813,7 @@ SC_VDECL int sc_curstates;    /* ID of the current state list */
 SC_VDECL int pc_optimize;     /* (peephole) optimization level */
 SC_VDECL int pc_memflags;     /* special flags for the stack/heap usage */
 SC_VDECL int pc_functag;      /* global function tag */
+SC_VDECL int pc_tag_string;   /* global string tag */
 
 SC_VDECL constvalue sc_automaton_tab; /* automaton table */
 SC_VDECL constvalue sc_state_tab;     /* state table */
diff --git a/sourcepawn/compiler/sc1.c b/sourcepawn/compiler/sc1.c
index 0188be0f..58d657b1 100644
--- a/sourcepawn/compiler/sc1.c
+++ b/sourcepawn/compiler/sc1.c
@@ -71,6 +71,7 @@
 #define VERSION_INT 0x0302
 
 int pc_functag = 0;
+int pc_tag_string = 0;
 
 static void resetglobals(void);
 static void initglobals(void);
@@ -683,7 +684,7 @@ static void initglobals(void)
   verbosity=1;          /* verbosity level, no copyright banner */
   sc_debug=sCHKBOUNDS|sSYMBOLIC;   /* sourcemod: full debug stuff */
   pc_optimize=sOPTIMIZE_DEFAULT;   /* sourcemod: full optimization */
-  sc_packstr=FALSE;     /* strings are unpacked by default */
+  sc_packstr=TRUE;     /* strings are packed by default */
   sc_compress=FALSE;	/* always disable compact encoding! */
   sc_needsemicolon=FALSE;/* semicolon required to terminate expressions? */
   sc_dataalign=sizeof(cell);
@@ -1248,6 +1249,7 @@ static void setconstants(void)
   append_constval(&tagname_tab,"_",0,0);/* "untagged" */
   append_constval(&tagname_tab,"bool",1,0);
   pc_functag = pc_addfunctag("Function");
+  pc_tag_string = pc_addtag("String");
 
   add_constant("true",1,sGLOBAL,1);     /* boolean flags */
   add_constant("false",0,sGLOBAL,1);
@@ -1731,6 +1733,8 @@ static void declglb(char *firstname,int firsttag,int fpublic,int fstatic,int fst
 #endif
       dim[numdim++]=(int)size;
     } /* while */
+    if (ident == iARRAY && tag == pc_tag_string)
+      dim[numdim-1] = (size + sizeof(cell)-1) / sizeof(cell);
     assert(sc_curstates==0);
     sc_curstates=getstates(name);
     if (sc_curstates<0) {
@@ -1989,6 +1993,9 @@ static int declloc(int fstatic)
         #endif
         dim[numdim++]=(int)size;
       } while (matchtoken('['));
+      /* Change the last dimension to be based on chars instead if we have a string */
+      if (tag == pc_tag_string)
+        dim[numdim-1] = (size + sizeof(cell)-1) / sizeof(cell);
     } else if (matchtoken('(')) {
       int dim_ident;
       symbol *dim_sym;
@@ -2072,10 +2079,11 @@ static int declloc(int fstatic)
         /* simple variable, also supports initialization */
         int ctag = tag;         /* set to "tag" by default */
         int explicit_init=FALSE;/* is the variable explicitly initialized? */
+        int cident=ident;
         if (matchtoken('=')) {
           if (!autozero)
             error(10);
-          doexpr(FALSE,FALSE,FALSE,FALSE,&ctag,NULL,TRUE);
+          cident=doexpr(FALSE,FALSE,FALSE,FALSE,&ctag,NULL,TRUE);
           explicit_init=TRUE;
         } else {
           if (autozero)
@@ -2094,7 +2102,7 @@ static int declloc(int fstatic)
         assert(staging);        /* end staging phase (optimize expression) */
         stgout(staging_start);
         stgset(FALSE);
-        if (!matchtag(tag,ctag,TRUE))
+        if (!matchtag_string(cident, ctag) && !matchtag(tag,ctag,TRUE))
           error(213);           /* tag mismatch */
         /* if the variable was not explicitly initialized, reset the
          * "uWRITTEN" flag that store() set */
@@ -2501,7 +2509,7 @@ static cell init(int ident,int *tag,int *errorfound)
       error(6);         /* must be assigned to an array */
       litidx=1;         /* reset literal queue */
     } /* if */
-    *tag=0;
+    *tag=pc_tag_string;
   } else if (constexpr(&i,tag,NULL)){
     litadd(i);          /* store expression result in literal table */
   } else {
@@ -2702,6 +2710,7 @@ static void dofuncenum(void)
 				}
 				if (matchtoken('['))
 				{
+					cell size;
 					if (arg->ident == iREFERENCE)
 					{
 						error(67, str);
@@ -2709,7 +2718,6 @@ static void dofuncenum(void)
 					do 
 					{
 						constvalue *enumroot;
-						cell size;
 						int ignore_tag;
 						if (arg->dimcount == sDIMEN_MAX)
 						{
@@ -2720,6 +2728,11 @@ static void dofuncenum(void)
 						arg->dims[arg->dimcount] = size;
 						arg->dimcount += 1;
 					} while (matchtoken('['));
+					/* Handle strings */
+					if (arg->tagcount == 1 && arg->tags[0] == pc_tag_string)
+					{
+						arg->dims[arg->dimcount-1] = (size + sizeof(cell)-1) / sizeof(cell);
+					}
 					arg->ident=iREFARRAY;
 				} else if (arg->ident == 0) {
 					arg->ident = iVARIABLE;
@@ -2850,6 +2863,7 @@ static void decl_enum(int vclass)
       constexpr(&size,&fieldtag,NULL);  /* get size */
       needtoken(']');
     } /* if */
+    /* :TODO: do we need a size modifier here for pc_tag_string? */
     if (matchtoken('='))
       constexpr(&value,NULL,NULL);      /* get value */
     /* add_constant() checks whether a variable (global or local) or
@@ -3355,6 +3369,9 @@ static void funcstub(int fnative)
     dim[numdim++]=(int)size;
   } /* while */
 
+  if (tag == pc_tag_string)
+    dim[numdim-1] = (size + sizeof(cell)-1) / sizeof(cell);
+
   tok=lex(&val,&str);
   fpublic=(tok==tPUBLIC) || (tok==tSYMBOL && str[0]==PUBLIC_CHAR);
   if (fnative) {
@@ -3933,6 +3950,8 @@ static void doarg(char *name,int ident,int offset,int tags[],int numtags,
       arg->numdim+=1;
     } while (matchtoken('['));
     ident=iREFARRAY;            /* "reference to array" (is a pointer) */
+    if (checktag(tags, numtags, pc_tag_string))
+      arg->dim[arg->numdim - 1] = (size + sizeof(cell) - 1) / sizeof(cell);
     if (matchtoken('=')) {
       lexpush();                /* initials() needs the "=" token again */
       assert(litidx==0);        /* at the start of a function, this is reset */
@@ -5682,7 +5701,7 @@ static void doreturn(void)
     rettype|=uRETVALUE;                 /* function returns a value */
     /* check tagname with function tagname */
     assert(curfunc!=NULL);
-    if (!matchtag(curfunc->tag,tag,TRUE))
+    if (!matchtag_string(ident, tag) && !matchtag(curfunc->tag,tag,TRUE))
       error(213);                       /* tagname mismatch */
     if (ident==iARRAY || ident==iREFARRAY) {
       int dim[sDIMEN_MAX],numdim;
diff --git a/sourcepawn/compiler/sc2.c b/sourcepawn/compiler/sc2.c
index 93576701..a65e684f 100644
--- a/sourcepawn/compiler/sc2.c
+++ b/sourcepawn/compiler/sc2.c
@@ -1795,7 +1795,7 @@ static const unsigned char *packedstring(const unsigned char *lptr,int flags)
   int i;
   ucell val,c;
 
-  i=sizeof(ucell)-(sCHARBITS/8); /* start at most significant byte */
+  i=0; /* start at least significant byte */
   val=0;
   while (*lptr!='\"' && *lptr!='\0') {
     if (*lptr=='\a') {          /* ignore '\a' (which was inserted at a line concatenation) */
@@ -1806,14 +1806,16 @@ static const unsigned char *packedstring(const unsigned char *lptr,int flags)
     if (c>=(ucell)(1 << sCHARBITS))
       error(43);                /* character constant exceeds range */
     val |= (c << 8*i);
-    if (i==0) {
+    if (i==sizeof(ucell)-(sCHARBITS/8)) {
       litadd(val);
       val=0;
-    } /* if */
-    i=(i+sizeof(ucell)-(sCHARBITS/8)) % sizeof(ucell);
+      i=0;
+    } else {
+      i=i+1;
+    }
   } /* if */
   /* save last code; make sure there is at least one terminating zero character */
-  if (i!=(int)(sizeof(ucell)-(sCHARBITS/8)))
+  if (i!=0)
     litadd(val);        /* at least one zero character in "val" */
   else
     litadd(0);          /* add full cell of zeros */
@@ -1875,7 +1877,7 @@ char *sc_tokens[] = {
          "*=", "/=", "%=", "+=", "-=", "<<=", ">>>=", ">>=", "&=", "^=", "|=",
          "||", "&&", "==", "!=", "<=", ">=", "<<", ">>>", ">>", "++", "--",
          "...", "..", "::",
-         "assert", "*begin", "break", "case", "char", "const", "continue", "default",
+         "assert", "*begin", "break", "case", "chars", "const", "continue", "default",
          "defined", "do", "else", "*end", "enum", "exit", "for", "forward", "funcenum", "goto",
          "if", "native", "new", "decl", "operator", "public", "return", "sizeof",
          "sleep", "state", "static", "stock", "switch", "tagof", "*then", "while",
@@ -2008,6 +2010,7 @@ SC_FUNC int lex(cell *lexvalue,char **lexsym)
     lptr+=1;            /* skip double quote */
     if ((stringflags & RAWMODE)!=0)
       lptr+=1;          /* skip "escape" character too */
+    /* Note that this should always be packedstring() for SourcePawn */
     lptr=sc_packstr ? packedstring(lptr,stringflags) : unpackedstring(lptr,stringflags);
     if (*lptr=='\"')
       lptr+=1;          /* skip final quote */
diff --git a/sourcepawn/compiler/sc3.c b/sourcepawn/compiler/sc3.c
index 4e7e47a6..a0a37657 100644
--- a/sourcepawn/compiler/sc3.c
+++ b/sourcepawn/compiler/sc3.c
@@ -282,6 +282,44 @@ static void (*unopers[])(void) = { lneg, neg, user_inc, user_dec };
   return TRUE;
 }
 
+SC_FUNC int checktags_string(int tags[], int numtags, value *sym1)
+{
+  int i;
+  if (sym1->ident == iARRAY || sym1->ident == iREFARRAY)
+  {
+    return FALSE;
+  }
+  for (i=0; i<numtags; i++) {
+    if ((sym1->tag == pc_tag_string && tags[i] == 0) ||
+		(sym1->tag == 0 && tags[i] == pc_tag_string))
+      return TRUE;
+  }
+  return FALSE;
+}
+
+SC_FUNC int checktag_string(value *sym1, value *sym2)
+{
+  if (sym1->ident == iARRAY || sym2->ident == iARRAY
+	  || sym1->ident == iREFARRAY || sym2->ident == iREFARRAY)
+  {
+    return FALSE;
+  }
+  if ((sym1->tag == pc_tag_string && sym2->tag == 0)
+	  || (sym1->tag == 0 && sym2->tag == pc_tag_string))
+  {
+    return TRUE;
+  }
+
+  return FALSE;
+}
+
+SC_FUNC int matchtag_string(int ident, int tag)
+{
+  if (ident == iARRAY || ident == iREFARRAY)
+    return FALSE;
+  return (tag == pc_tag_string) ? TRUE : FALSE;
+}
+
 SC_FUNC int matchtag(int formaltag,int actualtag,int allowcoerce)
 {
   if (formaltag!=actualtag) {
@@ -781,7 +819,7 @@ static void plnge2(void (*oper)(void),
         error(213);             /* tagname mismatch */
       lval1->constval=calc(lval1->constval,oper,lval2->constval,&lval1->boolresult);
     } else {
-      if (!matchtag(lval1->tag,lval2->tag,FALSE))
+      if (!checktag_string(lval1, lval2) && !matchtag(lval1->tag,lval2->tag,FALSE))
         error(213);             /* tagname mismatch */
       (*oper)();                /* do the (signed) operation */
       lval1->ident=iEXPRESSION;
@@ -1205,7 +1243,7 @@ static int hier14(value *lval1)
     check_userop(NULL,lval2.tag,lval3.tag,2,&lval3,&lval2.tag);
     store(&lval3);      /* now, store the expression result */
   } /* if */
-  if (!oper && !matchtag(lval3.tag,lval2.tag,TRUE))
+  if (!oper && !checktag_string(&lval3, &lval2) && !matchtag(lval3.tag,lval2.tag,TRUE))
     error(213);         /* tagname mismatch (if "oper", warning already given in plunge2()) */
   if (lval3.sym)
     markusage(lval3.sym,uWRITTEN);
@@ -1658,6 +1696,10 @@ static int hier2(value *lval)
           popreg(sPRI);         /* restore PRI (result of rvalue()) */
         sideeffect=TRUE;
         return FALSE;
+/* This is temporarily disabled because we detect it automatically.
+ * Thus, it could be weird if both were used at once
+ */
+#if 0
       case tCHAR:               /* char (compute required # of cells */
         if (lval->ident==iCONSTEXPR) {
           lval->constval *= sCHARBITS/8;  /* from char to bytes */
@@ -1670,6 +1712,7 @@ static int hier2(value *lval)
           addr2cell();          /* truncate to number of cells */
         } /* if */
         return FALSE;
+#endif
       default:
         lexpush();
         return lvalue;
@@ -1745,7 +1788,7 @@ restart:
           assert(sym->dim.array.level>=0 && sym->dim.array.level<sDIMEN_MAX);
           lval1->arrayidx[sym->dim.array.level]=lval2.constval;
         } /* if */
-        if (close==']') {
+        if (close==']' && !(sym->tag == pc_tag_string && sym->dim.array.level == 0)) {
           /* normal array index */
           if (lval2.constval<0 || sym->dim.array.length!=0 && sym->dim.array.length<=lval2.constval)
             error(32,sym->name);        /* array index out of bounds */
@@ -1826,7 +1869,11 @@ restart:
       } /* if */
       assert(sym->dim.array.level==0);
       /* set type to fetch... INDIRECTLY */
-      lval1->ident= (char)((close==']') ? iARRAYCELL : iARRAYCHAR);
+      if (sym->tag == pc_tag_string) {
+        lval1->ident = iARRAYCHAR;
+      } else {
+        lval1->ident= (char)((close==']') ? iARRAYCELL : iARRAYCHAR);
+      }
       /* if the array index is a field from an enumeration, get the tag name
        * from the field and save the size of the field too. Otherwise, the
        * tag is the one from the array symbol.
@@ -2105,7 +2152,7 @@ static int findnamedarg(arginfo *arg,char *name)
   return -1;
 }
 
-static int checktag(int tags[],int numtags,int exprtag)
+int checktag(int tags[],int numtags,int exprtag)
 {
   int i;
 
@@ -2281,12 +2328,8 @@ static int nesting=0;
               heapalloc+=markheap(MEMUSE_STATIC, 1);
               nest_stkusage++;
             } /* if */
-          } else if (lval.ident==iCONSTEXPR || lval.ident==iEXPRESSION
-                     || lval.ident==iARRAYCHAR)
+          } else if (lval.ident==iCONSTEXPR || lval.ident==iEXPRESSION)
           {
-            /* fetch value if needed */
-            if (lval.ident==iARRAYCHAR)
-              rvalue(&lval);
             /* allocate a cell on the heap and store the
              * value (already in PRI) there */
             setheap_pri();        /* address of the value on the heap in PRI */
@@ -2297,7 +2340,8 @@ static int nesting=0;
           /* otherwise, the address is already in PRI */
           if (lval.sym!=NULL)
             markusage(lval.sym,uWRITTEN);
-          if (!checktag(arg[argidx].tags,arg[argidx].numtags,lval.tag))
+          if (!checktags_string(arg[argidx].tags, arg[argidx].numtags, &lval)
+              && !checktag(arg[argidx].tags,arg[argidx].numtags,lval.tag))
             error(213);
           if (lval.tag!=0)
             append_constval(&taglst,arg[argidx].name,lval.tag,0);
@@ -2311,14 +2355,15 @@ static int nesting=0;
           /* otherwise, the expression result is already in PRI */
           assert(arg[argidx].numtags>0);
           check_userop(NULL,lval.tag,arg[argidx].tags[0],2,NULL,&lval.tag);
-          if (!checktag(arg[argidx].tags,arg[argidx].numtags,lval.tag))
+          if (!checktags_string(arg[argidx].tags, arg[argidx].numtags, &lval)
+              && !checktag(arg[argidx].tags,arg[argidx].numtags,lval.tag))
             error(213);
           if (lval.tag!=0)
             append_constval(&taglst,arg[argidx].name,lval.tag,0);
           argidx++;               /* argument done */
           break;
         case iREFERENCE:
-          if (!lvalue || lval.ident==iARRAYCHAR)
+          if (!lvalue)
             error(35,argidx+1);   /* argument type mismatch */
           if (lval.sym!=NULL && (lval.sym->usage & uCONST)!=0 && (arg[argidx].usage & uCONST)==0)
             error(35,argidx+1);   /* argument type mismatch */
@@ -2343,7 +2388,7 @@ static int nesting=0;
           break;
         case iREFARRAY:
           if (lval.ident!=iARRAY && lval.ident!=iREFARRAY
-              && lval.ident!=iARRAYCELL)
+              && lval.ident!=iARRAYCELL && lval.ident!=iARRAYCHAR)
           {
             error(35,argidx+1);   /* argument type mismatch */
             break;
@@ -2354,7 +2399,7 @@ static int nesting=0;
            * A literal array always has a single dimension.
            * An iARRAYCELL parameter is also assumed to have a single dimension.
            */
-          if (lval.sym==NULL || lval.ident==iARRAYCELL) {
+          if (lval.sym==NULL || lval.ident==iARRAYCELL || lval.ident==iARRAYCHAR) {
             if (arg[argidx].numdim!=1) {
               error(48);        /* array dimensions must match */
             } else if (arg[argidx].dim[0]!=0) {
@@ -2372,14 +2417,14 @@ static int nesting=0;
                   error(47);      /* array sizes must match */
               } /* if */
             } /* if */
-            if (lval.ident!=iARRAYCELL) {
+            if (lval.ident!=iARRAYCELL && lval.ident!=iARRAYCHAR) {
               /* save array size, for default values with uSIZEOF flag */
               cell array_sz=lval.constval;
               assert(array_sz!=0);/* literal array must have a size */
               if (array_sz<0)
                 array_sz= -array_sz;
               append_constval(&arrayszlst,arg[argidx].name,array_sz,0);
-            } /* if */
+            }/* if */
           } else {
             symbol *sym=lval.sym;
             short level=0;
@@ -2669,6 +2714,7 @@ static int constant(value *lval)
                                  * value distinguishes between literal arrays
                                  * and literal strings (this was done for
                                  * array assignment). */
+	lval->tag=pc_tag_string;
   } else if (tok=='{') {
     int tag,lasttag=-1;
     val=litidx;
diff --git a/sourcepawn/compiler/sc4.c b/sourcepawn/compiler/sc4.c
index ff8045c3..509b4e06 100644
--- a/sourcepawn/compiler/sc4.c
+++ b/sourcepawn/compiler/sc4.c
@@ -961,12 +961,16 @@ SC_FUNC void char2addr(void)
  * The ALIGN.pri/alt instructions must solve this machine dependence;
  * that is, on Big Endian computers, ALIGN.pri/alt shuold do nothing
  * and on Little Endian computers they should toggle the address.
+ *
+ * NOTE: For Source Pawn, this is fliped.  It will do nothing on Little-Endian.
  */
 SC_FUNC void charalign(void)
 {
+#if 0	/* TEMPORARILY DISABLED BECAUSE WE DON'T USE BIG ENDIAN */
   stgwrite("\talign.pri ");
   outval(sCHARBITS/8,TRUE);
   code_idx+=opcodes(1)+opargs(1);
+#endif
 }
 
 /*