diff --git a/xtrn/war/convert_game.js b/xtrn/war/convert_game.js
new file mode 100644
index 0000000000000000000000000000000000000000..3c3a14a8ed41cdd5c04d5dd94c9546f051773fa0
--- /dev/null
+++ b/xtrn/war/convert_game.js
@@ -0,0 +1,282 @@
+var game={
+	ncnt:0,
+	nations:[],
+	cities:[],
+	ttypes:[],
+	armies:[],
+	move_table:[]
+};
+
+var fp;
+var inbuf='';
+var p='';
+var cnt, ttcnt, acnt, mcnt, nt, i, j;
+var nbytes;
+var a_nation, a_r, a_c, a_combat, a_hero,
+	a_move_rate, a_move_tbl, a_special_mv, a_eparm1;
+
+/* initialize armies table */
+game.armies=[];
+
+/* open the game save */
+
+fp = new File(js.exec_dir+'/'+'game.orig');
+if(!fp.open("rb")) {
+	alert("Unable to open "+fp.name);
+	exit(1);
+}
+
+if((inbuf = fp.readln())==null) {
+	fp.close();
+	alert("Unable to read first line of "+fp.name);
+	exit(1);
+}
+
+if(inbuf.substr(0,2) != 'G ') {
+	fp.close();
+	alert("Invalid Header in "+fp.name);
+	exit(1);
+}
+
+cnt = ttcnt = acnt = mcnt = -1;
+
+gen = 0;
+
+game.world = '';
+
+m=inbuf.match(/^G ([0-9]+) ([0-9]+) ([0-9]+) ([0-9]+) ([0-9]+) g([0-9]+) ([^\s]{0,40})\s*$/);
+if(m==null) {
+	fp.close();
+	alert("Invalid header in "+fp.name);
+	exit(1);
+}
+game.ncnt=parseInt(m[1],10);
+cnt=parseInt(m[2],10);
+ttcnt=parseInt(m[3],10);
+acnt=parseInt(m[4],10);
+mcnt=parseInt(m[5],10);
+game.gen=parseInt(m[6],10);
+game.world=m[7];
+
+game.world=game.world.replace(/_/g, ' ');
+
+/* load nations table */
+
+if(game.ncnt == 0) {
+	game.ncnt = 1;
+	game.nations[0] = {
+		name:'God',
+		uid:0,
+		city:0,
+		mark:0,
+		idle_turns:0
+	};
+} else {
+	if(fp.readln()==null) {
+		fp.close();
+		alert("Unable to read nation header");
+		exit(1);
+	}
+
+	for(i=0; i<game.ncnt; i++) {
+		if((inbuf = fp.readln())==null) {
+			fp.close();
+			alert("Unable to read nation "+(game.nations.length+1)+" from "+fp.name);
+			exit(1);
+		}
+		if((m=inbuf.match(/^(.*?): U([0-9]+) C([0-9]+) M(.) I([0-9]+)\s*$/))==null) {
+			alert("Unable to parse nation "+(game.nations.length+1)+" from "+fp.name);
+			exit(1);
+		}
+		game.nations[i]={
+			name:m[1],
+			uid:parseInt(m[2], 10),
+			city:parseInt(m[3], 10),
+			mark:"*ABCDEFGHIJKLMNOPQRSTUVWXYZ?".substr(parseInt(m[4], 10), 1),
+			idle_turns:parseInt(m[5], 10)
+		};
+	}
+}
+for(i=game.ncnt; i<27; i++) {
+	game.nations[i] = {
+		name:'',
+		uid:0,
+		city:0,
+		mark:'*',
+		idle_turns:0
+	};
+}
+
+/* set up the Rogue nation */
+
+game.nations[27] = {
+	name:'Rogue',
+	uid:-1,
+	city:0,
+	mark:'?',
+	idle_turns:0
+};
+
+/* load cities table */
+
+for(i = 0; i < cnt; i++) {
+	if(fp.readln()==null) {
+		fp.close();
+		alert("Unable to read city header");
+		exit(1);
+	}
+
+	/* city id line */
+	if((inbuf = fp.readln())==null) {
+		fp.close();
+		alert("Unable to read city "+(game.cities.length+1)+" from "+fp.name);
+		exit(1);
+	}
+
+	if((m=inbuf.match(/^(.*?): C([0-9]+) N([0-9]+) @([0-9]+):([0-9]+) P([0-9]+):([0-9]+) D([0-9]+) T([0-9]+)\s*$/))==null) {
+		fp.close();
+		alert("Unable to parse city "+(game.cities.length+1)+" from "+fp.name);
+		exit(1);
+	}
+
+	game.cities[i] = {
+		name:m[1],
+		cluster:parseInt(m[2], 10),
+		nation:parseInt(m[3], 10),
+		r:parseInt(m[4], 10),
+		c:parseInt(m[5], 10),
+		prod_type:parseInt(m[6], 10),
+		turns_left:parseInt(m[7], 10),
+		defense:parseInt(m[8], 10),
+		ntypes:parseInt(m[9], 10),
+		types:[],
+		times:[],
+		instance:[]
+	};
+
+	/* troop types */
+
+	nt = 0;
+
+	for(j = 0; j < 4; j++) {
+		if((inbuf = fp.readln())==null) {
+			fp.close();
+			alert("Unable to read city "+(game.cities.length+1)+" troop "+(j)+" from "+fp.name);
+			exit(1);
+		}
+		if((m=inbuf.match(/^([-0-9]+) ([-0-9]+) ([-0-9]+)\s*$/))==null) {
+			fp.close();
+			alert("Unable to parse city "+(game.cities.length+1)+" troop "+(j)+" from "+fp.name);
+			exit(1);
+		}
+		game.cities[i].types[j]=parseInt(m[1], 10);
+		game.cities[i].times[j]=parseInt(m[2], 10);
+		game.cities[i].instance[j]=parseInt(m[3], 10);
+
+		if(game.cities[i].types[j] != -1)
+			nt = j + 1;
+	}
+
+	if(game.cities[i].ntypes == -1)
+		game.cities[i].ntypes = nt;
+}
+
+/* load troop types table */
+
+if(fp.readln()==null) {
+	fp.close();
+	alert("Unable to read troop type header");
+	exit(1);
+}
+
+for(i = 0; i < ttcnt; i++) {
+	if((inbuf = fp.readln())==null) {
+		fp.close();
+		alert("Unable to read troop type "+(game.ttypes.length+1)+" from "+fp.name);
+		exit(1);
+	}
+	if((m=inbuf.match(/^(.*?): C([0-9]+) M([0-9]+):([0-9]+):([0-9]+)\s*$/))==null) {
+		fp.close();
+		alert("Unable to parse troop type "+(game.ttypes.length+1)+" from "+fp.name);
+		exit(1);
+	}
+	game.ttypes[i]={
+		name:m[1],
+		combat:parseInt(m[2], 10),
+		move_rate:parseInt(m[3], 10),
+		move_tbl:parseInt(m[4], 10),
+		special_mv:parseInt(m[5], 10),
+	};
+}
+
+/* load armies table */
+
+if(acnt > 0) {
+	if(fp.readln()==null) {
+		fp.close();
+		alert("Unable to read armies header");
+		exit(1);
+	}
+
+	for(i = 0; i < acnt; i++) {
+
+		if((inbuf = fp.readln())==null) {
+			fp.close();
+			alert("Unable to read army type "+(game.armies.length+1)+" from "+fp.name);
+			exit(1);
+		}
+		if((m=inbuf.match(/^(.*?): N([0-9]+) @([0-9]+):([0-9]+) C([0-9]+):([0-9]+) M([0-9]+):([0-9]+) S([0-9]+) L([0-9]+)\s*$/))==null) {
+			fp.close();
+			alert("Unable to parse army type "+(game.armies.length+1)+" from "+fp.name);
+			exit(1);
+		}
+		game.armies[i] = {
+			name:m[1],
+			nation:parseInt(m[2], 10),
+			r:parseInt(m[3], 10),
+			c:parseInt(m[4], 10),
+			combat:parseInt(m[5], 10),
+			hero:parseInt(m[6], 10),
+			move_rate:parseInt(m[7], 10),
+			move_tbl:parseInt(m[8], 10),
+			special_mv:parseInt(m[9], 10),
+			eparm1:parseInt(m[10], 10),
+			move_left:parseInt(m[7], 10),
+		};
+	}
+}
+
+/* load move table */
+
+if(fp.readln()==null) {
+	fp.close();
+	alert("Unable to read move table header");
+	exit(1);
+}
+
+
+for(i = 0; i < mcnt; i++) {
+
+	if((inbuf = fp.readln())==null) {
+		fp.close();
+		alert("Unable to read move table "+(game.move_table.length+1)+" from "+fp.name);
+		exit(1);
+	}
+	if((m=inbuf.match(/^([0-9]+) ([0-9]+) ([0-9]+) ([0-9]+) ([0-9]+)\s*$/))==null) {
+		fp.close();
+		alert("Unable to parse move table "+(game.move_table.length+1)+" from "+fp.name);
+		exit(1);
+	}
+
+	game.move_table[i] = {};
+	game.move_table[i].cost=[];
+	for(j = 0; j < 5; j++)
+		game.move_table[i].cost[j] = parseInt(m[j+1], 10);
+}
+
+fp.close();
+fp=new File(js.exec_dir+'/'+'game.orig.json');
+if(fp.open('wb')) {
+	fp.write(JSON.stringify(game, null, '\t'));
+}
+fp.close();
diff --git a/xtrn/war/docs/Manual b/xtrn/war/docs/Manual
new file mode 100644
index 0000000000000000000000000000000000000000..9e7601f40cf803d77fadd8bb7d66b1b320efc34e
--- /dev/null
+++ b/xtrn/war/docs/Manual
@@ -0,0 +1,108 @@
+
+             S O L O M O R I A H ' S
+
+           X    X    XX    XXXXX    XXX
+           X    X   X  X   X    X   XXX
+           X    X  X    X  X    X   XXX
+           X    X  XXXXXX  XXXXX     X 
+           X XX X  X    X  X   X       
+           XX  XX  X    X  X    X   XXX
+            X  X   X    X  X    X   XXX
+
+
+WAR Version 4.4                       "Code by Solomoriah"
+Copyright 1993, 1994, 2001, 2013 Chris Gonnerman
+All Rights Reserved.
+ 
+
+INTRODUCTION 
+ 
+Two separate doc files are included with WAR!  The one you 
+are reading, Manual, explains how to set up and run the 
+game.  The other file, Rules, explains the user 
+interface and basic game rules.  
+ 
+ 
+GAME SETUP 
+ 
+Since you are reading this file, you have obviously unZIPped 
+the game archive WARPROG.ZIP.  Put all the program files in 
+a directory by themselves.  
+ 
+Several basic game worlds are included with WAR!  A game 
+world is stored in two files: map and game.sav.  map is 
+never changed by the game programs (except WARTOOL), while 
+game.sav will be.  game.sav will be backed up in the form of 
+files named game.000, game.001, etc.  WAR! will clean up 
+(remove) old game save backups when they are five 
+generations out of date.  
+ 
+A third file, master.cmd, is supplied.  Generally you should 
+not tamper with the contents of any files you find in the 
+WAR! directory.  
+ 
+To install a game world, the easiest thing to do is to unZIP 
+the world file (WARSOLO.ZIP, WARALDER.ZIP, or WARROOK.ZIP) 
+in the directory you put the game programs in.  Other 
+arrangements will be explained later under the CONTROL FILES 
+heading.  
+ 
+ 
+PLAYING WAR! STANDALONE 
+ 
+To play WAR! change to the WAR directory and enter the 
+command WAR.  For example, if you installed WAR! in the 
+directory C:\WAR, you would start WAR! as follows: 
+
+    C:\> cd \war
+    C:\WAR> war
+
+When WAR! starts, it will ask you for your UID.  Any number 
+from 1 to 32,768 is legal.  The first time you play a turn 
+in WAR! you will be assigned a home city and asked for the 
+name of your national leader.  You may use any name you 
+like, up to 14 characters in length.  WAR! will then go to 
+the main screen.  See the Rules file for information on 
+actually playing the game.  
+ 
+ 
+RUNNING UPDATES 
+ 
+Running updates is done the same way.  Change to the 
+directory WAR! is installed in and enter the command WARUPD.
+WARUPD sends progress messages to stdout, so you can collect 
+them as follows: 
+
+    C:\WAR> warupd >message.txt
+
+On a BBS system you may want or need to automate the update 
+processing.  Note that WARUPD will run even if someone is 
+actively playing WAR! (I'm still thinking about how to fix 
+that), so you should try to run the updates when no one will 
+be playing the game.  
+ 
+It is recommended for normal BBS game play that updates be 
+run every 24 hours.  
+ 
+ 
+WARNEWS 
+ 
+WARNEWS is a stand-alone news viewer for WAR! It presents 
+the same user interface that the regular WAR program does in 
+newsreader mode.  
+ 
+ 
+WARMAP 
+ 
+WARMAP combines the MAP and GAME.SAV files to create an 
+up-to-date map of the WAR! world.  As with WARUPD, the map 
+is printed to stdout and may be collected in a file as 
+follows: 
+
+    C:\WAR> warmap >file.txt
+
+To print most maps you will need to put your printer in 
+condensed print.  To view the map on the screen you will 
+need a file viewer or editor that can scroll sideways.  The 
+MS-DOS 5 EDIT command can do this.  
+ 
diff --git a/xtrn/war/docs/Rules b/xtrn/war/docs/Rules
new file mode 100644
index 0000000000000000000000000000000000000000..f7e01e3c0420c103af1cce49cbba99c6e5a9bdff
--- /dev/null
+++ b/xtrn/war/docs/Rules
@@ -0,0 +1,246 @@
+
+                S O L O M O R I A H ' S
+
+              X    X    XX    XXXXX    XXX
+              X    X   X  X   X    X   XXX
+              X    X  X    X  X    X   XXX
+              X    X  XXXXXX  XXXXX     X 
+              X XX X  X    X  X   X       
+              XX  XX  X    X  X    X   XXX
+               X  X   X    X  X    X   XXX
+
+    WAR Version 4.4             "Code by Solomoriah"
+    Copyright 1993, 1994, 2001, 2013 Chris Gonnerman
+    All Rights Reserved.
+
+
+Starting the Game:
+
+If you have never played WAR! before, you will be asked for your name 
+and your nation mark.  You may use any name you wish, up to 14 
+characters long.  This name will be used for your national leader (your 
+first hero) and will be shown on status displays.  You do not have to 
+use your real name.
+
+Enter a single exclamation mark (!) in place of the name to try for a 
+different city.
+
+The nation mark is the letter you wish to be used to represent your 
+nation's cities and armies in the game.  (Cities are uppercase, armies 
+are lowercase.)
+
+Next, you will be instructed to press a key to continue.  When you do,
+the following screen will appear:
+
+
+  --------------------------------
+ |                             . .|  ->   Victor (Hero)             8:8
+ |                             . .|       Verdant 1st Lt. Infantry  6:6
+ |     # #                        |
+ | . . . .                        |
+ | . . . .                        |
+ | . . . . % %                    |
+ | . . . % % * % V % %            |
+ | . . ^ * % % % %               ^|
+ | . ^ ^ ^ ^                   ^ ^|
+ | . ^ ^ ^ ^ *         . . % % ^ ^|
+ | % % % % % % # #   . . . % % % ^|
+ | % % % % % % # * # . . . . % % %|
+ | % % % % % % # # # . . . . . % %|
+ | # # % %           . . . . . % %|
+ | # # #             ^ ^ . . . % %|
+ | # # # #             ^ # # % % %|
+  --------------------------------
+  City:  Verdant (Verdant)
+
+  Welcome to Solomoriah's WAR!  Press ? for Help.
+
+(Of course, your screen may show a different city, and you probably 
+will name your hero something other than Victor...)
+
+If you enter the game before the first turn update, you will have your
+hero, your city, and one army.  For each turn after the first that
+passes before you enter the game, you will have an additional army, up
+to the limit of militia production (usually four or six).  This ensures 
+you will not be helpless if you enter the game late.
+
+The map uses the following symbols:
+
+    . Plains     * Neutral City
+    % Forest     ! Battle Zone
+    # Hills
+    ^ Mountains
+
+(Blank space represents water.)
+
+
+Playing WAR!
+
+Your first act upon entering the game will probably be to attack a
+neutral city nearby.  To do so you will need to move your army(s) into
+the city.
+
+Note the pointer (->) beside the hero, Victor, on the screen view
+above.  You use the <j> and <k> keys to move the pointer down or up.
+If you press the <space bar> a * will appear next to the army the
+pointer is pointing at.  (Pressing <space bar> again will remove the
+*.)  You may also press <*> to select all, or </> to unselect all.
+
+Once you have selected your armies, press <m> to move them.  A message
+will appear at the bottom of the screen, as follows:
+
+ Move Army          7 8 9      y k u    SPACE to Stop.
+                    4   6  or  h   l
+                    1 2 3      n j m
+
+The keys shown move your army stack in the corresponding direction.
+Note that if any army you have marked can't make a move, the entire
+stack can't.
+
+Next to each army name in the screen view, you will see a pair of
+numbers separated by a colon.  The first number is the army's maximum
+movement allowance, and the second is the amount remaining.  Note that
+different armies may have different costs for moving through a given 
+space.  Some terrain types may be totally impassable to a given army
+type; for instance, cavalry can't move through mountains, and most
+armies can't cross water.
+
+When you reach the neutral city, note that it will cost 2 movement
+points to enter.  (Entering a hostile city always costs 2 points;
+friendly cities always cost 1 point.)  Once you have entered you will
+see an exclamation point (!) indicating a battle zone.  You may not
+move armies out of a battle zone... so you should then just press
+<space bar> to finish moving.
+
+You may stop an army or an army stack anywhere, not just in a city;
+your remaining movement will still be available in that case.
+
+When the turn update runs, all battles will be resolved.  Note that if
+you attack a player-owned city, and he has moved additional armies
+into the city, the results may not be as you expect.
+
+The reason is, player commands are executed in random order.  The
+nation list is scrambled, then each nation's commands are executed,
+followed by battles.
+
+For instance, say you and your neighbor, both players, go to war.  You
+attack, moving a large army stack into a poorly-defended city.  He
+expects this, and moves a large army stack into the same city to
+defend it.
+
+If his commands execute first, there will be one large battle, as
+your army stack confronts his.  If your commands execute first, you may
+capture his city, only to be crushed when his defensive force arrives.
+
+Players may have as many as twelve armies in a friendly city.
+However, no more than ten armies belonging to a given nation may be in
+any other space, including an enemy city.  Note also that cities give
+a bonus to the combat ratings of friendly units (the defense value).
+
+Heros also give a bonus to friendly units they are grouped with.  Only
+the most powerful hero in a stack grants the stack his bonus.  (Only
+one commander per group.)
+
+
+Changing the View:
+
+The map shows your current group near the center; the cursor will be 
+on the exact spot.  To move the "focus" to another group, use the
+(n)ext and (p)revious commands.
+
+Pressing <n> for next moves the focus to the next group, in map order,
+which you own.  A group consists of a city and/or one or more armies.
+All armies in the group will be displayed in the right-hand column.
+Enemy army counts will be below your armies.  If the focus is on a
+city, the city name and owning nation will be below the map display.
+
+Similarly, <p> for previous moves to the previous group in map order.
+If there are no previous groups (or no more groups for next), a
+message will appear.
+
+You may also press <N> or <P> (capitalized) to move to the very last 
+(for N) or very first (for P) group.
+
+
+Viewing the Map:
+
+You may gain "recon" information about the map around any focus position 
+by entering (i)nformation mode.  While in "info mode" you may move the
+cursor around the screen, to any spot visible.  Notice that the focus
+remains in the same place.
+
+Information about the terrain and armies present in each spot you move the
+cursor over is shown just above the info mode help display, at the bottom
+of the screen.
+
+
+Status Display:
+
+The (s)tatus display shows the names of all nations, their rulers and nation
+marks, and a count of their currently owned cities, armies, and heros.  
+While in status display, you may use (n)ext and (p)revious to view other
+pages, or press ESC to return to the normal display.
+
+
+Drafting Armies:
+
+Each city can produce as many as four different types of units.
+Initially, each city is set up to produce the lowest-ranked unit type
+it can produce.  You can change this for friendly cities by pressing
+<a> for the armies command.  The available unit types will be shown,
+along with the time to produce in parenthesis.  The current type in
+production is also shown, along with the remaining time to produce the
+unit.
+
+If you change unit production, you lose any time spent producing a
+different type.  For instance, if one of your cities is producing Lt.
+Cavalry and needs four turns to produce a unit, and you have only two
+turns left to produce, then changing unit types causes you to lose the
+two turns you have spent already.
+
+Not all cities take the same time to produce the same unit type.  Some
+cities are better at producing certain types.  Also, not all cities
+produce the same types of armies.
+
+
+Transporting Armies:
+
+Certain special army types have the ability to transport other armies.
+For instance, a Navy unit can transport an entire stack of armies over
+water spaces.  There are units able to transport entire stacks, single 
+armies, or single heros.
+
+To use a transporting unit, simply select it along with the units you
+wish to have transported.  When you begin moving the stack, the movement
+costs will be applied to the transporting army.  Armies being carried
+pay a cost of 1 point per space moved through regardless of terrain
+type, and do not have to stop when they reach 0 movement (as long as
+the transporting army can still move).
+
+
+Special Hero Rules:
+
+As previously noted, a hero adds a bonus to all units stacked under him
+(or her).  This bonus, called the Command value, varies from hero to hero.
+
+Heros may make use of hero-transporting armies (such as Hippogryffs) as
+noted above.
+
+When a hero joins your nation, he or she has the movement capability (or
+costs) of the lowest-ranked unit produced in the hero's home city.  For
+most heros, this results in the hero moving like Lt. Infantry.  Elf 
+heros, however, have regular Elf movement (making it easier to move 
+through forests).
+
+
+Reading the News and Mail:
+
+You can read the News by pressing (R).  The News consists of information
+about recent battles (in capsule form), captured cities, etc. of all
+nations.
+
+You can read your Mail by pressing (M).  The results of your military 
+actions will be mailed to you in detail; also, you may receive mail from 
+other national leaders this way.  To send Mail, press (S).  You may enter
+the name of the leader, or the word All to post a message in the News.
+
diff --git a/xtrn/war/war.js b/xtrn/war/war.js
new file mode 100644
index 0000000000000000000000000000000000000000..184d607afcca99c0f4820f03567227547973a963
--- /dev/null
+++ b/xtrn/war/war.js
@@ -0,0 +1,2614 @@
+var game_dir = js.exec_dir;
+/*
+    Solomoriah's WAR!
+
+    war.js -- main procedure file for war user interface
+
+    Copyright 2013 Stephen Hurd
+    All rights reserved.
+
+    3 Clause BSD License
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions
+    are met:
+
+    Redistributions of source code must retain the above copyright
+    notice, self list of conditions and the following disclaimer.
+
+    Redistributions in binary form must reproduce the above copyright
+    notice, self list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+
+    Neither the name of the author nor the names of any contributors
+    may be used to endorse or promote products derived from self software
+    without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+    "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+    FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+    AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+    SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+    LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+    DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+    THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+    OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+
+// Based on:
+/*
+    Solomoriah's WAR!
+
+    war.c -- main procedure file for war user interface
+
+    Copyright 1993, 1994, 2001, 2013 Chris Gonnerman
+    All rights reserved.
+
+    3 Clause BSD License
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions
+    are met:
+
+    Redistributions of source code must retain the above copyright
+    notice, self list of conditions and the following disclaimer.
+
+    Redistributions in binary form must reproduce the above copyright
+    notice, self list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+
+    Neither the name of the author nor the names of any contributors
+    may be used to endorse or promote products derived from self software
+    without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+    "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+    FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+    AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+    SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+    LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+    DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+    THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+    OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+load("sbbsdefs.js");
+load(game_dir+'/warcommon.js');
+
+// From display.c
+const gran = 2;
+const terminate = "\033q ";
+var avcnt = 0;
+var avpnt = 0;
+var enemies = [
+	{nation:0, armies:0, heros:0},
+	{nation:0, armies:0, heros:0}
+];
+var armyview = [
+	{id:0, mark:' '},
+	{id:0, mark:' '},
+	{id:0, mark:' '},
+	{id:0, mark:' '},
+	{id:0, mark:' '},
+	{id:0, mark:' '},
+	{id:0, mark:' '},
+	{id:0, mark:' '},
+	{id:0, mark:' '},
+	{id:0, mark:' '},
+	{id:0, mark:' '},
+	{id:0, mark:' '}
+];
+var mvcnt = 0;
+var movestack = [
+	{ id:0, moved:0, dep:0 },
+	{ id:0, moved:0, dep:0 },
+	{ id:0, moved:0, dep:0 },
+	{ id:0, moved:0, dep:0 },
+	{ id:0, moved:0, dep:0 },
+	{ id:0, moved:0, dep:0 },
+	{ id:0, moved:0, dep:0 },
+	{ id:0, moved:0, dep:0 },
+	{ id:0, moved:0, dep:0 },
+	{ id:0, moved:0, dep:0 }
+];
+
+// These were extern...
+var trans;
+var pfile;
+
+// From data.c
+const terrain = "~.%#^";        /* standard types only. */
+const terr_attr = {
+	' ':'HB4',
+	'~':'HB4',
+	'.':'HY3',
+	'%':'HG2',
+	'#':'NW3',
+	'^':'HW7'
+};
+
+const terr_names = [
+    "Water",
+    "Plains",
+    "Forest",
+    "Hills",
+    "Mountains",
+];
+
+// From reader.c
+var r_index = [];
+var killed=[];
+var index_cnt = 0;
+var pages = [];
+var page_cnt = 0;
+
+function nationname(n)
+{
+    return nations[n].name;
+}
+
+function turn()
+{
+    return gen;
+}
+
+function mainscreen()
+{
+    var i;
+
+    console.clear(7);
+
+	console.gotoxy(2, 1);
+	console.print(ascii(201));
+	console.gotoxy(2, 18);
+	console.print(ascii(200));
+	console.gotoxy(35, 1);
+	console.print(ascii(205)+ascii(187));
+	console.gotoxy(35, 18);
+	console.print(ascii(205)+ascii(188));
+
+    for(i = 0; i < 16; i++) {
+		console.gotoxy(2, i+2);
+		console.print(ascii(186));
+		console.gotoxy(35, i+2);
+		console.print(' '+ascii(186));
+		console.gotoxy(i*2+3, 1);
+		console.print(ascii(205)+ascii(205));
+		console.gotoxy(i*2+3, 18);
+		console.print(ascii(205)+ascii(205));
+    }
+
+    console.gotoxy(1, 20);
+    console.print((new Array(81)).join(ascii(196)));
+
+    console.gotoxy(41, 1);
+    console.attributes = 'K7';
+    console.print(format("   %-20s    Turn %d   ", world, gen));
+    console.attributes = 'N';
+}
+
+function saystat(msg)
+{
+    console.gotoxy(2, 21);
+    console.print(msg);
+    console.cleartoeol();
+}
+
+function mailer(from, to)
+{
+	var heading;
+	var logf;
+	var fp;
+	var f;
+	var fname;
+	var inbuf;
+
+	if(to > 0) {
+		heading = format("From %s of %s to %s of %s  (Turn %d)",
+			nationname(from), nationcity(from),
+			nationname(to), nationcity(to), turn());
+	} else {
+		heading = format("From %s of %s  (Turn %d)",
+			nationname(from), nationcity(from), turn());
+	}
+
+	console.clear(7);
+	console.gotoxy(1,1);
+
+	f = new File(format("%s/%04d.tmpmsg", game_dir, nations[from].uid));
+	if(!f.open("wb")) {
+    	console.clear(7);
+    	mainscreen();
+		saystat("Message Creation Failed (System Error)");
+		return;
+	}
+	f.close();
+	if(console.editfile(f.name)) {
+		if(file_size(f.name) > 0) {
+			if(to > 0)
+				fname = game_dir+'/'+format(MAILFL, to);
+			else
+				fname = game_dir + '/' + NEWSFL;
+
+			if(!f.open('rb')) {
+				file_remove(f.name);
+    			console.clear(7);
+    			mainscreen();
+				saystat("Mail Could Not Be Read...  Cancelled.");
+				return;
+			}
+
+			fp = new File(fname);
+
+			if(!fp.open('ab')) {
+				file_remove(f.name);
+    			console.clear(7);
+    			mainscreen();
+				saystat("Mail Could Not Be Sent...  Cancelled.");
+				return;
+			}
+
+			fp.write(HEADERMARK);
+			fp.write(heading);
+			fp.write("\n\n");
+
+			while((inbuf = f.readln()) != null)
+				fp.writeln(inbuf);
+
+			f.close();
+			fp.close();
+
+			logf = new File(game_dir+'/'+MAILLOG);
+			if(logf.open('ab')) {
+				logf.write(HEADERMARK);
+				logf.write(heading);
+				logf.write("\n\n");
+			}
+		}
+	}
+	file_remove(f.name);
+    console.clear(7);
+    mainscreen();
+	saystat("Mail Sent.");
+
+}
+
+/*
+    showpage() shows a page of text from the current file, starting at
+    the file position in pages[pg], for 19 lines.
+*/
+
+function showpage(fp, pg)
+{
+    var i, len;
+    var inbuf;
+
+	fp.position = pages[pg];
+
+	len = HEADERMARK.length;
+
+    for(i = 0; i < 19; i++) {
+        if((inbuf = fp.readln(1024)) == null)
+            break;
+		inbuf = inbuf.substr(0, 77);
+
+        if(inbuf.substr(0, 2) == HEADERMARK)
+            break;
+
+        console.gotoxy(3, i+1);
+        console.print(inbuf);
+        console.cleartoeol();
+    }
+
+    for(; i < 19; i++) {
+        console.gotoxy(3, i+1);
+        console.cleartoeol();
+    }
+
+    console.gotoxy(56, 22);
+    console.print(format("Page %d of %d", pg + 1, page_cnt));
+    console.cleartoeol();
+
+    console.gotoxy(71, 22);
+    console.print("< >");
+}
+
+function show_killed(pos)
+{
+    console.gotoxy(41, 22);
+
+    if(killed[pos])
+        console.print("[Deleted]");
+    else
+        console.print("         ");
+}
+
+function viewerscr(mode)
+{
+    console.clear(7);
+
+    console.gotoxy(3, 21);
+
+    if(mode)
+        console.print("Mail:  (d)elete  ");
+    else
+        console.print("News:  ");
+
+    console.print("(j)down  (k)up");
+
+    console.gotoxy(3, 22);
+    console.print("Press SPACE to Exit.");
+
+    console.gotoxy(71, 22);
+    console.print("< >");
+}
+
+/*
+    delete_msgs() deletes messages from the named file, using the
+    information in the r_index[] and killed[] arrays.
+*/
+
+function delete_msgs(fn)
+{
+    var i, done, len;
+    var tmp, inbuf;
+    var inf, outf;
+
+    len = HEADERMARK.length;
+
+	tmp = 'tmp'+fn;
+
+	inf = new File(game_dir+'/'+fn);
+	outf = new File(game_dir+'/'+tmp);
+	if(!inf.open("rb")) {
+		log("Message Deletion Failed (System Error)");
+		saystat("Message Deletion Failed (System Error)");
+		return;
+	}
+	if(!outf.open("wb")) {
+		inf.close();
+		log("Message Deletion Failed (System Error)");
+		saystat("Message Deletion Failed (System Error)");
+		return;
+	}
+
+    for(i = 0; i < index_cnt; i++) {
+        if(!killed[i]) {
+			outf.write(HEADERMARK);
+			inf.position = r_index[i];
+			done = 0;
+			while((inbuf = inf.readln(1024)) != null && !done) {
+				inbuf = inbuf.substr(0, 77);
+				if(inbuf.substr(0, len) == HEADERMARK)
+					done = 1;
+				else
+					outf.write(inbuf+'\n');
+			}
+        }
+	}
+
+	inf.close();
+	outf.close();
+
+    file_remove(inf.name);
+    file_rename(outf.name, inf.name);
+}
+
+function readerscr(mode)
+{
+    console.clear(7);
+
+    console.gotoxy(3, 21);
+
+    if(mode)
+        console.print("Mail:  (v)iew current  (d)elete  ");
+    else
+        console.print("News:  (v)iew current  ");
+
+    console.print("(j)down  (k)up  (n)ext  (p)revious");
+
+    console.gotoxy(3, 22);
+    console.print("Press SPACE to Exit.");
+}
+
+/*
+    viewer() displays text from the given file, from the given
+    index offset to the end of file or until a line beginning with
+    a HEADERMARK is encountered.
+*/
+
+function viewer(fp, pos, mode)
+{
+    var ch, i, len, done, pg, opg;
+    var dummy;
+
+    len = HEADERMARK.length;
+
+	fp.position = r_index[pos];
+
+    viewerscr(mode);
+    show_killed(pos);
+
+    done = 0;
+
+    page_cnt = 0;
+
+    do {
+        pages[page_cnt++] = fp.position;
+
+        for(i = 0; i < 15; i++) {
+            if((dummy = fp.readln(1024)) == null) {
+                done = 1;
+                break;
+            }
+			dummy = dummy.substr(0, 77);
+            if(dummy.substr(0, len) == HEADERMARK) {
+                done = 1;
+                break;
+            }
+        }
+
+    } while(!done);
+
+    pg = 0;
+
+    showpage(fp, pg);
+
+    do {
+        console.gotoxy(72, 22);
+        ch = console.getkey();
+
+        opg = pg;
+
+        switch(ch) {
+
+        case 'j' :
+        case 'n' :
+        case KEY_DOWN:
+            pg++;
+            break;
+
+        case 'k' :
+        case 'p' :
+        case KEY_UP:
+            pg--;
+            break;
+
+        case 'd' :
+            killed[pos] = killed[pos] ? 0 : 1;
+            show_killed(pos);
+            break;
+
+        case ' ' :
+        case 'q' :
+            ch = '\033';
+            break;
+
+        }
+
+        if(pg < 0)         pg = 0;
+        if(pg >= page_cnt) pg = page_cnt - 1;
+
+        if(pg != opg)
+            showpage(fp, pg);
+
+    } while(ch != '\033');
+
+    readerscr(mode);
+}
+
+/*
+    show_screen() shows headers from the given file, centering at the
+    header number given.
+*/
+
+function show_screen(pos, fp)
+{
+    var i;
+    var inbuf;
+
+    pos -= 8;
+
+    for(i = 0; i < 18; i++) {
+        console.gotoxy(3, i+1);
+
+        if(pos + i < index_cnt && pos + i >= 0) {
+            if(killed[pos+i])
+                console.print('*');
+            else
+                console.print(' ');
+			fp.position = r_index[pos+i];
+			inbuf = fp.readln(1024);
+			if(inbuf != null) {
+				inbuf = inbuf.substr(0, 77);
+           		console.print(inbuf);
+			}
+        } else if(pos + i == -1)
+            console.print("*** Top of List ***");
+        else if(pos + i == index_cnt)
+            console.print("*** End of List ***");
+
+        console.cleartoeol();
+    }
+}
+
+/*
+    indexer() reads the given file, scanning for headings.  headings
+    are flagged with a space-backspace combination (" \b") which is
+    not shown on most printouts but is easily recognized.
+
+    the array r_index[] contains the seek positions of each heading.
+    it is limited by index_cnt.
+*/
+
+function indexer(fp)
+{
+	var inbuf, len, pos;
+
+    index_cnt = 0;
+
+    len = HEADERMARK.length;
+
+    fp.rewind();
+
+    for(pos = fp.position; (inbuf = fp.readln(1024)) != null; pos = fp.position) {
+		inbuf=inbuf.substr(0, 77);
+		if(inbuf.substr(0, len)==HEADERMARK) {
+			killed[index_cnt] = 0;
+			r_index[index_cnt++] = pos + len;
+		}
+	}
+}
+
+/*
+    reader() displays a list of headings from the given file.  the
+    user may page or "arrow" up or down to view long listings.  when
+    a heading is selected with the (v)iew command, viewer() is called.
+
+    mode is 0 for news, 1 for mail.  mode 1 enables deletion of headings.
+*/
+
+function reader(fname, mode)
+{
+    var top, pos, ch, killcnt;
+    var fp = new File(game_dir+'/'+fname);
+
+    if(!fp.open("rb")) {
+        if(mode)
+            saystat("No Mail in your box.");
+        else
+            saystat("No News to Read.");
+        return;
+    }
+
+    readerscr(mode);
+
+    indexer(fp);
+
+    top = pos = index_cnt - 1;
+
+    show_screen(top, fp);
+
+    do {
+        console.gotoxy(2, pos - top + 9);
+        console.print('>');
+
+        ch = console.getkey();
+
+        console.gotoxy(2, pos - top + 9);
+        console.print(' ');
+
+        switch(ch) {
+
+        case 'j' :
+        case KEY_DOWN:
+            pos++;
+            break;
+
+        case 'k' :
+        case KEY_UP:
+            pos--;
+            break;
+
+        case 'n' :
+        //case KEY_PAGEDOWN:
+            pos += 11;
+            break;
+
+        case 'p' :
+        //case KEY_PAGEUP:
+            pos -= 10;
+            break;
+
+        case 'd' :
+            if(!mode)
+                break;
+
+            killed[pos]++;
+            killed[pos] %= 2;
+
+            show_screen(top, fp);
+
+            break;
+
+        case 'v' :
+            viewer(fp, pos, mode);
+            show_screen(top, fp);
+            break;
+
+        case ' ' :
+        case 'q' :
+            ch = '\033';
+            break;
+
+        }
+
+        if(pos < 0)      pos = 0;
+        if(pos >= index_cnt) pos = index_cnt - 1;
+
+        if(pos > top + 8 || pos < top - 7) {
+            top = pos;
+            show_screen(top, fp);
+        }
+
+    } while(ch != '\033');
+
+    fp.close();
+
+    console.clear(7);
+    mainscreen();
+
+    /* handle deletion. */
+
+    if(mode) {
+        for(killcnt = 0, pos = 0; pos < index_cnt; pos++)
+            killcnt += killed[pos];
+
+        if(killcnt != 0) { /* deleted some... */
+
+            if(killcnt == index_cnt) /* deleted ALL */
+                file_remove(game_dir+'/'+fname);
+            else
+                delete_msgs(fname);
+        }
+    }
+}
+
+function analyze_stack(ms, mc)
+{
+    var i, j, a, b, mmode;
+
+    mmode = 0;
+
+    for(i = 0; i < mc; i++)
+        if(armies[ms[i].id].special_mv > mmode)
+            mmode = armies[ms[i].id].special_mv;
+
+    switch(mmode) {
+
+    case TRANS_ALL :
+
+        /* locate fastest transporter */
+        j = -1;
+        for(i = 0; i < mc; i++) {
+            a = ms[i].id;
+            if(armies[a].special_mv == TRANS_ALL) {
+                if(j == -1 || armies[a].move_left > armies[j].move_left)
+                    j = a;
+                ms[i].dep = a;
+            }
+        }
+
+        /* set (almost) all */
+        for(i = 0; i < mc; i++) {
+            a = ms[i].id;
+            if(armies[a].special_mv == TRANS_ALL)
+                ms[i].dep = a;
+            else if(ms[i].dep == -1)
+                ms[i].dep = j;
+        }
+
+        break;
+
+    case TRANS_SELF :
+
+        /* easy... all move by themselves */
+        for(i = 0; i < mc; i++)
+            ms[i].dep = ms[i].id;
+
+        break;
+
+    default :
+        /* transport hero and/or one army */
+
+        /* set all heros for transportation */
+        for(i = 0; i < mc; i++) {
+            a = ms[i].id;
+            if(armies[a].hero > 0)
+                for(j = 0; j < mc; j++) {
+                    b = ms[j].id;
+                    if(armies[b].special_mv == TRANS_HERO
+                    && ms[j].dep == -1) {
+                        ms[j].dep = b;
+                        ms[i].dep = b;
+                        break;
+                    }
+                }
+        }
+
+        /* set remaining for transportation */
+        for(i = 0; i < mc; i++) {
+            a = ms[i].id;
+            if(ms[i].dep == -1
+            && armies[a].special_mv == TRANS_SELF) {
+                for(j = 0; j < mc; j++) {
+                    b = ms[j].id;
+                    if(armies[b].special_mv == TRANS_ONE
+                    && ms[j].dep == -1) {
+                        ms[j].dep = b;
+                        ms[i].dep = b;
+                        break;
+                    }
+                }
+            }
+        }
+
+        /* leftovers transport self. */
+        for(i = 0; i < mc; i++)
+            if(ms[i].dep == -1)
+                ms[i].dep = ms[i].id;
+
+        break;
+    }
+}
+
+function movecost(a, r, c)
+{
+    var t, tbl, mv, city, cost, a2;
+
+    city = city_at(r, c);
+
+    if(city == -1) {
+        /* not a city */
+
+        /* search for a TRANS_ALL unit there */
+        if(!(armies[a].r == r && armies[a].c == c)
+        && armies[a].special_mv != TRANS_ALL)
+            for(a2 = 0; a2 < armycnt; a2++)
+                if(a != a2
+                && armies[a2].r == r
+                && armies[a2].c == c
+                && armies[a2].nation == armies[a].nation
+                && armies[a2].special_mv == TRANS_ALL)
+                    return 1;
+
+        /* else do this: */
+		t = terrain.indexOf(map[r][c]);
+        if(t != -1) {
+            tbl = armies[a].move_tbl;
+            mv = move_table[tbl].cost[t];
+            
+            if(mv == 0
+                /* otherwise can't move, and */
+            && map[r][c] != '~' 
+                /* target space is not water, and */
+            && map[armies[a].r][armies[a].c] == '~'
+                /* current space is water, and */
+            && (cost = move_table[tbl].cost[0]) > 0)
+                /* this unit moves on water, then */
+                mv = cost * 2; /* beaching is allowed */
+        } else {
+            if(map[r][c] == '+')
+                mv = 1;
+            else
+                mv = 3;
+		}
+    } else {
+
+        /* city */
+
+        if(armies[a].nation == cities[city].nation)
+            mv = 1;
+        else
+            mv = 2;
+    }
+
+    return mv;
+}
+
+function clearstat(mode)
+{
+    if(mode == -1) {
+        console.gotoxy(2, 21); console.cleartoeol();
+        console.gotoxy(2, 22); console.cleartoeol();
+        console.gotoxy(2, 23); console.cleartoeol();
+        console.gotoxy(2, 24); console.cleartoeol();
+    } else {
+        console.gotoxy(2, 21+mode); console.cleartoeol();
+    }
+}
+
+function mark_of(a)
+{
+    var i;
+
+    if(mvcnt < 1)
+        return 0;
+
+    for(i = 0; i < mvcnt; i++)
+        if(movestack[i].id == a)
+            return 1;
+
+    return 0;
+}
+
+function sortview()
+{
+    var gap, i, j, temp;
+
+    avpnt = 0;
+
+    for(gap = parseInt(avcnt / 2); gap > 0; gap = parseInt(gap / 2)) {
+        for(i = gap; i < avcnt; i++) {
+            for(j = i - gap; j >= 0 && isgreater(armyview[j+gap].id, armyview[j].id); j -= gap) {
+                temp = armyview[j].id;
+                armyview[j].id = armyview[j+gap].id;
+                armyview[j+gap].id = temp;
+                temp = armyview[j].mark;
+                armyview[j].mark = armyview[j+gap].mark;
+                armyview[j+gap].mark = temp;
+            }
+		}
+	}
+}
+
+function setfocus(ntn, r, c)
+{
+    var i, j, e;
+
+    avcnt = 0;
+
+    /* clear the enemies list */
+
+    for(e = 0; e < 2; e++) {
+        enemies[e].nation = -1;
+        enemies[e].armies = 0;
+        enemies[e].heros = 0;
+    }
+
+    /* clear the map overlay */
+
+    for(i = 0; i < map_height; i++)
+        for(j = 0; j < map_height; j++)
+            mapovl[i][j] = ' ';
+
+    /* find the player's armies */
+
+    for(i = 0; i < armycnt; i++) {
+        if(r == armies[i].r
+        && c == armies[i].c)
+            if(armies[i].nation == ntn || ntn == -1) {
+                armyview[avcnt].id = i;
+                armyview[avcnt++].mark = mark_of(i);
+            } else {
+
+                e = 0;
+
+                if(enemies[0].nation != armies[i].nation
+                && enemies[0].nation != -1)
+                    e = 1;
+
+                enemies[e].nation = armies[i].nation;
+
+                if(armies[i].hero > 0)
+                    enemies[e].heros++;
+                else
+                    enemies[e].armies++;
+            }
+
+        if(armies[i].nation >= 0) {
+            if(mapovl[armies[i].r][armies[i].c] == ' '
+            || mapovl[armies[i].r][armies[i].c] ==
+               marks[1].substr(marks[0].indexOf([nations[armies[i].nation].mark]), 1)) {
+                mapovl[armies[i].r][armies[i].c] =
+                    marks[1].substr(marks[0].indexOf([nations[armies[i].nation].mark]), 1);
+			}
+            else {
+                mapovl[armies[i].r][armies[i].c] = '!';
+			}
+        }
+    }
+
+    sortview();
+
+    /* update map overlay with cities */
+
+    for(i = 0; i < citycnt; i++) {
+        if(mapovl[cities[i].r][cities[i].c] == ' '
+        || marks[1].indexOf(mapovl[cities[i].r][cities[i].c]) != -1) {
+            mapovl[cities[i].r][cities[i].c] =
+                nations[cities[i].nation].mark;
+        }
+        else {
+            mapovl[cities[i].r][cities[i].c] = '!';
+		}
+    }
+}
+
+function showarmies()
+{
+    var i, a;
+    var buff;
+
+    for(i = 0; i < 12; i++) {
+
+        console.gotoxy(38, i + 3);
+
+        if(i < avcnt) {
+            a = armyview[i].id;
+            console.print(format("%s %c ",
+                i == avpnt ? "=>" : "  ",
+                armyview[i].mark ? '*' : ' '));
+            buff = armyname(a);
+
+            if(armies[a].name.length == 0 && armies[a].hero > 0)
+                buff = "(Nameless Hero)";
+            else if(armies[a].hero > 0)
+                buff += " (Hero)";
+
+            console.print(format("%-31.31s %d:%d", buff,
+                armies[a].move_rate, armies[a].move_left));
+        }
+
+        console.cleartoeol();
+    }
+
+    console.gotoxy(38, 14);
+    if(avcnt > 0)
+        console.print(format("     Total %d Armies", avcnt));
+    console.cleartoeol();
+
+    for(i = 0; i < 2; i++) {
+        console.gotoxy(43, i + 16);
+
+        if(enemies[i].nation != -1)
+            console.print(format("%-15.15s %3d Armies, %3d Heros",
+                i == 1
+                    ? "(Other Nations)"
+                    : nationcity(enemies[i].nation),
+                enemies[i].armies, enemies[i].heros));
+
+        console.cleartoeol();
+    }
+}
+
+function gmapspot(r, c, terr, mark, focus)
+{
+    if(mark == ' ')
+        mark = terr;
+
+    if(terr == '~')
+        terr = ' ';
+
+    if(mark == '~')
+        mark = ' ';
+
+    console.gotoxy(c * 2 + 4, r + 2);
+    if(terr_attr[mark]==undefined)
+		console.attributes='N';
+	else
+		console.attributes=terr_attr[mark];
+    console.print(mark);
+    console.attributes = terr_attr[terr];
+    console.print(terr);
+
+    console.gotoxy(c * 2 + 4, r + 2);
+
+    return 0;
+}
+
+function cityowner(c)
+{
+    var n;
+
+    n = cities[c].nation;
+
+    if(n == 0)  return "Neutral";
+    if(n == 27) return "Rogue";
+
+    return cities[nations[n].city].name;
+}
+
+function showcity(r, c)
+{
+    var i;
+    var buff = '';
+
+    console.gotoxy(4, 19);
+
+    i = city_at(r, c);
+
+    if(i != -1) {
+        buff = format("City:  %s (%s)",
+            cities[i].name, cityowner(i));
+    }
+    
+    console.print(format("%-40.40s", buff));
+}
+
+var old_ul_r = -1;
+var old_ul_c = -1;
+function showmap(r, c, force)
+{
+    var ul_r, ul_c, f_r, f_c;
+    var i, j, zr, zc;
+    var rem;
+
+    showarmies();
+
+    rem = parseInt((16 - gran) / 2);
+    f_r = r % gran;
+    f_c = c % gran;
+
+    ul_r = ((parseInt(r / gran) * gran - rem) + map_height) % map_height;
+    ul_c = ((parseInt(c / gran) * gran - rem) + map_width) % map_width;
+
+    if(old_ul_r != ul_r || old_ul_c != ul_c || force)
+        for(i = 0; i < 16; i++)
+            for(j = 0; j < 16; j++) {
+                zr = (ul_r+i) % map_height;
+                zc = (ul_c+j) % map_width;
+                gmapspot(i, j, map[zr][zc], mapovl[zr][zc], 0);
+            }
+
+	console.attributes='N';
+    old_ul_r = ul_r;
+    old_ul_c = ul_c;
+
+    if(mapovl[r][c] != ' ')
+        showcity(r, c);
+
+    console.gotoxy(f_c * 2 + 16, f_r + 8);
+}
+
+function showfocus(r, c, mode)
+{
+    var f_r, f_c, rem;
+
+    rem = parseInt((16 - gran) / 2);
+
+    f_r = (r % gran) + rem;
+    f_c = (c % gran) + rem;
+
+    gmapspot(f_r, f_c, map[r][c], mapovl[r][c], 1);
+    console.attributes='N';
+}
+
+function fixrow(r)
+{
+    r += map_height;
+    r %= map_height;
+
+    return r;
+}
+
+function fixcol(c)
+{
+    c += map_width;
+    c %= map_width;
+
+    return c;
+}
+
+function move_mode(ntn, rp, cp)
+{
+    var i, j, mv, ch, city, army, t_r, t_c, a, b, ok, cnt, max, flag;
+    var ac, hc, mmode;
+    var mvc = new Array(TRANS_ALL+1);
+    var gap, temp;
+    var unmarked = [
+		{ id:0, moved:0, dep:0 },
+		{ id:0, moved:0, dep:0 },
+		{ id:0, moved:0, dep:0 },
+		{ id:0, moved:0, dep:0 },
+		{ id:0, moved:0, dep:0 },
+		{ id:0, moved:0, dep:0 },
+		{ id:0, moved:0, dep:0 },
+		{ id:0, moved:0, dep:0 },
+		{ id:0, moved:0, dep:0 },
+		{ id:0, moved:0, dep:0 },
+		{ id:0, moved:0, dep:0 },
+		{ id:0, moved:0, dep:0 }
+    ];
+    var uncnt;
+
+    var buff;
+
+    if(avcnt < 1) {
+        saystat("No Army to Move.");
+        return {r:rp,c:cp};
+    }
+
+    mvcnt = 0;
+    flag = 0;
+
+    for(i = 0; i < avcnt; i++) {
+        if(armyview[i].mark)
+            flag = 1;
+        if(armyview[i].mark
+        && (armies[armyview[i].id].move_left > 0 || ntn == -1)) {
+            if(mvcnt >= 10 && ntn >= 0) {
+                saystat("Too Many Armies for Group.");
+        		return {r:rp,c:cp};
+            }
+            movestack[mvcnt].moved = 0;
+            movestack[mvcnt].dep = -1;
+            movestack[mvcnt++].id = armyview[i].id;
+        }
+    }
+
+    if(mvcnt < 1 && !flag
+    && (armies[armyview[avpnt].id].move_left > 0 || ntn == -1)) {
+        movestack[mvcnt].moved = 0;
+        movestack[mvcnt].dep = -1;
+        movestack[mvcnt++].id = armyview[avpnt].id;
+        armyview[avpnt].mark = 1;
+    }
+
+    if(mvcnt < 1 && ntn > -1) {
+        saystat("Armies Have No Movement Left.");
+        return {r:rp,c:cp};
+    }
+
+    /* 
+        prevent stranding:  
+            analyze the unmarked armies
+    
+        create a "movestack" of the unmarked.
+        if they can move, stranding can't occur.
+    */
+
+    if(ntn > -1) {
+
+        uncnt = 0;
+
+        for(i = 0; i < avcnt; i++) {
+            if(!armyview[i].mark) {
+                unmarked[uncnt].moved = 0;
+                unmarked[uncnt].dep = -1;
+                unmarked[uncnt++].id = armyview[i].id;
+            }
+        }
+
+        analyze_stack(unmarked, uncnt);
+
+        for(i = 0; i < uncnt; i++) {
+            a = unmarked[i].id;
+            if(unmarked[i].dep == a
+            && armies[a].special_mv != TRANS_ALL
+            && movecost(a, armies[a].r, armies[a].c) == 0) {
+                saystat("Armies Would Be Stranded...  Movement Cancelled.");
+                return {r:rp,c:cp};
+            }
+        }
+    }
+
+    /* analyze move stack */
+
+    if(ntn > -1)
+        analyze_stack(movestack, mvcnt);
+
+    /* perform movement */
+
+    clearstat(-1);
+
+    console.gotoxy(2, 22);
+    console.print(format("Move %s", mvcnt > 1 ? "Armies" : "Army"));
+
+    console.gotoxy(21, 23);
+    console.print("4   6  or  h   l");
+
+    console.gotoxy(21, 24);
+    console.print("1 2 3      n j m");
+
+    console.gotoxy(21, 22);
+    console.print("7 8 9      y k u    SPACE to Stop.  ");
+
+    setfocus(ntn, rp, cp);
+    showmap(rp, cp, 0);
+    showfocus(rp, cp, 1);
+
+    while(mvcnt > 0 && (ch = console.getkey()) != ' ' 
+    && terminate.indexOf(ch) == -1) {
+
+        showfocus(rp, cp, 0);
+        clearstat(0);
+
+        t_r = rp;
+        t_c = cp;
+
+        switch(ch) { /* directions */
+
+        case '7' :
+        case 'y' :
+            t_r--;
+            t_c--;
+          break;
+
+        case '8' :
+        case 'k' :
+            t_r--;
+            break;
+
+        case '9' :
+        case 'u' :
+            t_r--;
+            t_c++;
+            break;
+
+        case '4' :
+        case 'h' :
+            t_c--;
+            break;
+
+        case '6' :
+        case 'l' :
+            t_c++;
+            break;
+
+        case '1' :
+        case 'n' :
+            t_r++;
+            t_c--;
+          break;
+
+        case '2' :
+        case 'j' :
+            t_r++;
+            break;
+
+        case '3' :
+        case 'm' :
+            t_r++;
+            t_c++;
+            break;
+
+        case '\f' :
+			// TODO: Refresh
+            break;
+        }
+
+        t_r = fixrow(t_r);
+        t_c = fixcol(t_c);
+
+        if(t_r != rp || t_c != cp) {
+            /* actual move code... */
+
+            ok = 1;
+
+            /* verify that all units can make the move. */
+
+            if(ntn > -1) {
+
+                for(i = 0; i < mvcnt; i++) {
+
+                    a = movestack[i].id;
+
+                    if(movestack[i].dep == a) {
+
+                        mv = movecost(a, t_r, t_c);
+
+                        if(mv > armies[a].move_left
+                        || mv == 0) {
+                            ok = 0;
+                            buff = format("%s Can't Move There.",
+                                armyname(a));
+                            saystat(buff);
+                            break;
+                        }
+                    }
+                }
+            }
+
+            /* prevent overstacking. */
+
+            if(ok && ntn > -1) {
+                cnt = 0;
+
+                for(i = 0; i < armycnt; i++)
+                if(armies[i].nation == ntn
+                    && armies[i].r == t_r
+                    && armies[i].c == t_c)
+                        cnt++;
+
+                city = city_at(t_r, t_c);
+
+                max = 10;
+
+                if(city != -1
+                && cities[city].nation == ntn)
+                    max = 12;
+
+                if(mvcnt + cnt > max) {
+                    ok = 0;
+                    saystat("Too Many Armies There.");
+                }
+            }
+
+            /* can't leave combat. */
+
+            if(ok && ntn > -1)
+                for(i = 0; i < armycnt; i++)
+                    if(armies[i].nation != ntn
+                    && armies[i].r == rp
+                    && armies[i].c == cp) {
+                        ok = 0;
+                    saystat("Can't Leave Combat.");
+                        break;
+                    }
+
+            /* do it! */
+
+            if(ok) {
+                for(i = 0; i < mvcnt; i++) {
+                    a = movestack[i].id;
+
+                    if(ntn > -1) {
+                        if(movestack[i].dep == a)
+                            mv = movecost(a, t_r, t_c);
+                        else
+                            mv = armies[a].move_left ? 1 : 0;
+                    } else
+                        mv = 0;
+
+                    movestack[i].moved += mv;
+                    armies[a].move_left -= mv;
+                    armies[a].r = t_r;
+                    armies[a].c = t_c;
+                }
+                rp = t_r;
+                cp = t_c;
+            }
+
+            /* redo screen. */
+
+            setfocus(ntn, rp, cp);
+            showmap(rp, cp, ok);
+        }
+
+        showfocus(rp, cp, 1);
+    }
+
+    if(ntn > -1)
+        for(i = 0; i < mvcnt; i++)
+            if(movestack[i].moved > 0 || ntn == -1)
+                pfile.write(format("move-army %d %d %d %d %d\n",
+                    movestack[i].id, movestack[i].moved,
+                    rp, cp, movestack[i].dep));
+
+    clearstat(-1);
+
+    mvcnt = 0;
+
+    return {r:rp,c:cp};
+}
+
+function my_army_at(r, c, n)
+{
+    var i;
+
+    for(i = 0; i < armycnt; i++)
+        if(armies[i].nation == n
+        && armies[i].r == r
+        && armies[i].c == c)
+            return i;
+
+    return -1;
+}
+
+function show_info(r, c)
+{
+    var buff, buf2;
+    var i, ch, city, ntn, ac, hc;
+
+    buff = '';
+    city = city_at(r, c);
+
+    if(city != -1) {
+        buff = format("City:  %s (%s)", cities[city].name,
+            nationcity(cities[city].nation));
+    } else {
+        ch = map[r][c];
+
+	i=terrain.indexOf(ch);
+	if(i==-1 && ch==' ')
+		buff = "Ocean";
+	else
+		buff = terr_names[i];
+    }
+
+    ac = 0;
+    hc = 0;
+
+    for(i = 0; i < armycnt; i++)
+        if(armies[i].r == r && armies[i].c == c)
+            if(armies[i].hero > 0)
+                hc++;
+            else
+                ac++;
+
+    buf2 = format("  %d Armies, %d Heros", ac, hc);
+    buff += buf2;
+
+    saystat(buff);
+}
+
+function info_mode(rp, cp, n, ch)
+{
+    var done, r, c, ul_r, ul_c, f_r, f_c, t_r, t_c;
+    var city, army, i, flag;
+    var rem;
+
+    rem = parseInt((16 - gran) / 2);
+
+    showfocus(rp, cp, 1);
+
+    clearstat(-1);
+
+    console.gotoxy(21,23);
+    console.print("4   6  or  h   l");
+
+    console.gotoxy(21,24);
+    console.print("1 2 3      n j m");
+
+    console.gotoxy(2,22);
+    console.print("Info Mode:         7 8 9      y k u    ESC to Stop.  ");
+
+    r = rp;
+    c = cp;
+
+    ul_r = ((parseInt(r / gran) * gran - rem) + map_height) % map_height;
+    ul_c = ((parseInt(c / gran) * gran - rem) + map_width) % map_width;
+
+    f_r = (r % gran) + rem;
+    f_c = (c % gran) + rem;
+
+    done = 0;
+
+    do {
+        flag = 1;
+
+        switch(ch) {
+
+        case '7' :
+        case 'y' :
+            f_r--;
+            f_c--;
+            break;
+
+        case '8' :
+        case 'k' :
+            f_r--;
+            break;
+
+        case '9' :
+        case 'u' :
+            f_r--;
+            f_c++;
+            break;
+
+        case '6' :
+        case 'l' :
+            f_c++;
+            break;
+
+        case '3' :
+        case 'm' :
+            f_r++;
+            f_c++;
+            break;
+
+        case '2' :
+        case 'j' :
+            f_r++;
+            break;
+
+        case '1' :
+        case 'n' :
+            f_r++;
+            f_c--;
+            break;
+
+        case '4' :
+        case 'h' :
+            f_c--;
+            break;
+
+        case '\f' :
+	    // TODO: refresh
+            break;
+
+        default :
+            done = 1;
+        }
+
+        if(f_r < 0)  f_r = 0;
+        if(f_c < 0)  f_c = 0;
+
+        if(f_r > 15) f_r = 15;
+        if(f_c > 15) f_c = 15;
+
+        t_r = (ul_r + f_r + map_height) % map_height;
+        t_c = (ul_c + f_c + map_width) % map_width;
+
+        city = my_city_at(t_r, t_c, n);
+        army = my_army_at(t_r, t_c, n);
+
+        if(city >= 0 || army >= 0) {
+            showfocus(rp, cp, 0);
+            r = rp = t_r;
+            c = cp = t_c;
+            setfocus(n, rp, cp);
+            showmap(rp, cp, 0);
+            showfocus(rp, cp, 1);
+            ul_r = ((parseInt(r / gran) * gran - rem) + map_height)
+                % map_height;
+            ul_c = ((parseInt(c / gran) * gran - rem) + map_width)
+                % map_width;
+            f_r = (r % gran) + rem;
+            f_c = (c % gran) + rem;
+            done = 1;
+        }
+
+        if(flag)
+            show_info((ul_r + f_r + map_height) % map_height,
+                    (ul_c + f_c + map_width) % map_width);
+
+        console.gotoxy(f_c * 2 + 4, f_r + 2);
+
+        if(!done)
+            ch = console.getkey();
+
+    } while(!done);
+
+    clearstat(-1);
+
+    showfocus(rp, cp, 0);
+    return {r:rp,c:cp};
+}
+
+function groupcmp(r1, c1, r2, c2)
+{
+    /* quadrant check */
+
+    if(parseInt(r1 / 16) > parseInt(r2 / 16))
+        return 1;
+
+    if(parseInt(r1 / 16) < parseInt(r2 / 16))
+        return -1;
+
+    if(parseInt(c1 / 16) > parseInt(c2 / 16))
+        return 1;
+
+    if(parseInt(c1 / 16) < parseInt(c2 / 16))
+        return -1;
+
+    /* exact check */
+
+    if(r1 > r2)
+        return 1;
+
+    if(r1 < r2)
+        return -1;
+
+    if(c1 > c2)
+        return 1;
+
+    if(c1 < c2)
+        return -1;
+
+    return 0;
+}
+
+function prevgroup(ntn, rp, cp)
+{
+    var i, t_r, t_c;
+
+    t_r = -1;
+    t_c = -1;
+
+    for(i = 0; i < citycnt; i++) {
+        if(cities[i].nation == ntn) {
+            if(groupcmp(cities[i].r, cities[i].c, rp, cp) < 0
+            && (t_r == -1
+            || groupcmp(cities[i].r, cities[i].c, t_r, t_c) > 0)) {
+                t_r = cities[i].r;
+                t_c = cities[i].c;
+			}
+		}
+	}
+
+    for(i = 0; i < armycnt; i++) {
+        if(armies[i].nation == ntn) {
+            if(groupcmp(armies[i].r, armies[i].c, rp, cp) < 0
+            && (t_r == -1
+            || groupcmp(armies[i].r, armies[i].c, t_r, t_c) > 0)) {
+                t_r = armies[i].r;
+                t_c = armies[i].c;
+			}
+		}
+	}
+
+    if(t_r != -1)
+		return {r:t_r,c:t_c,ret:true};
+	else
+        return {r:rp,c:cp,ret:false};
+}
+
+function prevarmy(ntn, rp, cp)
+{
+    var i, t_r, t_c;
+
+    t_r = -1;
+    t_c = -1;
+
+    for(i = 0; i < armycnt; i++) {
+        if(armies[i].nation == ntn && armies[i].move_left > 0) {
+            if(groupcmp(armies[i].r, armies[i].c, rp, cp) < 0
+            && (t_r == -1
+            || groupcmp(armies[i].r, armies[i].c, t_r, t_c) > 0)) {
+                t_r = armies[i].r;
+                t_c = armies[i].c;
+			}
+		}
+	}
+
+    if(t_r != -1)
+		return {r:t_r,c:t_c,ret:true};
+	else
+        return {r:rp,c:cp,ret:false};
+}
+
+function nextgroup(ntn, rp, cp)
+{
+    var i, t_r, t_c;
+
+    t_r = -1;
+    t_c = -1;
+
+    for(i = 0; i < citycnt; i++) {
+        if(cities[i].nation == ntn) {
+            if(groupcmp(cities[i].r, cities[i].c, rp, cp) > 0
+            && (t_r == -1
+            || groupcmp(cities[i].r, cities[i].c, t_r, t_c) < 0)) {
+                t_r = cities[i].r;
+                t_c = cities[i].c;
+			}
+		}
+	}
+
+    for(i = 0; i < armycnt; i++) {
+        if(armies[i].nation == ntn) {
+            if(groupcmp(armies[i].r, armies[i].c, rp, cp) > 0
+            && (t_r == -1
+            || groupcmp(armies[i].r, armies[i].c, t_r, t_c) < 0)) {
+                t_r = armies[i].r;
+                t_c = armies[i].c;
+			}
+		}
+	}
+
+    if(t_r != -1)
+		return {r:t_r,c:t_c,ret:true};
+    else
+        return {r:rp,c:cp,ret:false};
+}
+
+function nextarmy(ntn, rp, cp)
+{
+    var i, t_r, t_c;
+
+    t_r = -1;
+    t_c = -1;
+
+    for(i = 0; i < armycnt; i++) {
+        if(armies[i].nation == ntn && armies[i].move_left > 0) {
+            if(groupcmp(armies[i].r, armies[i].c, rp, cp) > 0
+            && (t_r == -1
+            || groupcmp(armies[i].r, armies[i].c, t_r, t_c) < 0)) {
+                t_r = armies[i].r;
+                t_c = armies[i].c;
+			}
+		}
+	}
+
+    if(t_r != -1)
+		return {r:t_r,c:t_c,ret:true};
+    else
+		return {r:rp,c:cp,ret:false};
+}
+
+var help_mode = 0;
+function help()
+{
+    console.gotoxy(2, 21);
+    console.print(format("Commands, Page %d  (Press ? for More Help)", help_mode + 1));
+    console.cleartoeol();
+
+    switch(help_mode) {
+
+    case 0 :
+        console.gotoxy(2, 22);
+        console.print("  (n)ext group  (p)revious group  (N)last (P)first");
+        console.cleartoeol();
+
+        console.gotoxy(2, 23);
+        console.print("  (s)tatus display  (i)nformation mode");
+        console.print("  (a)rmy production");
+        console.cleartoeol();
+
+        console.gotoxy(2, 24);
+        console.print("  (R)ead news  read (M)ail  (S)end mail  (q)uit");
+        console.cleartoeol();
+
+        break;
+
+    case 1 :
+        console.gotoxy(2, 22);
+        console.print("  (j)pointer down  (k)pointer up  (SPACE)mark  (*)mark all");
+        console.cleartoeol();
+
+        console.gotoxy(2, 23);
+        console.print("  (m)ove marked armies  (r)ename hero  (q)uit");
+        console.cleartoeol();
+
+        console.gotoxy(2, 24);
+        console.cleartoeol();
+
+        break;
+    }
+
+    help_mode++;
+    help_mode %= 2;
+}
+
+function status()
+{
+    var ch, pos, i, j, hc, ac, cc;
+
+    /* set up screen */
+
+    console.clear(7);
+
+    console.gotoxy(21, 2);
+    console.print("Nation Status Display");
+
+    console.gotoxy(2, 4);    console.print("Nation:");
+    console.gotoxy(2, 5);    console.print("Ruler:");
+    console.gotoxy(2, 6);    console.print("Mark:");
+    console.gotoxy(2, 8);    console.print("Cities:");
+    console.gotoxy(2, 9);    console.print("Heros:");
+    console.gotoxy(2, 10);   console.print("Armies:");
+
+    console.gotoxy(2, 12);   console.print("(n)ext page  (p)revious page  (SPACE) to exit");
+
+    /* display loop */
+
+    pos = 0;
+
+    do {
+        /* show the nations. */
+
+        for(i = 4; i <= 11; i++) {
+            console.gotoxy(17, i);
+            console.cleartoeol();
+        }
+
+        for(i = 0; i < 4; i++)
+            if(pos + 1 + i < nationcnt) {
+                console.gotoxy(i * 16 + 17, 4);
+                console.print(nationcity(pos+1+i));
+
+                console.gotoxy(i * 16 + 17, 5);
+                console.print(nations[pos+1+i].name);
+
+                console.gotoxy(i * 16 + 20, 6);
+                console.print(nations[pos+1+i].mark);
+
+                cc = 0;
+
+                for(j = 0; j < citycnt; j++)
+                    if(cities[j].nation == pos + 1 + i)
+                        cc++;
+
+                hc = 0;
+                ac = 0;
+
+                for(j = 0; j < armycnt; j++)
+                    if(armies[j].nation == pos + 1 + i)
+                        if(armies[j].hero > 0)
+                            hc++;
+                        else
+                            ac++;
+
+                console.gotoxy(i * 16 + 17, 8);
+                console.print(format("%5d", cc));
+
+                console.gotoxy(i * 16 + 17, 9);
+                console.print(format("%5d", hc));
+
+                console.gotoxy(i * 16 + 17, 10);
+                console.print(format("%5d", ac));
+            }
+
+        /* handle input. */
+
+        console.gotoxy(71, 12);
+        console.print("< >\b\b");
+
+        switch((ch = console.getkey())) {
+
+        case ' ' :
+        case 'q' :
+            ch = '\033';
+            break;
+
+        case 'n' :
+            if(pos + 5 < nationcnt)
+                pos += 4;
+            break;
+
+        case 'p' :
+            if(pos - 3 > 0)
+                pos -= 4;
+            break;
+        }
+
+    } while(ch != '\033');
+
+    /* clean up */
+
+    mainscreen();
+}
+
+function produce(city)
+{
+    var i, t, ch;
+    var buff='';
+    var okstring='';
+
+    console.gotoxy(2, 22);  console.cleartoeol();
+    console.gotoxy(2, 23);  console.cleartoeol();
+
+    for(i = 0; i < cities[city].ntypes; i++) {
+        if(cities[city].types[i] != -1) {
+            console.gotoxy(parseInt(i / 2) * 30 + 2, (i % 2) + 22);
+            console.print(format("%d) %-14.14s (%d)", i + 1,
+                ttypes[cities[city].types[i]].name,
+                cities[city].times[i]));
+            okstring += (i+1);
+        }
+    }
+
+	console.gotoxy(2, 24);
+    t = cities[city].types[cities[city].prod_type];
+	console.print(format("Current:  %s (%d turns left)    ESC to Cancel",
+        ttypes[t].name,
+        cities[city].turns_left));
+    console.cleartoeol();
+
+    saystat(format("Set Army Production for %s:  ", cities[city].name));
+
+    if(okstring.indexOf(ch = console.getkeys(okstring+'\x1b', 0)) != -1) {
+        buff = format("set-produce %d %d\n", city, ch - 1);
+        pfile.write(buff);
+        execpriv(buff);
+    }
+
+    clearstat(-1);
+}
+
+function mainloop(ntn)
+{
+    var ch, r, c, i, n, city, army, force, obj;
+    var inbuf, buff;
+
+    r = -1;
+    c = -1;
+
+    army = -1;
+
+    /* find the player's capitol city */
+
+    if(cities[nations[ntn].city].nation == ntn) {
+        i = nations[ntn].city;
+        r = cities[i].r;
+        c = cities[i].c;
+       setfocus(ntn, r, c);
+    }
+
+    /* find the player's first city */
+
+    city = city_at(r, c);
+
+    if(city != -1 && cities[city].nation != ntn)
+        city = -1;
+
+    if(city == -1)
+        for(i = 0; i < citycnt; i++)
+            if(cities[i].nation == ntn) {
+                r = cities[i].r;
+                c = cities[i].c;
+                setfocus(ntn, r, c);
+                break;
+            }
+
+    /* find the player's first army */
+
+    if(city == -1)
+        for(i = 0; i < armycnt; i++)
+            if(armies[i].nation == ntn) {
+                r = armies[i].r;
+                c = armies[i].c;
+                army = i;
+             setfocus(ntn, r, c);
+                break;
+            }
+
+    if(army == -1 && city == -1) {
+        saystat("Nation is Destroyed.  Press Any Key:  ");
+        console.getkey();
+        return;
+    }
+
+    /* enter the loop */
+
+    saystat("Welcome to Solomoriah's WAR!  Press ? for Help.");
+
+    force = 0;
+
+    for(;;) {
+
+        showmap(r, c, force);
+        force = 0;
+
+        showfocus(r, c, 1);
+        ch = console.getkey();
+        showfocus(r, c, 0);
+
+        clearstat(-1);
+
+        switch(ch) {
+
+        case 'a' : /* armies */
+            city = city_at(r, c);
+            if(city != -1 && cities[city].nation == ntn)
+                produce(city);
+            else
+                saystat("Must View Your Own City First.");
+            break;
+
+        case '\016' : /* next army */
+			obj = nextarmy(ntn, r, c);
+			r = obj.r;
+			c = obj.c;
+            if(!obj.ret)
+                saystat("No Next Army with Movement Found");
+            else
+                setfocus(ntn, r, c);
+            break;
+
+        case 'n' : /* next group */
+			obj = nextgroup(ntn, r, c);
+			r = obj.r;
+			c = obj.c;
+            if(!obj.ret) {
+                saystat("No More Groups Remain.");
+            } else
+                setfocus(ntn, r, c);
+            break;
+
+        case 'N' : /* last group */
+            while((obj = nextgroup(ntn, r, c)).ret) {
+				r = obj.r;
+				c = obj.c;
+			}
+			r = obj.r;
+			c = obj.c;
+            setfocus(ntn, r, c);
+            break;
+
+        case '\020' : /* prev army */
+			obj = prevarmy(ntn, r, c);
+			r = obj.r;
+			c = obj.c;
+            if(!obj.ret)
+                saystat("No Previous Army with Movement Found");
+            else
+                setfocus(ntn, r, c);
+            break;
+
+        case 'p' : /* previous group */
+			obj = prevgroup(ntn, r, c);
+			r = obj.r;
+			c = obj.c;
+            if(!obj.ret) {
+                saystat("No Previous Groups Remain.");
+            } else
+                setfocus(ntn, r, c);
+          break;
+
+        case 'P' : /* first group */
+            while((obj = prevgroup(ntn, r, c)).ret) {
+				r = obj.r;
+				c = obj.c;
+			}
+			r = obj.r;
+			c = obj.c;
+            setfocus(ntn, r, c);
+            break;
+
+        case 'r' : /* rename hero */
+            if(avcnt > 0 && armies[armyview[avpnt].id].name.length == 0) {
+                saystat("Enter Hero's Name:  ");
+                inbuf = console.getstr(16);
+
+                buff = format("name-army %d '%s'\n", armyview[avpnt].id, inbuf);
+                pfile.write(buff);
+                execpriv(buff);
+
+                setfocus(ntn, r, c);
+                clearstat(-1);
+            } else
+                saystat("Can Only Rename Heros.");
+            break;
+
+        case 'j' : /* next army */
+        case 'd' :
+        case KEY_DOWN:
+            if(avcnt > 0) {
+                avpnt++;
+             avpnt += avcnt;
+                avpnt %= avcnt;
+            } else
+                saystat("No Armies!");
+            break;
+
+        case 'k' : /* previous army */
+        case 'u' :
+        case KEY_UP:
+            if(avcnt > 0) {
+                avpnt--;
+                avpnt += avcnt;
+                avpnt %= avcnt;
+            } else
+                saystat("No Armies!");
+            break;
+
+        case ' ' : /* mark */
+            if(avcnt > 0)
+                armyview[avpnt].mark =
+                    armyview[avpnt].mark ? 0 : 1;
+            break;
+
+        case 'I' : /* army information */
+            if(avcnt > 0) {
+                var id = armyview[avpnt].id;
+                buff = format("%s: Combat %d / Hero %d %s",
+                    armyname(id), armies[id].combat, armies[id].hero,
+                    ((armies[id].hero > 0 && armies[id].eparm1) ? "(Loyal)" : ""));
+                saystat(buff);
+            } else
+                saystat("No Armies!");
+            break;
+
+        case '*' : /* mark all */
+        case 'g' : /* mark all and move */
+            for(i = 0; i < avcnt; i++)
+                if(armies[armyview[i].id].move_left > 0)
+                    armyview[i].mark = 1;
+            if(ch == '*')
+                break;
+            /* fall through */
+
+        case 'm' : /* move */
+            obj = move_mode(ntn, r, c);
+            r = obj.r;
+            c = obj.c;
+            setfocus(ntn, r, c);
+            break;
+
+        case '/' : /* unmark all */
+            for(i = 0; i < avcnt; i++)
+                armyview[i].mark = 0;
+            break;
+
+        case 'i' : /* information */
+        case '1' :
+        case '2' :
+        case '3' :
+        case '4' :
+        case '5' :
+        case '6' :
+        case '7' :
+        case '8' :
+        case '9' :
+            obj = info_mode(r, c, ntn, ch);
+            r = obj.r;
+            c = obj.c;
+            setfocus(ntn, r, c);
+            break;
+
+        case 'R' : /* read... */
+            reader(NEWSFL, 0);
+			force = 1;
+            break;
+
+        case 'M' : /* mail... */
+            inbuf = format(MAILFL, ntn);
+            reader(inbuf, 1);
+            force = 1;
+            break;
+
+        case 'S' : /* send mail */
+            saystat("Send Mail -- Enter Ruler's Name, or All to Post News:  ");
+            inbuf = console.getstr(16);
+
+            n = -1;
+            for(i = 0; i < nationcnt; i++)
+                if(nations[i].name.toUpperCase() == inbuf.toUpperCase())
+                    n = i;
+
+            if(n == -1 && "all" == inbuf.toLowerCase())
+                n = 0;
+
+            if(n == -1) {
+                saystat("No Such Ruler.");
+                break;
+            }
+
+            mailer(ntn, n);
+
+            force = 1;
+            clearstat(-1);
+            break;
+
+       case 's' : /* status */
+            status();
+            force = 1;
+            break;
+
+        case 'h' : /* help */
+        case '?' :
+            help();
+            break;
+
+        case '\f' :
+			force = 1;
+            break;
+
+        case 'q' : /* quit */
+            saystat("Quit?  (Y/N)  ");
+            if(console.getkey().toLowerCase() == 'y')
+                return;
+            clearstat(-1);
+            break;
+       }
+    }
+}
+
+function writemap(fp, ntn) {
+    var r, c, i, j, m;
+	var pmap=[];
+
+	function markup(r, c)
+	{
+		var r_origin, c_origin, i, j, fixed_r, fixed_c;
+
+		r_origin = parseInt(r / gran) * gran - 7;
+		c_origin = parseInt(c / gran) * gran - 7;
+
+		for(i = 0; i < 16; i++)
+			for(j = 0; j < 16; j++) {
+				fixed_r = fixrow(r_origin+i);
+				fixed_c = fixcol(c_origin+j);
+				if(pmap[fixed_r][fixed_c] == 0)
+					pmap[fixed_r][fixed_c] = 3;
+			}
+	}
+
+    /* clear the player map */
+
+    for(r = 0; r < map_height; r++) {
+		pmap[r]=[];
+        for(c = 0; c < map_width; c++) {
+            pmap[r][c] = 0;
+        }
+	}
+
+    /* find the nation's groups */
+
+    for(i = 0; i < armycnt; i++)
+        if(armies[i].nation == ntn) {
+            r = armies[i].r;
+            c = armies[i].c;
+            pmap[r][c] = 1;
+        }
+
+    for(i = 0; i < citycnt; i++)
+        if(cities[i].nation == ntn) {
+            r = cities[i].r;
+            c = cities[i].c;
+            pmap[r][c] = 1;
+        }
+
+    /* mark up the overlay */
+
+    for(c = 0; c < map_width; c++)
+        for(r = 0; r < map_height; r++)
+            if(pmap[r][c] == 1)
+                markup(r, c);
+
+    /* write map */
+
+    fp.printf("%c %d %d\n\n", 
+        marks[0][nations[ntn].mark], map_height, map_width);
+
+    for(r = 0; r < map_height; r++) {
+        for(c = 0; c < map_width; c++)
+            fp.printf("%s%s%u", 
+                map[r][c], mapovl[r][c], pmap[r][c]);
+        fp.write('\n');
+    }
+}
+
+function titlescreen()
+{
+    var i;
+	var title = [
+		"             S O L O M O R I A H ' S",
+		"",
+		"           #    #    ##    #####    ###",
+		"           #    #   #  #   #    #   ###",
+		"           #    #  #    #  #    #   ###",
+		"           #    #  ######  #####     # ",
+		"           # ## #  #    #  #   #       ",
+		"           ##  ##  #    #  #    #   ###",
+		"            #  #   #    #  #    #   ###",
+	];
+
+    console.clear(7);
+
+    for(i=0; i<title.length; i++) {
+        console.gotoxy(11, i+3);
+        console.print(title[i]);
+    }
+
+    console.gotoxy(11, i+3);
+    console.print('JSWAR Version '+(major_ver)+'.'+(minor_ver)+'             "Code by Solomoriah"');
+
+    console.gotoxy(11, i+5);
+    console.print("Original Copyright 1993, 1994, 2001, 2013, Chris Gonnerman");
+
+    console.gotoxy(11, i+6);
+    console.print("JavaScript Version Copyright 2013, Stephen Hurd");
+
+    console.gotoxy(11, i+7);
+    console.print("All Rights Reserved.");
+}
+
+function newcity()
+{
+	var i;
+	var clusters = [];
+	var cc;
+	var c;
+	var cl;
+
+	for(i = 0; i<MAXCITIES; i++)
+		clusters[i] = -1;
+
+	for(i=0; i<citycnt; i++) {
+		if(cities[i].nation > 0)
+			clusters[cities[i].cluster % MAXCITIES] = 1;
+		else if(clusters[cities[i].cluster % MAXCITIES] == -1)
+			clusters[cities[i].cluster % MAXCITIES] = 0;
+	}
+
+    cc = 0;
+
+    for(i = 0; i < MAXCITIES; i++)
+        if(clusters[i] == 0)
+            cc++;
+
+    if(cc == 0) {   /* any city will do... */
+        cc = 0;
+
+        for(i = 0; i < citycnt; i++)
+            if(cities[i].nation == 0)
+                cc++;
+
+        if(cc == 0)
+            return -1;
+
+        c = random(cc);
+
+        for(i = 0; i < citycnt; i++)
+            if(cities[i].nation == 0)
+                if(c == 0)
+                    return i;
+                else
+                    c--;
+
+        /* should not get here... */
+
+        return -1;
+
+    } else {        /* find an empty cluster... */
+
+        c = random(cc);
+
+        for(i = 0; i < MAXCITIES; i++)
+            if(clusters[i] == 0)
+                if(c == 0)
+                    break;
+                else
+                    c--;
+
+        if(i < MAXCITIES) {
+            cl = i;
+            cc = 0;
+            for(i = 0; i < citycnt; i++)
+                if(cities[i].cluster == cl)
+                    cc++;
+            c = random(cc);
+            for(i = 0; i < citycnt; i++)
+                if(cities[i].cluster == cl)
+                    if(c == 0)
+                        return i;
+                    else
+                        c--;
+        }
+
+        /* should not get here. */
+
+        return -1;
+    }
+}
+
+function main(argc, argv)
+{
+	var rc;
+	var uid;
+	var n;
+	var c;
+	var ch;
+	var t;
+	var trys;
+	var mtbl;
+	var line;
+	var offset;
+	var confirmed;
+	var fp=new File();
+	var pp=new File();
+	var filename='';
+	var inbuf='';
+	var name='';
+	var p;
+	var u;
+	var pass='';
+	var cmd='';
+	var gamedir='';
+	var st_buf;
+	var i;
+
+	titlescreen();
+
+	/* load map file */
+
+	if((rc = loadmap()) != 0) {
+		console.gotoxy(11,21);
+		console.print("Error Loading Map ("+rc+")\r\n");
+		console.getkey();
+		exit(1);
+	}
+	if((rc = loadsave()) != 0) {
+		console.gotoxy(11,21);
+		console.print("Error Loading Game Save ("+rc+")\r\n");
+		console.getkey();
+		exit(2);
+	}
+
+	console.gotoxy(11,17);
+	if(world.length > 0)
+		console.print("World: "+world+"    ");
+	console.print("Turn:  "+gen);
+
+	uid = user.number;
+
+	if(uid == undefined || uid == 0) {
+		console.gotoxy(11, 21);
+		console.print("UID Not Available; Aborting.");
+		console.getkey();
+		exit(3);
+	}
+
+	console.gotoxy(11, 21);
+	console.print("Reading Master Commands...  ");
+
+	fp = new File(game_dir+'/master.cmd');
+	if(fp.open('rb')) {
+		for(i=0; (inbuf = fp.readln())!=null; i++) {
+			if((rc=execpriv(inbuf)==0)) {
+				console.gotoxy(49,21);
+				console.print(format("%3d lines"));
+			}
+			else {
+				console.gotoxy(11,21);
+				console.print("Master Cmd Failed, Line "+(i+1)+", Code "+rc+"  ");
+				console.getkey();
+				exit(4);
+			}
+		}
+		fp.close();
+	}
+
+    /* check if nation is entered. */
+
+    n = -1;
+
+    for(i = 0; i < nationcnt; i++) {
+        if(nations[i].uid == uid) {
+			/* TODO: Check for the canary file! */
+            n = i;
+            break;
+        }
+	}
+
+    if(n == -1) { /* nation not entered yet... */
+        c = newcity();
+
+        if(c >= 0) {
+            fp = new File(game_dir+'/master.cmd');
+            if(!fp.open('ab')) {
+				console.gotoxy(11,21);
+				console.print("Can't Write Master Cmd's  ");
+				console.cleartoeol();
+				console.getkey();
+				exit(5);
+			}
+
+            n = nationcnt;
+            confirmed = 0;
+
+            while(!confirmed) {
+				console.gotoxy(11,19);
+				console.print("Your City is "+ cities[c].name);
+				console.cleartoeol();
+
+				inbuf='';
+				while(inbuf.length==0) {
+					console.gotoxy(11, 21);
+					console.print("(Enter ! to Retry)");
+					console.cleartoeol();
+					console.gotoxy(11, 20);
+					console.print("Enter your name:  ");
+					console.cleartoeol();
+					inbuf = console.getstr(NATIONNMLEN);
+				}
+				if(inbuf == '!')
+					c = newcity();
+				else
+					confirmed = 1;
+            }
+
+			name=inbuf;
+			console.gotoxy(11,22);
+			console.print("Available:  ");
+			
+			inbuf = marks[0];
+			for(i=0; i<nationcnt; i++)
+				inbuf = inbuf.replace(nations[i].mark, '');
+			inbuf = inbuf.replace(' ','');
+			console.print(inbuf);
+			console.gotoxy(11, 21);
+			console.print("Select Nation Mark:  ");
+			console.cleartoeol();
+			ch = console.getkeys(inbuf);
+			console.gotoxy(11,22);
+			console.cleartoeol();
+			inbuf = "new-nation '"+name+"' "+uid+' '+c+' '+ch;
+			fp.writeln(inbuf);
+			execpriv(inbuf);
+			
+			/* ... and the hero... */
+			t = cities[c].types[0];
+			mtbl = ttypes[t].move_tbl;
+			inbuf = "make-army '"+name+"' "+n+' '+cities[c].r+' '+cities[c].c+' '+(random(3)+4)+' '+(random(2)+1)+' 8 '+(mtbl)+' 0 1';
+			fp.writeln(inbuf);
+			execpriv(inbuf);
+
+			/* ...and take the city. */
+			inbuf = 'control-city '+(n)+' '+(c);
+			fp.writeln(inbuf);
+			execpriv(inbuf);
+			fp.close();
+		}
+		else {
+			console.gotoxy(11, 21);
+			console.print("No Cities Available.  ");
+			console.cleartoeol();
+			console.getkey();
+			exit(6);
+		}
+	}
+
+	/* execute player commands */
+
+	console.gotoxy(11, 21);
+	console.print("Reading Player Commands...  ");
+	console.cleartoeol();
+	fp = new File(format("%s/%04d.cmd", game_dir, uid));
+	if(fp.open('rb')) {
+		for(i=0; (inbuf = fp.readln()) != null; i++) {
+			if((rc = execpriv(inbuf))==0) {
+				if((i+1) % 10 == 0) {
+					console.gotoxy(49, 21);
+					console.print(format("%3u lines", i));
+				}
+			}
+			else {
+				console.gotoxy(11, 21);
+				console.print("Player Cmd Failed, Line "+(i+1)+", Code "+(rc)+"  ");
+				console.getkey();
+				exit(7);
+			}
+		}
+		fp.close();
+	}
+
+	/* append to player file... */
+	
+	pfile = new File(format("%s/%04d.cmd", game_dir, uid));
+	if(!pfile.open('ab', 0 /* Not buffered */)) {
+		console.gotoxy(11, 21);
+		console.print("Can't Create or Append Player Cmd's  ");
+		console.cleartoeol();
+		console.getkey();
+		exit(8);
+	}
+
+	/* main loop */
+	
+	for(i=0; i<nationcnt; i++)
+		if(nations[i].uid == uid)
+			n = i;
+
+	console.gotoxy(11, 20);
+	console.print("Welcome, "+nations[n].name+" of "+nationcity(n)+"!");
+	console.cleartoeol();
+	console.gotoxy(11, 21);
+	console.print("Press Any Key to Begin...  ");
+	console.cleartoeol();
+	console.getkey();
+	mainscreen();
+	mainloop(n);
+	
+	/* clean up */
+
+	pfile.close();
+
+	pfile = new File(format("%s/%04d.map", game_dir, uid));
+	pfile.open('wb');
+	writemap(pfile, n);
+	pfile.close();
+	exit(0);
+}
+
+main(argc, argv);
+
+/* end of file. */
diff --git a/xtrn/war/warcommon.js b/xtrn/war/warcommon.js
new file mode 100644
index 0000000000000000000000000000000000000000..87ebc22c615d53ba4a1367b261e492828d4b75e0
--- /dev/null
+++ b/xtrn/war/warcommon.js
@@ -0,0 +1,589 @@
+// From stdver
+const major_ver = 1;
+const minor_ver = 0;
+
+// defines
+const NATIONNMLEN = 14;
+const MAXCITIES = 150;
+const MAXMAPSZ = 160;
+const TIME_TO_DESERT = 7;
+const MAXARMIES = 2000;
+const ARMYNAMLEN = 14;
+
+const TRANS_SELF = 0;
+const TRANS_HERO = 1;
+const TRANS_ONE  = 2;
+const TRANS_ALL  = 3;
+
+const MAILFL     = "mail.%03d";
+const NEWSFL     = "news";
+const HEADERMARK = " \b";
+const MAILLOG    = "mail.log";
+const GAMEBAK    = "game.%03d";
+const MASTERFL   = "master.cmd";
+const MASTERBAK  = "master.%03d";
+const GAMESAVE   = "game.save.json";
+const PLAYERFL   = "%04d.cmd";
+
+// defined by loadmap()
+var map_width;
+var map_height;
+var map=[];
+var mapovl=[];
+
+function loadmap()
+{
+    var fp;
+    var inbuf='';
+    var rows, cols, i, j, m;
+
+    /* initialize map arrays */
+
+	fp = new File(game_dir+'/map');
+	if(!fp.open('rb'))
+		return 'Open Error';
+	if((inbuf = fp.readln())==null) {
+		fp.close();
+		return 'Read Error';
+	}
+	if(inbuf.substr(0, 2) != 'M ') {
+		fp.close();
+		return 'Invalid Header';
+	}
+
+	if((m=inbuf.match(/^M ([0-9]+) ([0-9]+)$/))==null || m[1] < 1 || m[2] < 1 || m[1] > MAXMAPSZ || m[2] > MAXMAPSZ) {
+		fp.close();
+		return 'Invalid Header';
+	}
+	map_height=rows=parseInt(m[1], 10);
+	map_width=cols=parseInt(m[2], 10);
+
+	fp.readln();
+
+    for(i = 0; i < rows; i++) {
+		map[i]=[];
+		mapovl[i]=[];
+        for(j = 0; j < cols; j++) {
+            map[i][j] = '~';
+            mapovl[i][j] = ' ';
+        }
+	}
+
+    for(i = 0; i < rows; i++) {
+		if((inbuf = fp.readln())==null) {
+			fp.close();
+			return 'Unexpected EOF';
+		}
+		for(j = 0; j<cols && j<inbuf.length; j++)
+			map[i][j] = inbuf.substr(j, 1) == ' ' ? '~' : inbuf.substr(j, 1);
+    }
+    fp.close();
+
+    return 0;
+}
+
+// defined by loadsave()
+var cities;
+var citycnt = 0;
+var ttypes;
+var ttypecnt = 0;
+var armies;
+var armycnt = 0;
+var move_table;
+var mvtcnt = 0;
+var world='';
+var nations;
+var nationcnt=0;
+var gen=0;
+
+const marks = [
+    "*ABCDEFGHIJKLMNOPQRSTUVWXYZ?",
+    "@abcdefghijklmnopqrstuvwxyz "
+];
+
+function loadsave() {
+	var game;
+	var i;
+	var fp=new File(game_dir+'/game.save.json');
+	if(!file_exists(fp.name))
+		fp=new File(game_dir+'/game.orig.json');
+
+	if(!fp.open('rb'))
+		return 'Open Error';
+
+	game=JSON.parse(fp.readAll().join('\n'));
+	fp.close();
+
+    /* add cities to map overlay */
+
+    for(i = 0; i < game.cities.length; i++) {
+        if(mapovl[game.cities[i].r][game.cities[i].c] == ' '
+        || marks[1].indexOf(mapovl[game.cities[i].r][game.cities[i].c]) != -1)
+            mapovl[game.cities[i].r][game.cities[i].c] = game.nations[game.cities[i].nation].mark;
+        else
+            mapovl[game.cities[i].r][game.cities[i].c] = '!';
+    }
+
+    /* clean up */
+
+	cities=game.cities;
+	ttypes=game.ttypes;
+	nations=game.nations;
+	armies=game.armies;
+	move_table=game.move_table;
+	world=game.world;
+
+    citycnt = game.cities.length;
+    ttypecnt = game.ttypes.length;
+    nationcnt = game.ncnt;
+    armycnt = game.armies.length;
+    mvtcnt = game.move_table.length;
+    gen = game.gen;
+
+    fp.close();
+
+    return 0;
+}
+
+var maint_in_progress = false;
+var news = new File(game_dir+'/news');
+function nation_news(name, city) {
+	if(maint_in_progress && news.is_open)
+		news.write(name+' becomes the ruler of '+cities[city].name+'!\r\n\r\n');
+}
+
+function instance(n)
+{
+	var buff;
+	
+    if(n > 10 && n < 20) {
+        buff = format("%dth", n);
+        return buff;
+    }
+
+    switch(n % 10) {
+    case 1 :
+        buff = format("%dst", n);
+        break;
+
+    case 2 :
+        buff = format("%dnd", n);
+        break;
+
+    case 3 :
+        buff = format("%drd", n);
+        break;
+
+    default :
+        buff = format("%dth", n);
+        break;
+    }
+
+    return buff;
+}
+
+var privtable = {
+	"global-update":function(argc, argv) {
+		var i, k, n, t, cnt, xch, max;
+
+		/* pack army list */
+
+		do {
+			xch = 0;
+
+			for(k = 0; k < armycnt; k++)
+				if(armies[k].nation == -1)
+					break;
+
+			if(k < armycnt) {
+				for(i = armycnt - 1; i >= k; i--)
+					if(armies[i].nation != -1) 
+						break;
+					else
+						armycnt--;
+
+				if(i > k) {
+					armies[k].name = armies[i].name;
+					armies[k].nation = armies[i].nation;
+					armies[k].r = armies[i].r;
+					armies[k].c = armies[i].c;
+					armies[k].combat = armies[i].combat;
+					armies[k].hero = armies[i].hero;
+					armies[k].move_rate = armies[i].move_rate;
+					armies[k].move_tbl = armies[i].move_tbl;
+					armies[k].special_mv = armies[i].special_mv;
+					armies[k].eparm1 = armies[i].eparm1;
+
+					armycnt--;
+
+					xch = 1;
+				}
+			}
+		} while(xch);
+
+		/* create new armies */
+
+		for(i = 0; i < citycnt; i++) {
+
+			cnt = 0;
+
+			for(k = 0; k < armycnt; k++)
+				if(armies[k].nation == cities[i].nation
+				&& armies[k].r == cities[i].r
+				&& armies[k].c == cities[i].c)
+					cnt++;
+
+			max = cities[i].defense * 2;
+
+			if(max > 10)
+				max = 10;
+
+			if(cities[i].nation != 0) {
+				max = 12;
+				k = cities[i].nation;
+				if(nations[k].idle_turns >= TIME_TO_DESERT)
+					max = 0;
+			}
+
+			if(cnt < max) {
+
+				n = cities[i].prod_type;
+
+				if(n >= 0 && n < 4) {
+					cities[i].turns_left--;
+					if(cities[i].turns_left < 1) {
+						if(armycnt < MAXARMIES - 1) {
+							t = cities[i].types[n];
+
+							armies[armycnt] = {};
+							armies[armycnt].name = format(".%03d/%03d/%03d"
+										, i, t, ++cities[i].instance[n]);
+
+							armies[armycnt].nation = cities[i].nation;
+							armies[armycnt].r = cities[i].r;
+							armies[armycnt].c = cities[i].c;
+
+							armies[armycnt].combat = ttypes[t].combat;
+							armies[armycnt].hero = 0;
+
+							armies[armycnt].move_rate = ttypes[t].move_rate;
+							armies[armycnt].move_tbl = ttypes[t].move_tbl;
+							armies[armycnt].special_mv =
+												ttypes[t].special_mv;
+							armies[armycnt].eparm1 = 0;
+
+							armycnt++;
+
+							cities[i].turns_left = cities[i].times[n];
+
+						} else
+							cities[i].turns_left = 0;
+					}
+				}
+			}
+		}
+
+		/* update all armies' movement. */
+
+		for(i = 0; i < armycnt; i++)
+			armies[i].move_left = armies[i].move_rate;
+
+		gen++;
+
+		return 0;
+	},
+    "new-nation":function(argc, argv) {
+		var i, r, c;
+
+		/* if in war update, add news entry */
+
+		nation_news(argv[1], parseInt(argv[3],10));
+
+		/* create nation entry */
+
+		nations[nationcnt].name = argv[1];
+		nations[nationcnt].uid = parseInt(argv[2], 10);
+		nations[nationcnt].city = parseInt(argv[3], 10);
+		nations[nationcnt].mark = argv[4].substr(0, 1);
+
+		/* transfer armies */
+
+		r = cities[nations[nationcnt].city].r;
+		c = cities[nations[nationcnt].city].c;
+
+		for(i = 0; i < armycnt; i++)
+			if(armies[i].r == r
+			&& armies[i].c == c
+			&& armies[i].nation == 0)
+				armies[i].nation = nationcnt;
+
+		/* clean up */
+
+		nationcnt++;
+
+		return 0;
+	},
+    "control-city":function(argc, argv) {
+		var c;
+
+		cities[c = parseInt(argv[2], 10)].nation = parseInt(argv[1], 10);
+
+		if(argv[3] != undefined && parseInt(argv[3], 10) > 0)
+			cities[c].turns_left = cities[c].times[cities[c].prod_type] + 1;
+
+		return 0;
+	},
+    "kill-army":function(argc, argv) {
+		var a, i, n;
+
+		a = parseInt(argv[1], 10);
+
+		if(a == -2) {
+			i = parseInt(argv[2], 10);
+			n = parseInt(argv[3], 10);
+			if(n > 0) {
+				armies[i].nation = n;
+				if(armies[i].hero > 1)
+					armies[i].hero--;
+				return 0;
+			}
+			a = i;
+		}
+
+		if(a == -1) {
+			n = parseInt(argv[2], 10);
+			if(n < 1 || n > nationcnt)
+				return 0;
+			for(i = 0; i < armycnt; i++)
+				if(armies[i].nation == n) {
+					armies[i].nation = -1;
+					armies[i].r = -1;
+					armies[i].c = -1;
+				}
+			return 0;
+		}
+
+		armies[a].nation = -1;
+		armies[a].r = -1;
+		armies[a].c = -1;
+
+		return 0;
+	},
+    "move-army":function(argc, argv) {
+		var a, b;
+
+		a = parseInt(argv[1], 10);
+
+		if(armies[a].nation == -1)
+			return 0;
+
+		b = armies[a].move_left;
+		b -= parseInt(argv[2], 10);
+		if(b < 0)
+			b = 0;
+		armies[a].move_left = b;
+		armies[a].r = parseInt(argv[3], 10);
+		armies[a].c = parseInt(argv[4], 10);
+
+		return 0;
+	},
+    "make-army":function(argc, argv) {
+		/* no error, just don't do it. */
+
+		if(armycnt >= MAXARMIES)
+			return 0;
+
+		armies[armycnt] = {
+			name:argv[1].substr(0, ARMYNAMLEN),
+			nation:parseInt(argv[2], 10),
+			r:parseInt(argv[3], 10),
+			c:parseInt(argv[4], 10),
+			combat:parseInt(argv[5], 10),
+			hero:parseInt(argv[6], 10),
+			move_rate:parseInt(argv[7], 10),
+			move_left:parseInt(argv[7], 10),
+			move_tbl:parseInt(argv[8], 10),
+			special_mv:parseInt(argv[9], 10),
+			eparm1:parseInt(argv[10], 10)
+		};
+
+		armycnt++;
+
+		return 0;
+	},
+    "name-army":function(argc, argv) {
+		var a;
+
+		a = parseInt(argv[1], 10);
+
+		if(armies[a].nation == -1)
+			return 0;
+
+		armies[a].name = argv[2].substr(0, ARMYNAMLEN);
+
+		return 0;
+	},
+    "change-army":function(argc, argv) {
+		var a, c, h;
+
+		a = parseInt(argv[1], 10);
+		c = parseInt(argv[2], 10);
+		h = parseInt(argv[3], 10);
+
+		if(armies[a].nation == -1)
+			return 0;
+
+		if(c >= 0) armies[a].combat = c;
+		if(h >= 0) armies[a].hero = h;
+
+		return 0;
+	},
+    "set-eparm":function(argc, argv) {
+		var a;
+
+		a = parseInt(argv[1], 10);
+
+		if(armies[a].nation == -1)
+			return 0;
+
+		armies[a].eparm1 = parseInt(argv[2], 10);
+
+		return 0;
+	},
+    "set-produce":function(argc, argv) {
+		var c;
+
+		c = parseInt(argv[1], 10);
+
+		cities[c].prod_type = parseInt(argv[2], 10);
+		cities[c].turns_left = cities[c].times[cities[c].prod_type];
+
+		return 0;
+	}
+};
+
+function parseline(line) {
+	var i;
+	var s;
+	var args=[];
+
+	i = 0;
+
+	while(line.length > 0 && i++ < 20) {
+		line=line.replace(/^\s*((?:'.*?')|(?:[^'\s][^\s]*))\s*/, function(m, str) {
+			str=str.replace(/^'(.*)'$/,"$1");
+			args.push(str);
+			return '';
+		});
+	}
+
+	return args;
+}
+
+function execpriv(line)
+{
+    var args=[];
+    var n;
+
+    args = parseline(line);
+
+    if(args.length == 0)
+        return 'No Text on Line';
+
+	if(privtable[args[0]] == undefined)
+		return 'No Such Command';
+
+	return privtable[args[0]](args.length, args);
+}
+
+function my_city_at(r, c, n)
+{
+    var i;
+
+    for(i = 0; i < citycnt; i++)
+        if((n < 0 || cities[i].nation == n)
+        && cities[i].r == r
+        && cities[i].c == c)
+            return i;
+
+    return -1;
+}
+
+function city_at(r, c)
+{
+    return my_city_at(r, c, -1);
+}
+
+function nationcity(n)
+{
+    if(n == 0)  return "Militia";
+    if(n == 27) return "Rogue";
+
+    return cities[nations[n].city].name;
+}
+
+function armyname(a)
+{
+    var c, t, i, m;
+    var buff;
+
+    if(armies[a].name.substr(0, 1) != '.')
+        return armies[a].name;
+
+    c = 0;
+    t = 0;
+    i = -1;
+
+	m=armies[a].name.match(/([0-9]+)\/([0-9]+)\/([0-9]+)/);
+	if(m==null)
+		return "????";
+	c=parseInt(m[1], 10);
+	t=parseInt(m[2], 10);
+	i=parseInt(m[3], 10);
+
+	buff = cities[c].name+' '+instance(i)+' '+ttypes[t].name;
+	return buff;
+}
+
+function isgreater(a1, a2)
+{
+    var c1, c2, t1, t2, i1, i2;
+    var buf1='';
+    var buf2='';
+    var m;
+
+    if(armies[a1].hero > armies[a2].hero) return 1;
+    if(armies[a1].hero < armies[a2].hero) return 0;
+
+    if(armies[a1].special_mv > armies[a2].special_mv) return 1;
+    if(armies[a1].special_mv < armies[a2].special_mv) return 0;
+
+    if(armies[a1].combat > armies[a2].combat) return 1;
+    if(armies[a1].combat < armies[a2].combat) return 0;
+
+    if(armies[a1].move_rate > armies[a2].move_rate) return 1;
+    if(armies[a1].move_rate < armies[a2].move_rate) return 0;
+
+    if(armies[a1].name.substr(0,1) != '.' && armies[a2].name.substr(0,1) == '.')
+        return 1;
+
+    if(armies[a1].name.substr(0,1) == '.' && armies[a2].name.substr(0,1) != '.')
+        return 0;
+
+    if(armies[a1].name.substr(0,1) != '.' && armies[a2].name.substr(0,1) != '.')
+        if(armies[a1].name > armies[a2].name)
+            return 1;
+        else
+            return 0;
+
+	if((m=armies[a1].name.match(/^\.([0-9]+)\/([0-9]+)\/([0-9]+)$/))!=null)
+		buf1=format("%03d%03d%03d", parseInt(m[1], 10),parseInt(m[2], 10),parseInt(m[3], 10));
+	if((m=armies[a2].name.match(/^\.([0-9]+)\/([0-9]+)\/([0-9]+)$/))!=null)
+		buf2=format("%03d%03d%03d", parseInt(m[1], 10),parseInt(m[2], 10),parseInt(m[3], 10));
+
+    if(buf1 > buf2)
+        return 1;
+
+    return 0;
+}
+
diff --git a/xtrn/war/warupd.js b/xtrn/war/warupd.js
new file mode 100644
index 0000000000000000000000000000000000000000..4486e3411e32abc597000cf4253f12a97751c318
--- /dev/null
+++ b/xtrn/war/warupd.js
@@ -0,0 +1,942 @@
+var game_dir = js.exec_dir;
+/*
+    Solomoriah's WAR!
+
+    warupd.c -- main procedure file for war update
+
+    Copyright 2013 Stephen Hurd
+    All rights reserved.
+
+    3 Clause BSD License
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions
+    are met:
+
+    Redistributions of source code must retain the above copyright
+    notice, self list of conditions and the following disclaimer.
+
+    Redistributions in binary form must reproduce the above copyright
+    notice, self list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+
+    Neither the name of the author nor the names of any contributors
+    may be used to endorse or promote products derived from self software
+    without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+    "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+    FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+    AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+    SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+    LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+    DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+    THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+    OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+
+// Based on:
+/*
+    Solomoriah's WAR!
+
+    warupd.c -- main procedure file for war update
+
+    Copyright 1993, 1994, 2001, 2013 Chris Gonnerman
+    All rights reserved.
+
+    3 Clause BSD License
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions
+    are met:
+
+    Redistributions of source code must retain the above copyright
+    notice, self list of conditions and the following disclaimer.
+
+    Redistributions in binary form must reproduce the above copyright
+    notice, self list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+
+    Neither the name of the author nor the names of any contributors
+    may be used to endorse or promote products derived from self software
+    without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+    "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+    FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+    AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+    SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+    LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+    DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+    THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+    OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+load(game_dir+'/warcommon.js');
+
+var mfile;
+
+var nlist=[];
+var nlcnt;
+function shuffle()
+{
+    var i, n1, n2, tmp;
+
+    nlcnt = 0;
+
+    for(i = 1; i < nationcnt; i++)
+        nlist[nlcnt++] = i;
+
+    for(i = 0; i < nlcnt * nlcnt; i++) {
+        n1 = random(nlcnt);
+        n2 = random(nlcnt);
+        if(n1 != n2) {
+            tmp = nlist[n1];
+            nlist[n1] = nlist[n2];
+            nlist[n2] = tmp;
+        }
+    }
+}
+
+var usertable = {
+    "move-army":function(argc, argv) {
+		var a, b;
+
+		a = parseInt(argv[1], 10);
+
+		if(armies[a].nation == -1)
+			return 0;
+
+		if(argc > 5) {
+			b = parseInt(argv[5], 10);
+
+			if(a != b && armies[b].nation == -1)
+				return 0;
+		}
+
+		b = armies[a].move_left;
+		b -= parseInt(argv[2], 10);
+		if(b < 0)
+			b = 0;
+		armies[a].move_left = b;
+		armies[a].r = parseInt(argv[3], 10);
+		armies[a].c = parseInt(argv[4], 10);
+
+		if(argc > 5)
+			mfile.printf("move-army %s %s %s %s %s\n",
+				argv[1], argv[2], argv[3], argv[4], argv[5]);
+		else
+			mfile.printf("move-army %s %s %s %s\n",
+				argv[1], argv[2], argv[3], argv[4]);
+
+		return 0;
+	},
+    "make-army":function(argc, argv) {
+		/* no error, just don't do it. */
+
+		if(armycnt >= MAXARMIES)
+			return 0;
+
+		armies[armycnt].name = argv[1].substr(0, ARMYNAMLEN);
+		armies[armycnt].nation = parseInt(argv[2], 10);
+		armies[armycnt].r = parseInt(argv[3], 10);
+		armies[armycnt].c = parseInt(argv[4], 10);
+		armies[armycnt].combat = parseInt(argv[5], 10);
+		armies[armycnt].hero = parseInt(argv[6], 10);
+		armies[armycnt].move_rate = parseInt(argv[7], 10);
+		armies[armycnt].move_left = parseInt(argv[7], 10);
+		armies[armycnt].move_tbl = parseInt(argv[8], 10);
+		armies[armycnt].special_mv = parseInt(argv[9], 10);
+		armies[armycnt].eparm1 = 0;
+
+		armycnt++;
+
+		mfile.printf("make-army '%s' %s %s %s %s %s %s %s %s\n",
+			argv[1], argv[2], argv[3],
+			argv[4], argv[5], argv[6],
+			argv[7], argv[8], argv[9]);
+
+		return 0;
+	},
+    "name-army":function(argc, argv) {
+		var a;
+
+		a = parseInt(argv[1], 10);
+
+		if(armies[a].nation == -1)
+			return 0;
+
+		armies[a].name = argv[2].substr(0, ARMYNAMLEN);
+
+		mfile.printf("name-army %s '%s'\n", argv[1], argv[2]);
+
+		return 0;
+	},
+    "set-produce":function(argc, argv) {
+		var c;
+
+		c = parseInt(argv[1], 10);
+
+		cities[c].prod_type = parseInt(argv[2], 10);
+		cities[c].turns_left = cities[c].times[cities[c].prod_type];
+
+		mfile.printf("set-produce %s %s\n", argv[1], argv[2]);
+
+		return 0;
+	}
+};
+
+function execuser(line)
+{
+    var args;
+    var n;
+
+    args = parseline(line);
+
+    if(args.length == 0)
+        return 5;
+
+	if(usertable[args[0]] != undefined)
+		return usertable[args[0]](args.length, args);
+	return 6;
+}
+
+var mail_gen = 0;
+function mail_line(text, ntn)
+{
+    var i, pos;
+    var fname;
+	var mailfiles = [
+		{ntn:-1, age:0, fp:null},
+		{ntn:-1, age:0, fp:null},
+		{ntn:-1, age:0, fp:null},
+		{ntn:-1, age:0, fp:null},
+		{ntn:-1, age:0, fp:null},
+		{ntn:-1, age:0, fp:null},
+		{ntn:-1, age:0, fp:null},
+		{ntn:-1, age:0, fp:null}
+	];
+
+    if(ntn == -1) { /* close all */
+        for(i = 0; i < 8; i++) {
+            if(mailfiles[i].fp != null)
+				mailfiles[i].fp.close();
+
+            mailfiles[i].ntn = -1;
+            mailfiles[i].age = 0;
+            mailfiles[i].fp = null;
+        }
+        return;
+    }
+
+    if(ntn == 0 || ntn == 27) /* ignore god and rogue */
+        return;
+
+    /* find the nation's mail file if already open... */
+
+    for(i = 0; i < 8; i++)
+        if(mailfiles[i].ntn == ntn) {
+            mailfiles[i].age = mail_gen++;
+            break;
+        }
+
+    if(i >= 8) { /* not open. */
+        pos = 0;
+
+        for(i = 1; i < 8; i++)
+            if(mailfiles[i].age < mailfiles[pos].age)
+                pos = i;
+
+        if(mailfiles[pos].fp != null)
+			mailfiles[pos].fp.close();
+
+        mailfiles[pos].ntn = -1;
+
+        fname = game_dir+'/'+format(MAILFL, ntn);
+        mailfiles[pos].fp = new File(fname);
+
+        if(!mailfiles[pos].fp.open('ab')) /* error, can't stop now... */
+            return;
+
+        mailfiles[pos].ntn = ntn;
+        mailfiles[pos].age = mail_gen++;
+
+    } else
+        pos = i;
+
+    mailfiles[pos].fp.write(text);
+}
+
+function message_out(text, n1, n2, do_news)
+{
+    if(n1)
+        mail_line(text, n1);
+
+    if(n2)
+        mail_line(text, n2);
+
+    if(do_news)
+        news.write(text);
+
+    print(text);
+}
+
+function capture(n, c)
+{
+	var buff;
+	var n2;
+
+	n2 = cities[c].nation;
+
+	buff = nationcity(n)+" captures "+cities[c].name;
+	message_out(buff, n, n2, 1);
+
+	if(cities[c].nation > 0) {
+		buff = " from "+nationcity(n2)+"\n";
+		message_out(buff, n, n2, 1);
+	} else
+		message_out("\n", n, n2, 1);
+
+	buff = "control-city "+n+" "+c+" 1\n";
+	mfile.write(buff);
+	execpriv(buff);
+}
+
+/*
+	make_stack forms the stack of armies which includes army a.
+*/
+
+function make_stack(stack, a)
+{
+	var i, n, r, c, h;
+
+	n = armies[a].nation;
+	r = armies[a].r;
+	c = armies[a].c;
+
+	stack.count = 0;
+	stack.ctot = 0;
+	stack.hero = -1;
+	h = 0;
+
+	for(i = 0; stack.count < 12 && i < armycnt; i++)
+		if(armies[i].nation == n
+		&& armies[i].r == r
+		&& armies[i].c == c) {
+			stack.index[stack.count] = i;
+			if(armies[i].hero > h) {
+				stack.hero = stack.count;
+				h = armies[i].hero;
+			}
+			stack.ctot += armies[i].combat;
+			stack.count++;
+		}
+
+	stack.ctot += stack.count * h;
+
+	stack.city = city_at(r, c);
+
+	if(cities[stack.city].nation != n)
+		stack.city = -1;
+
+	if(stack.city != -1)
+		stack.ctot += stack.count * cities[stack.city].defense;
+}
+
+function least(stack)
+{
+	var i, n;
+
+	n = 0;
+
+	for(i = 0; i < stack.count; i++)
+		if(isgreater(stack.index[n], stack.index[i]))
+			n = i;
+
+	return n;
+}
+
+function stack_remove(stack, idx)
+{
+	var i, h;
+
+	if(stack.count < 1)
+		return;
+
+	stack.count--;
+
+	if(idx < stack.count)
+		stack.index[idx] = stack.index[stack.count];
+	
+	stack.ctot = 0;
+	stack.hero = -1;
+	h = 0;
+
+	for(i = 0; i < stack.count; i++) { 
+		stack.ctot += armies[stack.index[i]].combat;
+		if(armies[stack.index[i]].hero > h) {
+			stack.hero = i;
+			h = armies[stack.index[i]].hero;
+		}
+	}
+	
+	stack.ctot += stack.count * h;
+
+	if(stack.city != -1)
+		stack.ctot += stack.count * cities[stack.city].defense;
+}
+
+function advance(hero)
+{
+    var res;
+	var buff;
+
+    print("advance "+hero+"\n");
+
+    res = random(9) + 1;
+
+    if(res <= (armies[hero].hero + armies[hero].combat))
+        return;
+
+    if(armies[hero].combat < 7 
+    && random(8) >= armies[hero].combat) {
+        print("advance "+hero+" combat\n");
+		buff = "change-army "+hero+" "+armies[hero].combat + 1+" "+armies[hero].hero+"\n";
+		mfile.write(buff);
+		execpriv(buff);
+        return;
+    }
+
+    if(armies[hero].hero < 3
+    && random(4) >= armies[hero].hero) {
+        print("advance "+hero+" hero\n");
+		buff = "change-army "+hero+" "+armies[hero].combat+" "+armies[hero].hero + 1+"\n";
+		mfile.write(buff);
+		execpriv(buff);
+    }
+}
+
+function battle(a, b)
+{
+	var stacks = [
+		{ctot:0, hero:0, count:0, city:0, index:[0,0,0,0,0,0,0,0,0,0,0,0]},
+		{ctot:0, hero:0, count:0, city:0, index:[0,0,0,0,0,0,0,0,0,0,0,0]}
+	];
+	var ntns=[0,0];
+	var r, c, city, hi, total, rlose, rwin, l, i, d, dn;
+	var names, buff;
+
+	ntns[0] = armies[a].nation;
+	ntns[1] = armies[b].nation;
+
+	names[0] = nationcity(ntns[0]);
+	names[1] = nationcity(ntns[1]);
+
+	r = armies[a].r;
+	c = armies[a].c;
+	city = city_at(r, c);
+
+	buff = "Battle between "+names[0]+" and "+names[1];
+	message_out(buff, ntns[0], ntns[1], 1);
+
+	if(city != -1) {
+		buff = " in "+cities[city].name;
+		message_out(buff, ntns[0], ntns[1], 1);
+	}
+
+	buff = " (Turn "+gen+")";
+	message_out(buff, ntns[0], ntns[1], 0);
+
+	message_out("\n", ntns[0], ntns[1], 1);
+
+	make_stack(stacks[0], a);
+	make_stack(stacks[1], b);
+
+	buff = "(Odds:  "+stacks[0].ctot+" to "+stacks[1].ctot+")\n";
+	message_out(buff, ntns[0], ntns[1], 0);
+
+	for(i = 0; i < 2; i++) {
+
+		buff = names[i]+" has "+stacks[i].count+" armies";
+		message_out(buff, ntns[0], ntns[1], 1);
+
+		if((hi = stacks[i].hero) != -1) {
+			buff = " led by " +
+				armies[stacks[i].index[hi]].name[0] == '\0'
+					? "a nameless hero"
+					: armies[stacks[i].index[hi]].name;
+			buff += '\n';
+			message_out(buff, ntns[0], ntns[1], 1);
+		} else
+			message_out("\n", ntns[0], ntns[1], 1);
+	}
+
+	while(stacks[0].count > 0 && stacks[1].count > 0) {
+
+		total = stacks[0].ctot + stacks[1].ctot;
+
+		/* roll dem bones */
+
+		if(random(total) < stacks[0].ctot)
+			rlose = 1;
+		else
+			rlose = 0;
+
+		rwin = (rlose + 1) % 2;
+
+		/* check for hero desertion */
+
+		d = -1;
+
+		if(stacks[rlose].ctot < parseInt(stacks[rwin].ctot / 2)
+		&& (hi = stacks[rlose].hero) != -1
+		&& armies[stacks[rlose].index[hi]].eparm1 != 1) {
+			if(random(10) < 5) {
+				dn = -1;
+				if(stacks[rwin].count < 12 && random(10) < 5)
+					dn = ntns[rwin];
+				d = hi;
+			} else {
+				buff = "set-eparm "+stacks[d].index[hi]+" 1\n";
+				mfile.write(buff);
+				execpriv(buff);
+			}
+		}
+
+		/* find the victim */
+
+		if(d == -1) {
+			l = least(stacks[rlose]);
+
+			buff = armyname(stacks[rlose].index[l])+" ("+names[rlose]+") is destroyed.\n";
+			message_out(buff, ntns[0], ntns[1], 0);
+
+			if(armies[stacks[rlose].index[l]].hero > 0)
+				news.write(buff);
+
+			/* kill an army */
+
+			buff = "kill-army "+stacks[rlose].index[l]+"\n";
+			mfile.write(buff);
+			execpriv(buff);
+
+		} else {
+			l = d;
+
+			buff = armyname(stacks[rlose].index[l])+" ("+names[rlose]+") deserts";
+			message_out(buff, ntns[0], ntns[1], 1);
+
+			if(dn != -1) {
+				buff = " and joins "+nationcity(dn)+"\n";
+				message_out(buff, ntns[0], ntns[1], 1);
+			} else
+				message_out("\n", ntns[0], ntns[1], 1);
+
+			/* hero deserts */
+
+			buff = "kill-army -2 "+stacks[rlose].index[d]+" "+dn+"\n";
+			mfile.write(buff);
+			execpriv(buff);
+
+			/* rebuild other stack around the deserter */
+
+			if(dn != -1)
+			    make_stack(stacks[rwin], d);
+		}
+
+		/* remove army from stack */
+
+		stack_remove(stacks[rlose], l);
+	}
+
+	if(stacks[0].count < 1)
+		rwin = 1;
+	else
+		rwin = 0;
+
+	buff = names[rwin]+" wins!\n";
+	message_out(buff, ntns[0], ntns[1], 1);
+
+	if(city != -1
+	&& cities[city].nation != ntns[rwin])
+		capture(ntns[rwin], city);
+
+	if((hi = stacks[rwin].hero) != -1)
+        advance(stacks[rwin].index[hi]);
+}
+
+function combat(n)
+{
+	var i, j, c;
+
+	for(i = 0; i < armycnt; i++)
+		if(armies[i].nation == n)
+			for(j = 0; j < armycnt; j++)
+				if(armies[j].nation != n
+				&& armies[j].r == armies[i].r
+				&& armies[j].c == armies[i].c) {
+
+					mail_line(HEADERMARK, armies[i].nation);
+					mail_line(HEADERMARK, armies[j].nation);
+
+					battle(i, j);
+					print('\n');
+					news.write('\n');
+					break;
+				}
+
+	/* all battles are now over. */
+	/* rescan the armies table for armies attacking undefended cities */
+	/* must scan separately since armies may have died in battle */
+
+	for(i = 0; i < armycnt; i++)
+		if(armies[i].nation == n)
+			if((c = city_at(armies[i].r, armies[i].c)) != -1
+			&& cities[c].nation != n) {
+
+				mail_line(HEADERMARK, armies[i].nation);
+				mail_line(HEADERMARK, cities[c].nation);
+
+				capture(armies[i].nation, c);
+				print('\n');
+				news.write('\n');
+			}
+}
+
+/*
+	deserter() causes a randomly-selected non-hero army to desert the 
+	given nation.
+*/
+
+function deserter(n)
+{
+	var narmies, i, die;
+	var buff;
+
+	narmies = 0;
+
+	for(i = 0; i < armycnt; i++)
+		if(armies[i].nation == n
+		&& armies[i].hero < 1)
+			narmies++;
+
+	if(narmies < 1)
+		return;
+
+	die = random(narmies);
+
+	for(i = 0; i < armycnt; i++)
+		if(armies[i].nation == n
+		&& armies[i].hero < 1)
+			if(die == 0)
+				break;
+			else
+				die--;
+
+
+	/* found one, kill it. */
+
+	mail_line(" \b", n);
+	buff = armyname(i)+" deserts "+nations[n].name+" of "+nationcity(n)+".";
+	message_out(buff, n, 0, 1);
+
+	buff = " (Turn "+gen+")";
+	message_out(buff, n, 0, 0);
+
+	message_out("\n\n", n, 0, 1);
+
+	/* so kill it. */
+
+	buff = "kill-army "+i+"\n";
+	mfile.write(buff);
+	execpriv(buff);
+}
+
+/*
+	creator() constructs a hero for the given nation, *if* the nation
+	needs one and if a roll indicates one is to be created.
+
+	a nation "needs" a hero when it has more cities than heros.
+
+	a roll is then made using (number of cities) - (number of heros)
+	as a percent chance EXCEPT if the nation has NO heros; then the
+    odds are 10 times normal.  Maximum odds are 90% in either case.
+*/
+
+function creator(n)
+{
+	var nheros, ncities, odds, counter, i, c, r, t, mtbl;
+	var buff;
+
+	ncities = 0;
+
+	for(i = 0; i < citycnt; i++)
+		if(cities[i].nation == n)
+			ncities++;
+
+	nheros = 0;
+
+	for(i = 0; i < armycnt; i++)
+		if(armies[i].nation == n
+		&& armies[i].hero > 0)
+			nheros++;
+
+	odds = ncities - nheros;
+
+	if(nheros == 0)
+		odds *= 10;
+
+    if(odds > 90)
+        odds = 90;
+
+	if(nheros >= ncities
+	|| random(100) >= odds)
+		return;
+
+	r = random(ncities);
+
+	for(i = 0; i < citycnt; i++)
+		if(cities[i].nation == n)
+			if(r-- < 1)
+				break;
+
+	c = i;
+
+	/* too many armies there? */
+
+	counter = 0;
+
+	for(i = 0; i < armycnt; i++)
+		if(armies[i].nation == n
+		&& armies[i].r == cities[c].r
+		&& armies[i].c == cities[c].c)
+			counter++;
+
+	if(counter >= 12)
+		return;
+
+	/* it's OK, do it. */
+
+	mail_line(" \b", n);
+	buff = "A hero arises in "+cities[c].name+" and joins "+nations[n].name+" of "+nationcity(n)+"!";
+	message_out(buff, n, 0, 1);
+
+	buff = " (Turn "+gen+")";
+	message_out(buff, n, 0, 0);
+
+	message_out("\n\n", n, 0, 1);
+
+	t = cities[c].types[0];
+	mtbl = ttypes[t].move_tbl;
+
+	buff = format("make-army '' %d %d %d %d %d %d %d %d %d\n",
+		   n, cities[c].r, cities[c].c,
+		   random(4)+2, random(2)+1, 8, mtbl, 0, 0);
+
+	mfile.write(buff);
+	execpriv(buff);
+}
+
+function savegame(fp)
+{
+	var game={};
+
+	game.cities=cities;
+	game.ttypes=ttypes;
+	game.nations=nations;
+	game.armies=armies;
+	game.move_table=move_table;
+	game.world=world;
+    game.cities.length=citycnt;
+    game.ttypes.length=ttypecnt;
+    game.ncnt=nationcnt;
+    game.armies.length=armycnt;
+    game.move_table.length=mvtcnt;
+    game.gen=gen;
+    fp.write(JSON.stringify(game, null, '\t'));
+}
+
+function main(argc, argv)
+{
+    var rc, i, j, k, n, u;
+    var fp;
+    var filename, inbuf, p;
+
+    print(format("\nJSWARUPD Version %d.%d  \"Code by Solomoriah\"\n", 
+        major_ver, minor_ver));
+    print("Original Copyright 1993, 1994, 2001, 2013, Chris Gonnerman\n");
+    print("JavaScript Version Copyright 2013, Stephen Hurd\n");
+    print("All Rights Reserved.\n\n");
+
+    
+    /* load map file */
+
+    rc = loadmap();
+
+    if(rc != 0) {
+        print("Error Loading Map ("+rc+")\n");
+        exit(1);
+    }
+
+    /* load game save */
+
+    rc = loadsave();
+
+    if(rc != 0) {
+        print("Error Loading Game Save ("+rc+")\n");
+        exit(1);
+    }
+
+    if(world.length != 0)
+        print("World:  "+world+"\n");
+
+    /* open news output */
+
+    if(!news.open('ab')) {
+        print("Error Writing News File <"+news.name+">\n");
+        exit(10);
+    }
+    maint_in_progress = true;
+
+    print("Turn Update "+gen+"\n\n");
+
+    if(world.length != 0) {
+        news.write(" \b");
+        news.write(world);
+    } else
+        news.write(" \bSolomoriah's WAR!");
+
+    news.write(" News Report     Turn "+gen+"\n\n");
+
+    /* execute master file */
+
+    print("Reading Master Commands...\r\n");
+
+	fp = new File(game_dir+'/'+MASTERFL);
+
+    if(fp.open('rb')) {
+        for(i = 0; (inbuf = fp.readln()) != null; i++) {
+            rc = execpriv(inbuf);
+            if(rc != 0) {
+                print("Master Cmd Failed, Line "+(i+1)+", Code "+rc+"\n");
+                exit(2);
+            }
+        }
+
+        fp.close();
+    }
+
+    /* open master for writing. */
+
+	mfile = new File(game_dir+'/'+MASTERFL);
+
+    if(!mfile.open('ab')) {
+        print("Can't Append to Master File");
+        exit(5);
+    }
+
+    /* execute player commands */
+
+    print("Reading Player Commands...\r\n");
+
+    shuffle();
+
+    for(k = 0; k < nlcnt; k++) {
+
+        n = nlist[k];
+        u = nations[n].uid;
+
+        filename = format(PLAYERFL, u);
+
+        fp = new File(game_dir+'/'+filename);
+
+        if(fp.open("rb")) {
+
+            print("\n"+nations[n].name+" of "+nationcity(n)+" moves...\n");
+
+            nations[n].idle_turns = 0;
+
+            for(i = 0; (inbuf = fp.readln()) != null; i++) {
+                rc = execuser(inbuf);
+                if(rc != 0) {
+                    printf("Player Cmd Failed, Line "+(i+1)+", Code "+rc+"  ");
+                    exit(2);
+                }
+            }
+
+            fp.close();
+
+            file_remove(fp.name);
+        } else {
+            print("\n"+nations[n].name+" of "+nationcity(n)+" is idle.\n");
+print("FILE: "+fp.name);
+            nations[n].idle_turns++;
+        }
+
+        combat(n);
+
+        if(nations[n].idle_turns >= TIME_TO_DESERT)
+            deserter(n);
+        else
+            creator(n);
+    }
+
+    /* do the update */
+
+    print("Global Update...\n");
+
+    execpriv("global-update");
+    mfile.write("global-update\n");
+
+    /* close up */
+
+    news.close();
+    mfile.close();
+
+    mail_line(null, -1);
+
+    /* consolidate */
+
+    filename = format(MASTERBAK, gen);
+
+    if(!file_rename(game_dir+'/'+MASTERFL, game_dir+'/'+filename)) {
+        print("Can't Rename Master Cmd File\n");
+        exit(9);
+    }
+
+    filename = format(filename, GAMEBAK, gen);
+
+    if(file_exists(game_dir+'/'+GAMESAVE) && !file_rename(game_dir+'/'+GAMESAVE, game_dir+'/'+filename)) {
+        print("Can't Rename Game Save\n");
+        exit(9);
+    }
+
+	fp = new File(game_dir+'/'+GAMESAVE);
+
+    if(!fp.open('wb')) {
+        print("Can't Create New Save File\n");
+        exit(9);
+    }
+
+    /* clean up outdated files. */
+
+    if(gen - 4 > 0) {
+        filename = game_dir+'/'+format(MASTERBAK, gen - 4);
+        file_remove(filename);
+
+        filename = game_dir+'/'+format(GAMEBAK, gen - 4);
+        file_remove(filename);
+    }
+
+    savegame(fp);
+
+    fp.close();
+
+    exit(0);
+}
+
+main(argc, argv);
diff --git a/xtrn/war/worlds/alderon/game.orig.json b/xtrn/war/worlds/alderon/game.orig.json
new file mode 100644
index 0000000000000000000000000000000000000000..58253337eb2af2e9a9019b5abcc6c8793d4cee94
--- /dev/null
+++ b/xtrn/war/worlds/alderon/game.orig.json
@@ -0,0 +1,2047 @@
+{
+	"ncnt": 1,
+	"nations": [
+		{
+			"name": "Overlord",
+			"uid": 0,
+			"city": 0,
+			"mark": "*",
+			"idle_turns": 0
+		},
+		{
+			"name": "",
+			"uid": 0,
+			"city": 0,
+			"mark": "*",
+			"idle_turns": 0
+		},
+		{
+			"name": "",
+			"uid": 0,
+			"city": 0,
+			"mark": "*",
+			"idle_turns": 0
+		},
+		{
+			"name": "",
+			"uid": 0,
+			"city": 0,
+			"mark": "*",
+			"idle_turns": 0
+		},
+		{
+			"name": "",
+			"uid": 0,
+			"city": 0,
+			"mark": "*",
+			"idle_turns": 0
+		},
+		{
+			"name": "",
+			"uid": 0,
+			"city": 0,
+			"mark": "*",
+			"idle_turns": 0
+		},
+		{
+			"name": "",
+			"uid": 0,
+			"city": 0,
+			"mark": "*",
+			"idle_turns": 0
+		},
+		{
+			"name": "",
+			"uid": 0,
+			"city": 0,
+			"mark": "*",
+			"idle_turns": 0
+		},
+		{
+			"name": "",
+			"uid": 0,
+			"city": 0,
+			"mark": "*",
+			"idle_turns": 0
+		},
+		{
+			"name": "",
+			"uid": 0,
+			"city": 0,
+			"mark": "*",
+			"idle_turns": 0
+		},
+		{
+			"name": "",
+			"uid": 0,
+			"city": 0,
+			"mark": "*",
+			"idle_turns": 0
+		},
+		{
+			"name": "",
+			"uid": 0,
+			"city": 0,
+			"mark": "*",
+			"idle_turns": 0
+		},
+		{
+			"name": "",
+			"uid": 0,
+			"city": 0,
+			"mark": "*",
+			"idle_turns": 0
+		},
+		{
+			"name": "",
+			"uid": 0,
+			"city": 0,
+			"mark": "*",
+			"idle_turns": 0
+		},
+		{
+			"name": "",
+			"uid": 0,
+			"city": 0,
+			"mark": "*",
+			"idle_turns": 0
+		},
+		{
+			"name": "",
+			"uid": 0,
+			"city": 0,
+			"mark": "*",
+			"idle_turns": 0
+		},
+		{
+			"name": "",
+			"uid": 0,
+			"city": 0,
+			"mark": "*",
+			"idle_turns": 0
+		},
+		{
+			"name": "",
+			"uid": 0,
+			"city": 0,
+			"mark": "*",
+			"idle_turns": 0
+		},
+		{
+			"name": "",
+			"uid": 0,
+			"city": 0,
+			"mark": "*",
+			"idle_turns": 0
+		},
+		{
+			"name": "",
+			"uid": 0,
+			"city": 0,
+			"mark": "*",
+			"idle_turns": 0
+		},
+		{
+			"name": "",
+			"uid": 0,
+			"city": 0,
+			"mark": "*",
+			"idle_turns": 0
+		},
+		{
+			"name": "",
+			"uid": 0,
+			"city": 0,
+			"mark": "*",
+			"idle_turns": 0
+		},
+		{
+			"name": "",
+			"uid": 0,
+			"city": 0,
+			"mark": "*",
+			"idle_turns": 0
+		},
+		{
+			"name": "",
+			"uid": 0,
+			"city": 0,
+			"mark": "*",
+			"idle_turns": 0
+		},
+		{
+			"name": "",
+			"uid": 0,
+			"city": 0,
+			"mark": "*",
+			"idle_turns": 0
+		},
+		{
+			"name": "",
+			"uid": 0,
+			"city": 0,
+			"mark": "*",
+			"idle_turns": 0
+		},
+		{
+			"name": "",
+			"uid": 0,
+			"city": 0,
+			"mark": "*",
+			"idle_turns": 0
+		},
+		{
+			"name": "Rogue",
+			"uid": -1,
+			"city": 0,
+			"mark": "?",
+			"idle_turns": 0
+		}
+	],
+	"cities": [
+		{
+			"name": "Indigo",
+			"cluster": 1,
+			"nation": 0,
+			"r": 62,
+			"c": 61,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 2,
+			"ntypes": 4,
+			"types": [
+				0,
+				1,
+				2,
+				21
+			],
+			"times": [
+				1,
+				2,
+				2,
+				6
+			],
+			"instance": [
+				0,
+				0,
+				0,
+				0
+			]
+		},
+		{
+			"name": "Lavender",
+			"cluster": 1,
+			"nation": 0,
+			"r": 58,
+			"c": 4,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 2,
+			"ntypes": 4,
+			"types": [
+				0,
+				1,
+				2,
+				14
+			],
+			"times": [
+				1,
+				2,
+				2,
+				6
+			],
+			"instance": [
+				0,
+				0,
+				0,
+				0
+			]
+		},
+		{
+			"name": "Crimson",
+			"cluster": 1,
+			"nation": 0,
+			"r": 57,
+			"c": 0,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 2,
+			"ntypes": 3,
+			"types": [
+				0,
+				1,
+				2,
+				3
+			],
+			"times": [
+				1,
+				2,
+				2,
+				4
+			],
+			"instance": [
+				0,
+				0,
+				0,
+				0
+			]
+		},
+		{
+			"name": "Saffron",
+			"cluster": 1,
+			"nation": 0,
+			"r": 62,
+			"c": 5,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 2,
+			"ntypes": 3,
+			"types": [
+				0,
+				1,
+				2,
+				-1
+			],
+			"times": [
+				1,
+				2,
+				2,
+				-1
+			],
+			"instance": [
+				0,
+				0,
+				0,
+				0
+			]
+		},
+		{
+			"name": "Verdant",
+			"cluster": 1,
+			"nation": 0,
+			"r": 1,
+			"c": 0,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 2,
+			"ntypes": 4,
+			"types": [
+				0,
+				1,
+				2,
+				14
+			],
+			"times": [
+				1,
+				2,
+				2,
+				6
+			],
+			"instance": [
+				0,
+				0,
+				0,
+				0
+			]
+		},
+		{
+			"name": "Metropolis",
+			"cluster": 2,
+			"nation": 0,
+			"r": 15,
+			"c": 11,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 2,
+			"ntypes": 4,
+			"types": [
+				0,
+				1,
+				2,
+				3
+			],
+			"times": [
+				1,
+				2,
+				2,
+				4
+			],
+			"instance": [
+				0,
+				0,
+				0,
+				0
+			]
+		},
+		{
+			"name": "Gotham",
+			"cluster": 2,
+			"nation": 0,
+			"r": 14,
+			"c": 6,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 2,
+			"ntypes": 3,
+			"types": [
+				0,
+				1,
+				2,
+				14
+			],
+			"times": [
+				1,
+				2,
+				2,
+				6
+			],
+			"instance": [
+				0,
+				0,
+				0,
+				0
+			]
+		},
+		{
+			"name": "Keystone City",
+			"cluster": 2,
+			"nation": 0,
+			"r": 20,
+			"c": 9,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 2,
+			"ntypes": 4,
+			"types": [
+				0,
+				1,
+				2,
+				20
+			],
+			"times": [
+				1,
+				2,
+				2,
+				5
+			],
+			"instance": [
+				0,
+				0,
+				0,
+				0
+			]
+		},
+		{
+			"name": "Central City",
+			"cluster": 2,
+			"nation": 0,
+			"r": 18,
+			"c": 6,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 2,
+			"ntypes": 4,
+			"types": [
+				0,
+				1,
+				2,
+				14
+			],
+			"times": [
+				1,
+				2,
+				2,
+				6
+			],
+			"instance": [
+				0,
+				0,
+				0,
+				0
+			]
+		},
+		{
+			"name": "Heliochrysum",
+			"cluster": 3,
+			"nation": 0,
+			"r": 32,
+			"c": 32,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 2,
+			"ntypes": 4,
+			"types": [
+				0,
+				1,
+				2,
+				3
+			],
+			"times": [
+				1,
+				2,
+				2,
+				4
+			],
+			"instance": [
+				0,
+				0,
+				0,
+				0
+			]
+		},
+		{
+			"name": "Portulaca",
+			"cluster": 3,
+			"nation": 0,
+			"r": 28,
+			"c": 32,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 2,
+			"ntypes": 4,
+			"types": [
+				0,
+				1,
+				2,
+				14
+			],
+			"times": [
+				1,
+				2,
+				2,
+				6
+			],
+			"instance": [
+				0,
+				0,
+				0,
+				0
+			]
+		},
+		{
+			"name": "Gaillardia",
+			"cluster": 3,
+			"nation": 0,
+			"r": 35,
+			"c": 33,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 2,
+			"ntypes": 4,
+			"types": [
+				0,
+				1,
+				2,
+				3
+			],
+			"times": [
+				1,
+				2,
+				2,
+				4
+			],
+			"instance": [
+				0,
+				0,
+				0,
+				0
+			]
+		},
+		{
+			"name": "Coreopsis",
+			"cluster": 3,
+			"nation": 0,
+			"r": 34,
+			"c": 36,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 2,
+			"ntypes": 4,
+			"types": [
+				0,
+				1,
+				2,
+				21
+			],
+			"times": [
+				1,
+				2,
+				2,
+				6
+			],
+			"instance": [
+				0,
+				0,
+				0,
+				0
+			]
+		},
+		{
+			"name": "Delphineum",
+			"cluster": 3,
+			"nation": 0,
+			"r": 33,
+			"c": 40,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 2,
+			"ntypes": 4,
+			"types": [
+				0,
+				1,
+				2,
+				14
+			],
+			"times": [
+				1,
+				2,
+				2,
+				6
+			],
+			"instance": [
+				0,
+				0,
+				0,
+				0
+			]
+		},
+		{
+			"name": "Ruby",
+			"cluster": 4,
+			"nation": 0,
+			"r": 21,
+			"c": 18,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 2,
+			"ntypes": 4,
+			"types": [
+				0,
+				1,
+				2,
+				3
+			],
+			"times": [
+				1,
+				2,
+				2,
+				4
+			],
+			"instance": [
+				0,
+				0,
+				0,
+				0
+			]
+		},
+		{
+			"name": "Amber",
+			"cluster": 4,
+			"nation": 0,
+			"r": 28,
+			"c": 23,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 2,
+			"ntypes": 3,
+			"types": [
+				0,
+				1,
+				2,
+				14
+			],
+			"times": [
+				1,
+				2,
+				2,
+				6
+			],
+			"instance": [
+				0,
+				0,
+				0,
+				0
+			]
+		},
+		{
+			"name": "Emerald",
+			"cluster": 4,
+			"nation": 0,
+			"r": 26,
+			"c": 21,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 2,
+			"ntypes": 4,
+			"types": [
+				0,
+				1,
+				2,
+				14
+			],
+			"times": [
+				1,
+				2,
+				2,
+				6
+			],
+			"instance": [
+				0,
+				0,
+				0,
+				0
+			]
+		},
+		{
+			"name": "Diamond",
+			"cluster": 4,
+			"nation": 0,
+			"r": 22,
+			"c": 22,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 2,
+			"ntypes": 4,
+			"types": [
+				0,
+				1,
+				2,
+				14
+			],
+			"times": [
+				1,
+				2,
+				2,
+				6
+			],
+			"instance": [
+				0,
+				0,
+				0,
+				0
+			]
+		},
+		{
+			"name": "Sapphire",
+			"cluster": 4,
+			"nation": 0,
+			"r": 25,
+			"c": 25,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 2,
+			"ntypes": 4,
+			"types": [
+				0,
+				1,
+				2,
+				20
+			],
+			"times": [
+				1,
+				2,
+				2,
+				5
+			],
+			"instance": [
+				0,
+				0,
+				0,
+				0
+			]
+		},
+		{
+			"name": "Zhentil Keep",
+			"cluster": 5,
+			"nation": 0,
+			"r": 39,
+			"c": 21,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 2,
+			"ntypes": 4,
+			"types": [
+				0,
+				1,
+				2,
+				3
+			],
+			"times": [
+				1,
+				2,
+				2,
+				4
+			],
+			"instance": [
+				0,
+				0,
+				0,
+				0
+			]
+		},
+		{
+			"name": "Shadowdale",
+			"cluster": 5,
+			"nation": 0,
+			"r": 36,
+			"c": 21,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 2,
+			"ntypes": 4,
+			"types": [
+				0,
+				1,
+				2,
+				14
+			],
+			"times": [
+				1,
+				2,
+				2,
+				6
+			],
+			"instance": [
+				0,
+				0,
+				0,
+				0
+			]
+		},
+		{
+			"name": "Silverdale",
+			"cluster": 5,
+			"nation": 0,
+			"r": 44,
+			"c": 25,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 2,
+			"ntypes": 4,
+			"types": [
+				0,
+				1,
+				2,
+				20
+			],
+			"times": [
+				1,
+				2,
+				2,
+				6
+			],
+			"instance": [
+				0,
+				0,
+				0,
+				0
+			]
+		},
+		{
+			"name": "Battledale",
+			"cluster": 5,
+			"nation": 0,
+			"r": 41,
+			"c": 23,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 2,
+			"ntypes": 4,
+			"types": [
+				0,
+				1,
+				2,
+				14
+			],
+			"times": [
+				1,
+				2,
+				2,
+				6
+			],
+			"instance": [
+				0,
+				0,
+				0,
+				0
+			]
+		},
+		{
+			"name": "Dread",
+			"cluster": 6,
+			"nation": 0,
+			"r": 44,
+			"c": 6,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 3,
+			"ntypes": 2,
+			"types": [
+				6,
+				7,
+				-1,
+				-1
+			],
+			"times": [
+				1,
+				4,
+				-1,
+				-1
+			],
+			"instance": [
+				0,
+				0,
+				0,
+				0
+			]
+		},
+		{
+			"name": "Doom",
+			"cluster": 6,
+			"nation": 0,
+			"r": 50,
+			"c": 8,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 3,
+			"ntypes": 3,
+			"types": [
+				6,
+				7,
+				15,
+				-1
+			],
+			"times": [
+				1,
+				4,
+				6,
+				-1
+			],
+			"instance": [
+				0,
+				0,
+				0,
+				0
+			]
+		},
+		{
+			"name": "Despair",
+			"cluster": 6,
+			"nation": 0,
+			"r": 52,
+			"c": 7,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 3,
+			"ntypes": 2,
+			"types": [
+				6,
+				13,
+				-1,
+				-1
+			],
+			"times": [
+				1,
+				3,
+				-1,
+				-1
+			],
+			"instance": [
+				0,
+				0,
+				0,
+				0
+			]
+		},
+		{
+			"name": "Death",
+			"cluster": 6,
+			"nation": 0,
+			"r": 49,
+			"c": 5,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 3,
+			"ntypes": 2,
+			"types": [
+				6,
+				7,
+				-1,
+				-1
+			],
+			"times": [
+				1,
+				5,
+				-1,
+				-1
+			],
+			"instance": [
+				0,
+				0,
+				0,
+				0
+			]
+		},
+		{
+			"name": "Agony",
+			"cluster": 6,
+			"nation": 0,
+			"r": 52,
+			"c": 12,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 3,
+			"ntypes": 3,
+			"types": [
+				6,
+				13,
+				15,
+				-1
+			],
+			"times": [
+				1,
+				3,
+				6,
+				-1
+			],
+			"instance": [
+				0,
+				0,
+				0,
+				0
+			]
+		},
+		{
+			"name": "Gloom",
+			"cluster": 6,
+			"nation": 0,
+			"r": 49,
+			"c": 13,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 3,
+			"ntypes": 2,
+			"types": [
+				6,
+				7,
+				-1,
+				-1
+			],
+			"times": [
+				1,
+				5,
+				-1,
+				-1
+			],
+			"instance": [
+				0,
+				0,
+				0,
+				0
+			]
+		},
+		{
+			"name": "Iron",
+			"cluster": 7,
+			"nation": 0,
+			"r": 51,
+			"c": 41,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 3,
+			"ntypes": 4,
+			"types": [
+				0,
+				1,
+				8,
+				14
+			],
+			"times": [
+				1,
+				2,
+				3,
+				6
+			],
+			"instance": [
+				0,
+				0,
+				0,
+				0
+			]
+		},
+		{
+			"name": "Gold",
+			"cluster": 7,
+			"nation": 0,
+			"r": 57,
+			"c": 36,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 3,
+			"ntypes": 4,
+			"types": [
+				0,
+				1,
+				8,
+				20
+			],
+			"times": [
+				1,
+				2,
+				3,
+				5
+			],
+			"instance": [
+				0,
+				0,
+				0,
+				0
+			]
+		},
+		{
+			"name": "Silver",
+			"cluster": 7,
+			"nation": 0,
+			"r": 51,
+			"c": 36,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 3,
+			"ntypes": 4,
+			"types": [
+				0,
+				1,
+				8,
+				14
+			],
+			"times": [
+				1,
+				2,
+				3,
+				6
+			],
+			"instance": [
+				0,
+				0,
+				0,
+				0
+			]
+		},
+		{
+			"name": "Tin",
+			"cluster": 7,
+			"nation": 0,
+			"r": 49,
+			"c": 34,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 3,
+			"ntypes": 3,
+			"types": [
+				0,
+				1,
+				8,
+				-1
+			],
+			"times": [
+				1,
+				2,
+				3,
+				-1
+			],
+			"instance": [
+				0,
+				0,
+				0,
+				0
+			]
+		},
+		{
+			"name": "Lead",
+			"cluster": 7,
+			"nation": 0,
+			"r": 54,
+			"c": 37,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 3,
+			"ntypes": 3,
+			"types": [
+				0,
+				1,
+				8,
+				-1
+			],
+			"times": [
+				1,
+				2,
+				3,
+				-1
+			],
+			"instance": [
+				0,
+				0,
+				0,
+				0
+			]
+		},
+		{
+			"name": "Nyarlathotep",
+			"cluster": 8,
+			"nation": 0,
+			"r": 2,
+			"c": 17,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 2,
+			"ntypes": 2,
+			"types": [
+				9,
+				12,
+				-1,
+				-1
+			],
+			"times": [
+				1,
+				3,
+				-1,
+				-1
+			],
+			"instance": [
+				0,
+				0,
+				0,
+				0
+			]
+		},
+		{
+			"name": "Yogsothoth",
+			"cluster": 8,
+			"nation": 0,
+			"r": 8,
+			"c": 13,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 2,
+			"ntypes": 2,
+			"types": [
+				9,
+				12,
+				-1,
+				-1
+			],
+			"times": [
+				1,
+				3,
+				-1,
+				-1
+			],
+			"instance": [
+				0,
+				0,
+				0,
+				0
+			]
+		},
+		{
+			"name": "Cthulhu",
+			"cluster": 8,
+			"nation": 0,
+			"r": 1,
+			"c": 11,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 2,
+			"ntypes": 2,
+			"types": [
+				9,
+				13,
+				-1,
+				-1
+			],
+			"times": [
+				1,
+				3,
+				-1,
+				-1
+			],
+			"instance": [
+				0,
+				0,
+				0,
+				0
+			]
+		},
+		{
+			"name": "Hastor",
+			"cluster": 8,
+			"nation": 0,
+			"r": 4,
+			"c": 12,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 2,
+			"ntypes": 2,
+			"types": [
+				9,
+				13,
+				-1,
+				-1
+			],
+			"times": [
+				1,
+				3,
+				-1,
+				-1
+			],
+			"instance": [
+				0,
+				0,
+				0,
+				0
+			]
+		},
+		{
+			"name": "Olan",
+			"cluster": 9,
+			"nation": 0,
+			"r": 44,
+			"c": 37,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 3,
+			"ntypes": 2,
+			"types": [
+				4,
+				10,
+				-1,
+				-1
+			],
+			"times": [
+				1,
+				3,
+				-1,
+				-1
+			],
+			"instance": [
+				0,
+				0,
+				0,
+				0
+			]
+		},
+		{
+			"name": "Kaxandar",
+			"cluster": 9,
+			"nation": 0,
+			"r": 42,
+			"c": 39,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 3,
+			"ntypes": 2,
+			"types": [
+				4,
+				10,
+				-1,
+				-1
+			],
+			"times": [
+				1,
+				3,
+				-1,
+				-1
+			],
+			"instance": [
+				0,
+				0,
+				0,
+				0
+			]
+		},
+		{
+			"name": "Torgar",
+			"cluster": 9,
+			"nation": 0,
+			"r": 40,
+			"c": 37,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 3,
+			"ntypes": 2,
+			"types": [
+				4,
+				10,
+				-1,
+				-1
+			],
+			"times": [
+				1,
+				3,
+				-1,
+				-1
+			],
+			"instance": [
+				0,
+				0,
+				0,
+				0
+			]
+		},
+		{
+			"name": "Arras Charka",
+			"cluster": 10,
+			"nation": 0,
+			"r": 11,
+			"c": 53,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 2,
+			"ntypes": 3,
+			"types": [
+				0,
+				1,
+				21,
+				-1
+			],
+			"times": [
+				1,
+				2,
+				6,
+				-1
+			],
+			"instance": [
+				0,
+				0,
+				0,
+				0
+			]
+		},
+		{
+			"name": "Derzon",
+			"cluster": 10,
+			"nation": 0,
+			"r": 11,
+			"c": 49,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 2,
+			"ntypes": 3,
+			"types": [
+				0,
+				1,
+				2,
+				-1
+			],
+			"times": [
+				1,
+				2,
+				2,
+				-1
+			],
+			"instance": [
+				0,
+				0,
+				0,
+				0
+			]
+		},
+		{
+			"name": "Ekosiak",
+			"cluster": 10,
+			"nation": 0,
+			"r": 14,
+			"c": 54,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 2,
+			"ntypes": 4,
+			"types": [
+				0,
+				1,
+				2,
+				3
+			],
+			"times": [
+				1,
+				2,
+				2,
+				4
+			],
+			"instance": [
+				0,
+				0,
+				0,
+				0
+			]
+		},
+		{
+			"name": "Ish-Tako",
+			"cluster": 10,
+			"nation": 0,
+			"r": 13,
+			"c": 44,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 2,
+			"ntypes": 4,
+			"types": [
+				0,
+				1,
+				8,
+				14
+			],
+			"times": [
+				1,
+				2,
+				3,
+				6
+			],
+			"instance": [
+				0,
+				0,
+				0,
+				0
+			]
+		},
+		{
+			"name": "Chishata",
+			"cluster": 10,
+			"nation": 0,
+			"r": 15,
+			"c": 49,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 2,
+			"ntypes": 4,
+			"types": [
+				0,
+				1,
+				8,
+				14
+			],
+			"times": [
+				1,
+				2,
+				3,
+				6
+			],
+			"instance": [
+				0,
+				0,
+				0,
+				0
+			]
+		},
+		{
+			"name": "Qualinesti",
+			"cluster": 11,
+			"nation": 0,
+			"r": 0,
+			"c": 39,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 2,
+			"ntypes": 4,
+			"types": [
+				17,
+				5,
+				11,
+				20
+			],
+			"times": [
+				1,
+				2,
+				2,
+				4
+			],
+			"instance": [
+				0,
+				0,
+				0,
+				0
+			]
+		},
+		{
+			"name": "Sylvanesti",
+			"cluster": 11,
+			"nation": 0,
+			"r": 6,
+			"c": 38,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 2,
+			"ntypes": 4,
+			"types": [
+				17,
+				5,
+				11,
+				16
+			],
+			"times": [
+				1,
+				2,
+				2,
+				7
+			],
+			"instance": [
+				0,
+				0,
+				0,
+				0
+			]
+		},
+		{
+			"name": "Rathwynn",
+			"cluster": 11,
+			"nation": 0,
+			"r": 5,
+			"c": 42,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 2,
+			"ntypes": 3,
+			"types": [
+				17,
+				5,
+				11,
+				-1
+			],
+			"times": [
+				1,
+				2,
+				2,
+				-1
+			],
+			"instance": [
+				0,
+				0,
+				0,
+				0
+			]
+		},
+		{
+			"name": "Caledon",
+			"cluster": 11,
+			"nation": 0,
+			"r": 1,
+			"c": 43,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 2,
+			"ntypes": 4,
+			"types": [
+				17,
+				5,
+				11,
+				16
+			],
+			"times": [
+				1,
+				2,
+				2,
+				7
+			],
+			"instance": [
+				0,
+				0,
+				0,
+				0
+			]
+		},
+		{
+			"name": "Alfheim",
+			"cluster": 11,
+			"nation": 0,
+			"r": 62,
+			"c": 42,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 2,
+			"ntypes": 4,
+			"types": [
+				17,
+				5,
+				11,
+				16
+			],
+			"times": [
+				1,
+				2,
+				2,
+				7
+			],
+			"instance": [
+				0,
+				0,
+				0,
+				0
+			]
+		},
+		{
+			"name": "Atlantis",
+			"cluster": 12,
+			"nation": 0,
+			"r": 43,
+			"c": 54,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 2,
+			"ntypes": 3,
+			"types": [
+				18,
+				19,
+				22,
+				-1
+			],
+			"times": [
+				1,
+				2,
+				8,
+				-1
+			],
+			"instance": [
+				0,
+				0,
+				0,
+				0
+			]
+		},
+		{
+			"name": "Mu",
+			"cluster": 12,
+			"nation": 0,
+			"r": 45,
+			"c": 58,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 2,
+			"ntypes": 3,
+			"types": [
+				18,
+				19,
+				22,
+				-1
+			],
+			"times": [
+				1,
+				2,
+				8,
+				-1
+			],
+			"instance": [
+				0,
+				0,
+				0,
+				0
+			]
+		},
+		{
+			"name": "Poseidon",
+			"cluster": 12,
+			"nation": 0,
+			"r": 42,
+			"c": 59,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 2,
+			"ntypes": 3,
+			"types": [
+				18,
+				19,
+				22,
+				-1
+			],
+			"times": [
+				1,
+				2,
+				8,
+				-1
+			],
+			"instance": [
+				0,
+				0,
+				0,
+				0
+			]
+		},
+		{
+			"name": "Neptune",
+			"cluster": 12,
+			"nation": 0,
+			"r": 47,
+			"c": 54,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 2,
+			"ntypes": 3,
+			"types": [
+				18,
+				19,
+				22,
+				-1
+			],
+			"times": [
+				1,
+				2,
+				8,
+				-1
+			],
+			"instance": [
+				0,
+				0,
+				0,
+				0
+			]
+		}
+	],
+	"ttypes": [
+		{
+			"name": "Lt. Infantry",
+			"combat": 2,
+			"move_rate": 6,
+			"move_tbl": 0,
+			"special_mv": 0
+		},
+		{
+			"name": "Hv. Infantry",
+			"combat": 3,
+			"move_rate": 4,
+			"move_tbl": 0,
+			"special_mv": 0
+		},
+		{
+			"name": "Lt. Cavalry",
+			"combat": 2,
+			"move_rate": 12,
+			"move_tbl": 1,
+			"special_mv": 0
+		},
+		{
+			"name": "Hv. Cavalry",
+			"combat": 3,
+			"move_rate": 8,
+			"move_tbl": 1,
+			"special_mv": 0
+		},
+		{
+			"name": "Dwarf Legion",
+			"combat": 3,
+			"move_rate": 4,
+			"move_tbl": 2,
+			"special_mv": 0
+		},
+		{
+			"name": "Elven Archers",
+			"combat": 3,
+			"move_rate": 6,
+			"move_tbl": 3,
+			"special_mv": 0
+		},
+		{
+			"name": "Zombie Legion",
+			"combat": 3,
+			"move_rate": 3,
+			"move_tbl": 0,
+			"special_mv": 0
+		},
+		{
+			"name": "Wraith Horde",
+			"combat": 4,
+			"move_rate": 6,
+			"move_tbl": 4,
+			"special_mv": 0
+		},
+		{
+			"name": "Elite Troopers",
+			"combat": 4,
+			"move_rate": 4,
+			"move_tbl": 0,
+			"special_mv": 0
+		},
+		{
+			"name": "Gug",
+			"combat": 3,
+			"move_rate": 4,
+			"move_tbl": 0,
+			"special_mv": 0
+		},
+		{
+			"name": "Dwarf Miners",
+			"combat": 4,
+			"move_rate": 4,
+			"move_tbl": 5,
+			"special_mv": 0
+		},
+		{
+			"name": "Scout",
+			"combat": 1,
+			"move_rate": 8,
+			"move_tbl": 6,
+			"special_mv": 0
+		},
+		{
+			"name": "Byakhee",
+			"combat": 2,
+			"move_rate": 7,
+			"move_tbl": 4,
+			"special_mv": 2
+		},
+		{
+			"name": "Ghouls",
+			"combat": 3,
+			"move_rate": 5,
+			"move_tbl": 0,
+			"special_mv": 0
+		},
+		{
+			"name": "Navy",
+			"combat": 2,
+			"move_rate": 10,
+			"move_tbl": 7,
+			"special_mv": 3
+		},
+		{
+			"name": "Undead Navy",
+			"combat": 3,
+			"move_rate": 8,
+			"move_tbl": 7,
+			"special_mv": 3
+		},
+		{
+			"name": "Elf Clipper",
+			"combat": 2,
+			"move_rate": 12,
+			"move_tbl": 7,
+			"special_mv": 3
+		},
+		{
+			"name": "Elf Infantry",
+			"combat": 2,
+			"move_rate": 8,
+			"move_tbl": 3,
+			"special_mv": 0
+		},
+		{
+			"name": "Mermen",
+			"combat": 2,
+			"move_rate": 6,
+			"move_tbl": 7,
+			"special_mv": 0
+		},
+		{
+			"name": "Tritons",
+			"combat": 3,
+			"move_rate": 4,
+			"move_tbl": 7,
+			"special_mv": 0
+		},
+		{
+			"name": "Pegasus",
+			"combat": 2,
+			"move_rate": 10,
+			"move_tbl": 4,
+			"special_mv": 1
+		},
+		{
+			"name": "Hippogryff",
+			"combat": 3,
+			"move_rate": 8,
+			"move_tbl": 4,
+			"special_mv": 1
+		},
+		{
+			"name": "Leviathan",
+			"combat": 5,
+			"move_rate": 4,
+			"move_tbl": 8,
+			"special_mv": 1
+		}
+	],
+	"armies": [],
+	"move_table": [
+		{
+			"cost": [
+				0,
+				1,
+				2,
+				2,
+				4
+			]
+		},
+		{
+			"cost": [
+				0,
+				1,
+				2,
+				3,
+				0
+			]
+		},
+		{
+			"cost": [
+				0,
+				1,
+				2,
+				1,
+				2
+			]
+		},
+		{
+			"cost": [
+				0,
+				1,
+				1,
+				2,
+				4
+			]
+		},
+		{
+			"cost": [
+				1,
+				1,
+				1,
+				1,
+				2
+			]
+		},
+		{
+			"cost": [
+				0,
+				1,
+				2,
+				2,
+				3
+			]
+		},
+		{
+			"cost": [
+				0,
+				1,
+				1,
+				1,
+				2
+			]
+		},
+		{
+			"cost": [
+				1,
+				0,
+				0,
+				0,
+				0
+			]
+		},
+		{
+			"cost": [
+				1,
+				1,
+				2,
+				3,
+				4
+			]
+		}
+	],
+	"world": "Alderon's World",
+	"gen": 0
+}
\ No newline at end of file
diff --git a/xtrn/war/worlds/alderon/map b/xtrn/war/worlds/alderon/map
new file mode 100644
index 0000000000000000000000000000000000000000..47270ef31595b49484d59f498f4be4381fb0becf
--- /dev/null
+++ b/xtrn/war/worlds/alderon/map
@@ -0,0 +1,66 @@
+M 64 64
+
+...~%%%~~~^^#~~~%%%~~#%.%%%%..^^~~~####%%%%%#~.~~~~~~~~~~~~~~%%%
+...~~~~~~~^##~~~%%%%###%....^^^^~~%#####%%%%~#.~~~~~~~~~~~~~~~~~
+..~~~~~~~~^##~~%%%%%###......^^~~~%%####%%%%~~.~~~~~~~~~~~~~~~~~
+~~~~~~~~~^^##%%%%%%%~##.......~~~~%%#~~###%~~~~~~~~~~~~~~~~~~~~~
+~~~~####^^##%%%~~~~~~~~~.~~..~~~%%%%^~~~%%%%~~~~~~~~~~~~~~~~~~~~
+~~~~###~~~~~.~~~~~~~~~~~~~~##~~%%%%%^~%%%%%%~~~~~~~~~~~~~~~~~~~~
+~~~~~~~~~~~~~..~~~~~~~~~~~##%%%%%%%.~~%%%%%.~~~~~~~~~~~~~~~~~~~~
+~~~~~~~~~~~~..~~~~~~~~~~~###%%%%~~~.~~~~%%..%%~~~~~~^~~~~~~~~~~~
+~~~~~~~~~~~%%%%~~~....~~~~~%%%%~~~~~~~~~....~%%~~~^^^#~~~~~~~~~~
+~~~~~~~~~~~%%%%%~~.....~~~~%%%~~~~~~~~~^....~~%~~##^##~~~~~~~~~~
+~~~~~~~~~~##%%%%~......~~...%~~~~~~~~~~^~..~~#%~%#####%~~~~~~~~~
+~~~~~...##~#%%%%....^^~~~...~~~~~~~~~~~~~~~~##%.%###~%%%~~~~~~~~
+~~~~~~^^..~~~~%%....^^~~~~~~~~~~~~~~~~~~~~~#^^..####..%%~~~~~~~~
+~~~~~~^^^^%%~~~%...####~~~~~~~~~~~~~~~~~~~~##....###....~^^...~~
+~~~~~~^^^%%%~~~~~~#####.~~~~~~~~~~~~~~~~~~~~#....###%%..###..~~~
+~~~~...#%%%%%%%~~~####...~~~~~~~~~~~~~~~~~~~...~###%%%%.###..~~~
+##....~~%%%%%%%~~~......~~~~~~~~~~~~~~~~~~~~~..~~##%%%%~##..%...
+......~~####%%~~~~.....~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%%~~~~..%%..
+...%..#######~~~~~~...~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~.%%%.
+..%%%#########~~~~~##%~~~~~~..#%~~~~~~~~~~~~~~~~~~~~~~~~~~~##%%.
+~~~~~~~########~~%%%###~~~~~####~~~~~~~~~~~~~~~~~~~~~~~~~~~~##~~
+~~~~~~~~###.##~~~%%%##^~~~~~####~~~~~~~~~~~~~~~~....~~~~~~~~~~~~
+~~~~~~~~~##^^~~~%%%%..^^~~~~####~~~~~~~~~~~~~~~#....#~~~~~~~~~~~
+~~..~~~~~~~~~~~~%%%%....~~~~%###~~~~~~~~~~~~~~~%...~~~~~~~~~~~~~
+~~~~..~~~~~~~~~~~~%%.....#%%%%%%^^%%.~~~~~~~~~~~~~~~~~~~~~~~~~~~
+~~~~~~~~~~~~~~~~~~~%%...##%%%%%%^^%%~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+~~~~~~~~~~~~~~~~~~~^%..~~~.^^^..^^%%~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+~~~~~~~~~~~~~~~~~~~^~~~~~~~^^^..^^^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+~~~~~~~~~~~~~~~~~~~~~~~%.%.%.....^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+~~~~~~~~~~~~~~~~~~~~~~~~~~%%.....~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~....%~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~....%%%.~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%%%%%%%%%%%%~~~~~~~~~~~~~~~~~~~~~~
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%%%%%%%%..~~~~~~~~~~~~~~~~~~~~~~~
+~~~~~~~~~~~~~~~~~~~~~%^^%%~~~~~~%%%%......~~~~~~~~~~~~~~~~~~~~~~
+~~~~~~~~~~~~~~~~~~~~%%%^%%~~~~~~%%%%.....~~~~~~~~~~~~~~~~~~~~~~~
+~~~~~~~~~~~~~~~~~~####~~~~~~~~......~~~~~~~~..~~~~~~~~~~~~~~~~~~
+~~~~~~~~~~~~~~~~######~~~~~~~~~~~~..%~~~~~~~...~~~~~~~~~~~~~~~~~
+~~~~~~~~~~~%%%%%#######~~~~~~~~~~~~~%%~~~~~~..~~~~~~~~~~~~~~~~~~
+~~~~~~~~~~~~~%%%###^####~~~~~~~~~~~~^^^.%%~~.~~~~~~~~~~~~~~~~~~~
+~~~~~~~~~~~~~~~~####%###~~~~####~~~~^^^^%%%%..~~~~~~~~~~~~~~~~~~
+~~~~~~~~~~~~~~~~####%%%%%%~~###~~~~~^^^^%%%%.~~~~~~~~~~~~~~~~~~~
+~~~~~~~~^^^~~~~.####%%%%%%%..#~~~~~^^^^^^%%%~~~~~~~~~~~~~~~~~~~~
+~~~~....^^^~~~..####...%%%%...~~~~~^.^^^^%%~~~~~~~~~~~~~~~~~~~~~
+~~~~.....~~~~~...####...##.....~~~~~^^^.#~~~~~~~~~~~~~~~~~~~~~~~
+~~~~~...~~~~^##...##%%%%##.....~~~~~^^..~~~~~~~~~~~~~~~~~~~~~~~~
+~~~~~~..~~~~^^##..~~%%%%##...###~~~~~^..~~~~~~~~~~~~~~~~~~~~~~~~
+~~~~~~..~~~~^^##.~~~%%%%~~..#####~~~~...~~~~#~~~~~~~~~~~~~~~~~~~
+~~~~###.~~~####%%%~~~~~~~~~~%###%%..#~~.....#~~~~~~~~~~~~~~~~~~~
+~~~~####~~~####%%%%~~~~~~~~~%###%^^^#~~~#...~~~~~~~~~~~~~~~~~~~~
+~~~~####^^..###~%%~~~~~~....%###~%^^#~~~##..~~~~~~~~~~~~~~~~~~~~
+~~~~~###^^..^^^~~~~~##~.....%%#~~~^^^^~###%%~~~~~~~~~~~~~~~~~~~~
+~~~~~~^^^~~..^~~~~%%~##.~~~.%%%~~~~^^..#~~~.###~~~~~~~~~~~~~~~~~
+~~~~~~^^~~~..~~~~~~%~~~~~~~..%~~~~~^^...~~~.###~~~~~~~~~~~~~~~~~
+~~~~~~~^~~~~.~~~~~~%%~~~~~~~.~~~~~~^^^.~~~~~##~~~~~~~~~~~~~~~~~~
+~#~~~~~~~~~~##~~~~~~~~~~~~~~~.~.~~%%^^^~~~~~##~~~~~~~~~~~~~~~~~~
+###~~~~~~~~~~~^~.~~~~~~~~~~^.....%%%^^^~~~~~~~~~~~~~~~~~~~~~~%%%
+%#.....%~~~~~~~...~~~~~~~~~~~~..^^%%^^^~~~~~~~~~~~~~~~~~~~~~~~%%
+....%%%%~~~~~~~~...%~~~~~~~~^~.^^^^%^^~~~~~~~~~~~~~~~~~~~~~~~~~%
+~~~~~~~%###~~~~~...%%~~~~~~~###^^^~~%~~~~~~~~~~~~~~~~~~~~~~~~~~~
+~~~~~~~.###..~~~~...%%%~~~~#####~~~~~#.~##~~~~~~~~~~~~~~~~~~~~.~
+~~~~..........~~~~~~%%%~~~%~###~~~~~##..###~~~~~~~~~~~~~~~~~%...
+%%............~~~~~~%%%%~%%%~~~~~~~~##..##..~~~~~~~~~~~~~~~%%%%%
+%%..%%..~~...~~~~~~~~%%%%%%%~~~~~~~~###.#...~~~~~~~~~~~~~~~%%%%%
diff --git a/xtrn/war/worlds/earth/game.orig.json b/xtrn/war/worlds/earth/game.orig.json
new file mode 100644
index 0000000000000000000000000000000000000000..aaf8360c13a3c1cc1039e23726051b58fa9313ce
--- /dev/null
+++ b/xtrn/war/worlds/earth/game.orig.json
@@ -0,0 +1,2047 @@
+{
+	"ncnt": 1,
+	"nations": [
+		{
+			"name": "Overlord",
+			"uid": 0,
+			"city": 0,
+			"mark": "*",
+			"idle_turns": 0
+		},
+		{
+			"name": "",
+			"uid": 0,
+			"city": 0,
+			"mark": "*",
+			"idle_turns": 0
+		},
+		{
+			"name": "",
+			"uid": 0,
+			"city": 0,
+			"mark": "*",
+			"idle_turns": 0
+		},
+		{
+			"name": "",
+			"uid": 0,
+			"city": 0,
+			"mark": "*",
+			"idle_turns": 0
+		},
+		{
+			"name": "",
+			"uid": 0,
+			"city": 0,
+			"mark": "*",
+			"idle_turns": 0
+		},
+		{
+			"name": "",
+			"uid": 0,
+			"city": 0,
+			"mark": "*",
+			"idle_turns": 0
+		},
+		{
+			"name": "",
+			"uid": 0,
+			"city": 0,
+			"mark": "*",
+			"idle_turns": 0
+		},
+		{
+			"name": "",
+			"uid": 0,
+			"city": 0,
+			"mark": "*",
+			"idle_turns": 0
+		},
+		{
+			"name": "",
+			"uid": 0,
+			"city": 0,
+			"mark": "*",
+			"idle_turns": 0
+		},
+		{
+			"name": "",
+			"uid": 0,
+			"city": 0,
+			"mark": "*",
+			"idle_turns": 0
+		},
+		{
+			"name": "",
+			"uid": 0,
+			"city": 0,
+			"mark": "*",
+			"idle_turns": 0
+		},
+		{
+			"name": "",
+			"uid": 0,
+			"city": 0,
+			"mark": "*",
+			"idle_turns": 0
+		},
+		{
+			"name": "",
+			"uid": 0,
+			"city": 0,
+			"mark": "*",
+			"idle_turns": 0
+		},
+		{
+			"name": "",
+			"uid": 0,
+			"city": 0,
+			"mark": "*",
+			"idle_turns": 0
+		},
+		{
+			"name": "",
+			"uid": 0,
+			"city": 0,
+			"mark": "*",
+			"idle_turns": 0
+		},
+		{
+			"name": "",
+			"uid": 0,
+			"city": 0,
+			"mark": "*",
+			"idle_turns": 0
+		},
+		{
+			"name": "",
+			"uid": 0,
+			"city": 0,
+			"mark": "*",
+			"idle_turns": 0
+		},
+		{
+			"name": "",
+			"uid": 0,
+			"city": 0,
+			"mark": "*",
+			"idle_turns": 0
+		},
+		{
+			"name": "",
+			"uid": 0,
+			"city": 0,
+			"mark": "*",
+			"idle_turns": 0
+		},
+		{
+			"name": "",
+			"uid": 0,
+			"city": 0,
+			"mark": "*",
+			"idle_turns": 0
+		},
+		{
+			"name": "",
+			"uid": 0,
+			"city": 0,
+			"mark": "*",
+			"idle_turns": 0
+		},
+		{
+			"name": "",
+			"uid": 0,
+			"city": 0,
+			"mark": "*",
+			"idle_turns": 0
+		},
+		{
+			"name": "",
+			"uid": 0,
+			"city": 0,
+			"mark": "*",
+			"idle_turns": 0
+		},
+		{
+			"name": "",
+			"uid": 0,
+			"city": 0,
+			"mark": "*",
+			"idle_turns": 0
+		},
+		{
+			"name": "",
+			"uid": 0,
+			"city": 0,
+			"mark": "*",
+			"idle_turns": 0
+		},
+		{
+			"name": "",
+			"uid": 0,
+			"city": 0,
+			"mark": "*",
+			"idle_turns": 0
+		},
+		{
+			"name": "",
+			"uid": 0,
+			"city": 0,
+			"mark": "*",
+			"idle_turns": 0
+		},
+		{
+			"name": "Rogue",
+			"uid": -1,
+			"city": 0,
+			"mark": "?",
+			"idle_turns": 0
+		}
+	],
+	"cities": [
+		{
+			"name": "Indigo",
+			"cluster": 1,
+			"nation": 0,
+			"r": 5,
+			"c": 4,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 2,
+			"ntypes": 4,
+			"types": [
+				0,
+				1,
+				2,
+				21
+			],
+			"times": [
+				1,
+				2,
+				2,
+				6
+			],
+			"instance": [
+				 0,
+				 0,
+				 0,
+				 0
+			]
+		},
+		{
+			"name": "Lavender",
+			"cluster": 1,
+			"nation": 0,
+			"r": 7,
+			"c": 2,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 2,
+			"ntypes": 4,
+			"types": [
+				0,
+				1,
+				2,
+				14
+			],
+			"times": [
+				1,
+				2,
+				2,
+				6
+			],
+			"instance": [
+				 0,
+				 0,
+				 0,
+				 0
+			]
+		},
+		{
+			"name": "Crimson",
+			"cluster": 1,
+			"nation": 0,
+			"r": 3,
+			"c": 5,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 2,
+			"ntypes": 3,
+			"types": [
+				0,
+				1,
+				2,
+				3
+			],
+			"times": [
+				1,
+				2,
+				2,
+				4
+			],
+			"instance": [
+				 0,
+				 0,
+				 0,
+				 0
+			]
+		},
+		{
+			"name": "Saffron",
+			"cluster": 1,
+			"nation": 0,
+			"r": 9,
+			"c": 8,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 2,
+			"ntypes": 3,
+			"types": [
+				0,
+				1,
+				2,
+				-1
+			],
+			"times": [
+				1,
+				2,
+				2,
+				-1
+			],
+			"instance": [
+				7,
+				0,
+				0,
+				-1
+			]
+		},
+		{
+			"name": "Verdant",
+			"cluster": 1,
+			"nation": 0,
+			"r": 6,
+			"c": 10,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 2,
+			"ntypes": 4,
+			"types": [
+				0,
+				1,
+				2,
+				14
+			],
+			"times": [
+				1,
+				2,
+				2,
+				6
+			],
+			"instance": [
+				 0,
+				 0,
+				 0,
+				 0
+			]
+		},
+		{
+			"name": "Metropolis",
+			"cluster": 2,
+			"nation": 0,
+			"r": 28,
+			"c": 10,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 2,
+			"ntypes": 4,
+			"types": [
+				0,
+				1,
+				2,
+				3
+			],
+			"times": [
+				1,
+				2,
+				2,
+				4
+			],
+			"instance": [
+				 0,
+				 0,
+				 0,
+				 0
+			]
+		},
+		{
+			"name": "Gotham",
+			"cluster": 2,
+			"nation": 0,
+			"r": 29,
+			"c": 5,
+			"prod_type": 0,
+			"turns_left": 2,
+			"defense": 2,
+			"ntypes": 3,
+			"types": [
+				0,
+				1,
+				2,
+				-1
+			],
+			"times": [
+				1,
+				2,
+				2,
+				-1
+			],
+			"instance": [
+				10,
+				9,
+				0,
+				-1
+			]
+		},
+		{
+			"name": "Keystone City",
+			"cluster": 2,
+			"nation": 0,
+			"r": 31,
+			"c": 8,
+			"prod_type": 0,
+			"turns_left": 2,
+			"defense": 2,
+			"ntypes": 4,
+			"types": [
+				0,
+				1,
+				2,
+				20
+			],
+			"times": [
+				1,
+				2,
+				2,
+				5
+			],
+			"instance": [
+				 0,
+				 0,
+				 0,
+				 0
+			]
+		},
+		{
+			"name": "Central City",
+			"cluster": 2,
+			"nation": 0,
+			"r": 35,
+			"c": 9,
+			"prod_type": 0,
+			"turns_left": 5,
+			"defense": 2,
+			"ntypes": 4,
+			"types": [
+				0,
+				1,
+				2,
+				14
+			],
+			"times": [
+				1,
+				2,
+				2,
+				6
+			],
+			"instance": [
+				 0,
+				 0,
+				 0,
+				 0
+			]
+		},
+		{
+			"name": "Heliochrysum",
+			"cluster": 3,
+			"nation": 0,
+			"r": 32,
+			"c": 24,
+			"prod_type": 0,
+			"turns_left": 3,
+			"defense": 2,
+			"ntypes": 4,
+			"types": [
+				0,
+				1,
+				2,
+				3
+			],
+			"times": [
+				1,
+				2,
+				2,
+				4
+			],
+			"instance": [
+				 0,
+				 0,
+				 0,
+				 0
+			]
+		},
+		{
+			"name": "Portulaca",
+			"cluster": 3,
+			"nation": 0,
+			"r": 33,
+			"c": 29,
+			"prod_type": 0,
+			"turns_left": 3,
+			"defense": 2,
+			"ntypes": 4,
+			"types": [
+				0,
+				1,
+				2,
+				3
+			],
+			"times": [
+				1,
+				2,
+				2,
+				4
+			],
+			"instance": [
+				 0,
+				 0,
+				 0,
+				 0
+			]
+		},
+		{
+			"name": "Gaillardia",
+			"cluster": 3,
+			"nation": 0,
+			"r": 38,
+			"c": 24,
+			"prod_type": 0,
+			"turns_left": 2,
+			"defense": 2,
+			"ntypes": 4,
+			"types": [
+				0,
+				1,
+				2,
+				14
+			],
+			"times": [
+				1,
+				2,
+				2,
+				6
+			],
+			"instance": [
+				 0,
+				 0,
+				 0,
+				 0
+			]
+		},
+		{
+			"name": "Coreopsis",
+			"cluster": 3,
+			"nation": 0,
+			"r": 36,
+			"c": 21,
+			"prod_type": 0,
+			"turns_left": 2,
+			"defense": 2,
+			"ntypes": 4,
+			"types": [
+				0,
+				1,
+				2,
+				21
+			],
+			"times": [
+				1,
+				2,
+				2,
+				6
+			],
+			"instance": [
+				 0,
+				 0,
+				 0,
+				 0
+			]
+		},
+		{
+			"name": "Delphineum",
+			"cluster": 3,
+			"nation": 0,
+			"r": 33,
+			"c": 19,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 2,
+			"ntypes": 4,
+			"types": [
+				0,
+				1,
+				2,
+				14
+			],
+			"times": [
+				1,
+				2,
+				2,
+				6
+			],
+			"instance": [
+				 0,
+				 0,
+				 0,
+				 0
+			]
+		},
+		{
+			"name": "Ruby",
+			"cluster": 4,
+			"nation": 0,
+			"r": 14,
+			"c": 23,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 2,
+			"ntypes": 4,
+			"types": [
+				0,
+				1,
+				2,
+				3
+			],
+			"times": [
+				1,
+				2,
+				2,
+				4
+			],
+			"instance": [
+				 0,
+				 0,
+				 0,
+				 0
+			]
+		},
+		{
+			"name": "Amber",
+			"cluster": 4,
+			"nation": 0,
+			"r": 16,
+			"c": 20,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 2,
+			"ntypes": 3,
+			"types": [
+				0,
+				1,
+				2,
+				-1
+			],
+			"times": [
+				1,
+				2,
+				2,
+				-1
+			],
+			"instance": [
+				7,
+				0,
+				0,
+				-1
+			]
+		},
+		{
+			"name": "Emerald",
+			"cluster": 4,
+			"nation": 0,
+			"r": 16,
+			"c": 28,
+			"prod_type": 0,
+			"turns_left": 5,
+			"defense": 2,
+			"ntypes": 4,
+			"types": [
+				0,
+				1,
+				2,
+				14
+			],
+			"times": [
+				1,
+				2,
+				2,
+				6
+			],
+			"instance": [
+				 0,
+				 0,
+				 0,
+				 0
+			]
+		},
+		{
+			"name": "Diamond",
+			"cluster": 4,
+			"nation": 0,
+			"r": 18,
+			"c": 25,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 2,
+			"ntypes": 4,
+			"types": [
+				0,
+				1,
+				2,
+				14
+			],
+			"times": [
+				1,
+				2,
+				2,
+				6
+			],
+			"instance": [
+				 0,
+				 0,
+				 0,
+				 0
+			]
+		},
+		{
+			"name": "Sapphire",
+			"cluster": 4,
+			"nation": 0,
+			"r": 19,
+			"c": 22,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 2,
+			"ntypes": 4,
+			"types": [
+				0,
+				1,
+				2,
+				20
+			],
+			"times": [
+				1,
+				2,
+				2,
+				5
+			],
+			"instance": [
+				 0,
+				 0,
+				 0,
+				 0
+			]
+		},
+		{
+			"name": "Zhentil Keep",
+			"cluster": 5,
+			"nation": 0,
+			"r": 40,
+			"c": 18,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 2,
+			"ntypes": 4,
+			"types": [
+				0,
+				1,
+				2,
+				3
+			],
+			"times": [
+				1,
+				2,
+				2,
+				4
+			],
+			"instance": [
+				 0,
+				 0,
+				 0,
+				 0
+			]
+		},
+		{
+			"name": "Shadowdale",
+			"cluster": 5,
+			"nation": 0,
+			"r": 42,
+			"c": 20,
+			"prod_type": 0,
+			"turns_left": 5,
+			"defense": 2,
+			"ntypes": 4,
+			"types": [
+				0,
+				1,
+				2,
+				14
+			],
+			"times": [
+				1,
+				2,
+				2,
+				6
+			],
+			"instance": [
+				 0,
+				 0,
+				 0,
+				 0
+			]
+		},
+		{
+			"name": "Silverdale",
+			"cluster": 5,
+			"nation": 0,
+			"r": 45,
+			"c": 22,
+			"prod_type": 0,
+			"turns_left": 2,
+			"defense": 2,
+			"ntypes": 4,
+			"types": [
+				0,
+				1,
+				2,
+				20
+			],
+			"times": [
+				1,
+				2,
+				2,
+				6
+			],
+			"instance": [
+				 0,
+				 0,
+				 0,
+				 0
+			]
+		},
+		{
+			"name": "Battledale",
+			"cluster": 5,
+			"nation": 0,
+			"r": 48,
+			"c": 24,
+			"prod_type": 0,
+			"turns_left": 3,
+			"defense": 2,
+			"ntypes": 4,
+			"types": [
+				0,
+				1,
+				2,
+				14
+			],
+			"times": [
+				1,
+				2,
+				2,
+				6
+			],
+			"instance": [
+				 0,
+				 0,
+				 0,
+				 0
+			]
+		},
+		{
+			"name": "Dread",
+			"cluster": 6,
+			"nation": 0,
+			"r": 38,
+			"c": 0,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 3,
+			"ntypes": 2,
+			"types": [
+				6,
+				7,
+				-1,
+				-1
+			],
+			"times": [
+				1,
+				4,
+				-1,
+				-1
+			],
+			"instance": [
+				9,
+				7,
+				-1,
+				-1
+			]
+		},
+		{
+			"name": "Doom",
+			"cluster": 6,
+			"nation": 0,
+			"r": 39,
+			"c": 4,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 3,
+			"ntypes": 3,
+			"types": [
+				6,
+				7,
+				15,
+				-1
+			],
+			"times": [
+				1,
+				4,
+				6,
+				-1
+			],
+			"instance": [
+				17,
+				8,
+				0,
+				-1
+			]
+		},
+		{
+			"name": "Despair",
+			"cluster": 6,
+			"nation": 0,
+			"r": 42,
+			"c": 3,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 3,
+			"ntypes": 2,
+			"types": [
+				6,
+				13,
+				-1,
+				-1
+			],
+			"times": [
+				1,
+				3,
+				-1,
+				-1
+			],
+			"instance": [
+				9,
+				9,
+				-1,
+				-1
+			]
+		},
+		{
+			"name": "Death",
+			"cluster": 6,
+			"nation": 0,
+			"r": 43,
+			"c": 9,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 3,
+			"ntypes": 2,
+			"types": [
+				6,
+				7,
+				-1,
+				-1
+			],
+			"times": [
+				1,
+				5,
+				-1,
+				-1
+			],
+			"instance": [
+				31,
+				0,
+				-1,
+				-1
+			]
+		},
+		{
+			"name": "Agony",
+			"cluster": 6,
+			"nation": 0,
+			"r": 45,
+			"c": 4,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 3,
+			"ntypes": 3,
+			"types": [
+				6,
+				13,
+				15,
+				-1
+			],
+			"times": [
+				1,
+				3,
+				6,
+				-1
+			],
+			"instance": [
+				30,
+				0,
+				0,
+				-1
+			]
+		},
+		{
+			"name": "Gloom",
+			"cluster": 6,
+			"nation": 0,
+			"r": 49,
+			"c": 3,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 3,
+			"ntypes": 2,
+			"types": [
+				6,
+				7,
+				-1,
+				-1
+			],
+			"times": [
+				1,
+				5,
+				-1,
+				-1
+			],
+			"instance": [
+				12,
+				0,
+				-1,
+				-1
+			]
+		},
+		{
+			"name": "Iron",
+			"cluster": 7,
+			"nation": 0,
+			"r": 55,
+			"c": 8,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 3,
+			"ntypes": 4,
+			"types": [
+				0,
+				1,
+				8,
+				14
+			],
+			"times": [
+				1,
+				2,
+				3,
+				6
+			],
+			"instance": [
+				 0,
+				 0,
+				 0,
+				 0
+			]
+		},
+		{
+			"name": "Gold",
+			"cluster": 7,
+			"nation": 0,
+			"r": 54,
+			"c": 14,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 3,
+			"ntypes": 4,
+			"types": [
+				0,
+				1,
+				8,
+				20
+			],
+			"times": [
+				1,
+				2,
+				3,
+				5
+			],
+			"instance": [
+				 0,
+				 0,
+				 0,
+				 0
+			]
+		},
+		{
+			"name": "Silver",
+			"cluster": 7,
+			"nation": 0,
+			"r": 58,
+			"c": 13,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 3,
+			"ntypes": 4,
+			"types": [
+				0,
+				1,
+				8,
+				14
+			],
+			"times": [
+				1,
+				2,
+				3,
+				6
+			],
+			"instance": [
+				 0,
+				 0,
+				 0,
+				 0
+			]
+		},
+		{
+			"name": "Tin",
+			"cluster": 7,
+			"nation": 0,
+			"r": 57,
+			"c": 10,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 3,
+			"ntypes": 3,
+			"types": [
+				0,
+				1,
+				8,
+				-1
+			],
+			"times": [
+				1,
+				2,
+				3,
+				-1
+			],
+			"instance": [
+				9,
+				0,
+				0,
+				-1
+			]
+		},
+		{
+			"name": "Lead",
+			"cluster": 7,
+			"nation": 0,
+			"r": 51,
+			"c": 13,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 3,
+			"ntypes": 3,
+			"types": [
+				0,
+				1,
+				8,
+				-1
+			],
+			"times": [
+				1,
+				2,
+				3,
+				-1
+			],
+			"instance": [
+				9,
+				0,
+				0,
+				-1
+			]
+		},
+		{
+			"name": "Nyarlathotep",
+			"cluster": 8,
+			"nation": 0,
+			"r": 34,
+			"c": 55,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 2,
+			"ntypes": 2,
+			"types": [
+				9,
+				12,
+				-1,
+				-1
+			],
+			"times": [
+				1,
+				3,
+				-1,
+				-1
+			],
+			"instance": [
+				7,
+				0,
+				-1,
+				-1
+			]
+		},
+		{
+			"name": "Yogsothoth",
+			"cluster": 8,
+			"nation": 0,
+			"r": 30,
+			"c": 52,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 2,
+			"ntypes": 2,
+			"types": [
+				9,
+				12,
+				-1,
+				-1
+			],
+			"times": [
+				1,
+				3,
+				-1,
+				-1
+			],
+			"instance": [
+				7,
+				0,
+				-1,
+				-1
+			]
+		},
+		{
+			"name": "Cthulhu",
+			"cluster": 8,
+			"nation": 0,
+			"r": 31,
+			"c": 57,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 2,
+			"ntypes": 2,
+			"types": [
+				9,
+				13,
+				-1,
+				-1
+			],
+			"times": [
+				1,
+				3,
+				-1,
+				-1
+			],
+			"instance": [
+				7,
+				0,
+				-1,
+				-1
+			]
+		},
+		{
+			"name": "Hastor",
+			"cluster": 8,
+			"nation": 0,
+			"r": 28,
+			"c": 59,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 2,
+			"ntypes": 2,
+			"types": [
+				9,
+				13,
+				-1,
+				-1
+			],
+			"times": [
+				1,
+				3,
+				-1,
+				-1
+			],
+			"instance": [
+				7,
+				0,
+				-1,
+				-1
+			]
+		},
+		{
+			"name": "Olan",
+			"cluster": 9,
+			"nation": 0,
+			"r": 42,
+			"c": 59,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 3,
+			"ntypes": 2,
+			"types": [
+				4,
+				10,
+				-1,
+				-1
+			],
+			"times": [
+				1,
+				3,
+				-1,
+				-1
+			],
+			"instance": [
+				10,
+				0,
+				-1,
+				-1
+			]
+		},
+		{
+			"name": "Kaxandar",
+			"cluster": 9,
+			"nation": 0,
+			"r": 40,
+			"c": 58,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 3,
+			"ntypes": 2,
+			"types": [
+				4,
+				10,
+				-1,
+				-1
+			],
+			"times": [
+				1,
+				3,
+				-1,
+				-1
+			],
+			"instance": [
+				11,
+				0,
+				-1,
+				-1
+			]
+		},
+		{
+			"name": "Torgar",
+			"cluster": 9,
+			"nation": 0,
+			"r": 46,
+			"c": 60,
+			"prod_type": 0,
+			"turns_left": 2,
+			"defense": 3,
+			"ntypes": 2,
+			"types": [
+				4,
+				10,
+				-1,
+				-1
+			],
+			"times": [
+				1,
+				3,
+				-1,
+				-1
+			],
+			"instance": [
+				14,
+				1,
+				-1,
+				-1
+			]
+		},
+		{
+			"name": "Arras Charka",
+			"cluster": 10,
+			"nation": 0,
+			"r": 18,
+			"c": 43,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 2,
+			"ntypes": 3,
+			"types": [
+				0,
+				1,
+				21,
+				-1
+			],
+			"times": [
+				1,
+				2,
+				6,
+				-1
+			],
+			"instance": [
+				7,
+				0,
+				0,
+				-1
+			]
+		},
+		{
+			"name": "Derzon",
+			"cluster": 10,
+			"nation": 0,
+			"r": 17,
+			"c": 51,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 2,
+			"ntypes": 3,
+			"types": [
+				0,
+				1,
+				2,
+				-1
+			],
+			"times": [
+				1,
+				2,
+				2,
+				-1
+			],
+			"instance": [
+				9,
+				0,
+				0,
+				-1
+			]
+		},
+		{
+			"name": "Ekosiak",
+			"cluster": 10,
+			"nation": 0,
+			"r": 20,
+			"c": 47,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 2,
+			"ntypes": 4,
+			"types": [
+				0,
+				1,
+				2,
+				3
+			],
+			"times": [
+				1,
+				2,
+				2,
+				4
+			],
+			"instance": [
+				 0,
+				 0,
+				 0,
+				 0
+			]
+		},
+		{
+			"name": "Ish-Tako",
+			"cluster": 10,
+			"nation": 0,
+			"r": 16,
+			"c": 46,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 2,
+			"ntypes": 4,
+			"types": [
+				0,
+				1,
+				8,
+				14
+			],
+			"times": [
+				1,
+				2,
+				3,
+				6
+			],
+			"instance": [
+				 0,
+				 0,
+				 0,
+				 0
+			]
+		},
+		{
+			"name": "Chishata",
+			"cluster": 10,
+			"nation": 0,
+			"r": 23,
+			"c": 50,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 2,
+			"ntypes": 4,
+			"types": [
+				0,
+				1,
+				8,
+				14
+			],
+			"times": [
+				1,
+				2,
+				3,
+				6
+			],
+			"instance": [
+				 0,
+				 0,
+				 0,
+				 0
+			]
+		},
+		{
+			"name": "Qualinesti",
+			"cluster": 11,
+			"nation": 0,
+			"r": 53,
+			"c": 54,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 2,
+			"ntypes": 4,
+			"types": [
+				17,
+				5,
+				11,
+				20
+			],
+			"times": [
+				1,
+				2,
+				2,
+				4
+			],
+			"instance": [
+				 0,
+				 0,
+				 0,
+				 0
+			]
+		},
+		{
+			"name": "Sylvanesti",
+			"cluster": 11,
+			"nation": 0,
+			"r": 56,
+			"c": 55,
+			"prod_type": 0,
+			"turns_left": 3,
+			"defense": 2,
+			"ntypes": 4,
+			"types": [
+				17,
+				5,
+				11,
+				16
+			],
+			"times": [
+				1,
+				2,
+				2,
+				7
+			],
+			"instance": [
+				 0,
+				 0,
+				 0,
+				 0
+			]
+		},
+		{
+			"name": "Rathwynn",
+			"cluster": 11,
+			"nation": 0,
+			"r": 62,
+			"c": 58,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 2,
+			"ntypes": 3,
+			"types": [
+				17,
+				5,
+				11,
+				-1
+			],
+			"times": [
+				1,
+				2,
+				2,
+				-1
+			],
+			"instance": [
+				20,
+				0,
+				0,
+				-1
+			]
+		},
+		{
+			"name": "Caledon",
+			"cluster": 11,
+			"nation": 0,
+			"r": 60,
+			"c": 54,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 2,
+			"ntypes": 4,
+			"types": [
+				17,
+				5,
+				11,
+				16
+			],
+			"times": [
+				1,
+				2,
+				2,
+				7
+			],
+			"instance": [
+				  0,
+				  0,
+				  0,
+				  0
+			]
+		},
+		{
+			"name": "Alfheim",
+			"cluster": 11,
+			"nation": 0,
+			"r": 58,
+			"c": 51,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 2,
+			"ntypes": 4,
+			"types": [
+				17,
+				5,
+				11,
+				16
+			],
+			"times": [
+				1,
+				2,
+				2,
+				7
+			],
+			"instance": [
+				 0,
+				 0,
+				 0,
+				 0
+			]
+		},
+		{
+			"name": "Atlantis",
+			"cluster": 12,
+			"nation": 0,
+			"r": 49,
+			"c": 41,
+			"prod_type": 0,
+			"turns_left": 2,
+			"defense": 2,
+			"ntypes": 3,
+			"types": [
+				18,
+				19,
+				22,
+				-1
+			],
+			"times": [
+				1,
+				2,
+				8,
+				-1
+			],
+			"instance": [
+				6,
+				0,
+				3,
+				-1
+			]
+		},
+		{
+			"name": "Mu",
+			"cluster": 12,
+			"nation": 0,
+			"r": 49,
+			"c": 37,
+			"prod_type": 0,
+			"turns_left": 3,
+			"defense": 2,
+			"ntypes": 3,
+			"types": [
+				18,
+				19,
+				22,
+				-1
+			],
+			"times": [
+				1,
+				2,
+				8,
+				-1
+			],
+			"instance": [
+				7,
+				0,
+				3,
+				-1
+			]
+		},
+		{
+			"name": "Poseidon",
+			"cluster": 12,
+			"nation": 0,
+			"r": 46,
+			"c": 42,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 2,
+			"ntypes": 3,
+			"types": [
+				18,
+				19,
+				22,
+				-1
+			],
+			"times": [
+				1,
+				2,
+				8,
+				-1
+			],
+			"instance": [
+				7,
+				0,
+				3,
+				-1
+			]
+		},
+		{
+			"name": "Neptune",
+			"cluster": 12,
+			"nation": 0,
+			"r": 44,
+			"c": 38,
+			"prod_type": 0,
+			"turns_left": 8,
+			"defense": 2,
+			"ntypes": 3,
+			"types": [
+				18,
+				19,
+				22,
+				-1
+			],
+			"times": [
+				1,
+				2,
+				8,
+				-1
+			],
+			"instance": [
+				7,
+				0,
+				4,
+				-1
+			]
+		}
+	],
+	"ttypes": [
+		{
+			"name": "Lt. Infantry",
+			"combat": 2,
+			"move_rate": 6,
+			"move_tbl": 0,
+			"special_mv": 0
+		},
+		{
+			"name": "Hv. Infantry",
+			"combat": 3,
+			"move_rate": 4,
+			"move_tbl": 0,
+			"special_mv": 0
+		},
+		{
+			"name": "Lt. Cavalry",
+			"combat": 2,
+			"move_rate": 12,
+			"move_tbl": 1,
+			"special_mv": 0
+		},
+		{
+			"name": "Hv. Cavalry",
+			"combat": 3,
+			"move_rate": 8,
+			"move_tbl": 1,
+			"special_mv": 0
+		},
+		{
+			"name": "Dwarf Legion",
+			"combat": 3,
+			"move_rate": 4,
+			"move_tbl": 2,
+			"special_mv": 0
+		},
+		{
+			"name": "Elven Archers",
+			"combat": 3,
+			"move_rate": 6,
+			"move_tbl": 3,
+			"special_mv": 0
+		},
+		{
+			"name": "Zombie Legion",
+			"combat": 3,
+			"move_rate": 3,
+			"move_tbl": 0,
+			"special_mv": 0
+		},
+		{
+			"name": "Wraith Horde",
+			"combat": 4,
+			"move_rate": 6,
+			"move_tbl": 4,
+			"special_mv": 0
+		},
+		{
+			"name": "Elite Troopers",
+			"combat": 4,
+			"move_rate": 4,
+			"move_tbl": 0,
+			"special_mv": 0
+		},
+		{
+			"name": "Gug",
+			"combat": 3,
+			"move_rate": 4,
+			"move_tbl": 0,
+			"special_mv": 0
+		},
+		{
+			"name": "Dwarf Miners",
+			"combat": 4,
+			"move_rate": 4,
+			"move_tbl": 5,
+			"special_mv": 0
+		},
+		{
+			"name": "Scout",
+			"combat": 1,
+			"move_rate": 8,
+			"move_tbl": 6,
+			"special_mv": 0
+		},
+		{
+			"name": "Byakhee",
+			"combat": 2,
+			"move_rate": 7,
+			"move_tbl": 4,
+			"special_mv": 2
+		},
+		{
+			"name": "Ghouls",
+			"combat": 3,
+			"move_rate": 5,
+			"move_tbl": 0,
+			"special_mv": 0
+		},
+		{
+			"name": "Navy",
+			"combat": 2,
+			"move_rate": 10,
+			"move_tbl": 7,
+			"special_mv": 3
+		},
+		{
+			"name": "Undead Navy",
+			"combat": 3,
+			"move_rate": 8,
+			"move_tbl": 7,
+			"special_mv": 3
+		},
+		{
+			"name": "Elf Clipper",
+			"combat": 2,
+			"move_rate": 12,
+			"move_tbl": 7,
+			"special_mv": 3
+		},
+		{
+			"name": "Elf Infantry",
+			"combat": 2,
+			"move_rate": 8,
+			"move_tbl": 3,
+			"special_mv": 0
+		},
+		{
+			"name": "Mermen",
+			"combat": 2,
+			"move_rate": 6,
+			"move_tbl": 7,
+			"special_mv": 0
+		},
+		{
+			"name": "Tritons",
+			"combat": 3,
+			"move_rate": 4,
+			"move_tbl": 7,
+			"special_mv": 0
+		},
+		{
+			"name": "Pegasus",
+			"combat": 2,
+			"move_rate": 10,
+			"move_tbl": 4,
+			"special_mv": 1
+		},
+		{
+			"name": "Hippogryff",
+			"combat": 3,
+			"move_rate": 8,
+			"move_tbl": 4,
+			"special_mv": 1
+		},
+		{
+			"name": "Leviathan",
+			"combat": 5,
+			"move_rate": 4,
+			"move_tbl": 8,
+			"special_mv": 1
+		}
+	],
+	"armies": [],
+	"move_table": [
+		{
+			"cost": [
+				0,
+				1,
+				2,
+				2,
+				4
+			]
+		},
+		{
+			"cost": [
+				0,
+				1,
+				2,
+				3,
+				0
+			]
+		},
+		{
+			"cost": [
+				0,
+				1,
+				2,
+				1,
+				2
+			]
+		},
+		{
+			"cost": [
+				0,
+				1,
+				1,
+				2,
+				4
+			]
+		},
+		{
+			"cost": [
+				1,
+				1,
+				1,
+				1,
+				2
+			]
+		},
+		{
+			"cost": [
+				0,
+				1,
+				2,
+				2,
+				3
+			]
+		},
+		{
+			"cost": [
+				0,
+				1,
+				1,
+				1,
+				2
+			]
+		},
+		{
+			"cost": [
+				1,
+				0,
+				0,
+				0,
+				0
+			]
+		},
+		{
+			"cost": [
+				1,
+				1,
+				2,
+				3,
+				4
+			]
+		}
+	],
+	"world": "Solomoriah's World",
+	"gen": 0
+}
diff --git a/xtrn/war/worlds/earth/map b/xtrn/war/worlds/earth/map
new file mode 100644
index 0000000000000000000000000000000000000000..4cf7706ebde5168af702c1b69d5f50df950bc720
--- /dev/null
+++ b/xtrn/war/worlds/earth/map
@@ -0,0 +1,66 @@
+M 64 64
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+~~~~~~~~%%....%~~~~~~~~~~~~~~~~~~~~~~~~~~~.~~~~^...~~~~.~~~~~~~~
+~~~~~~~~~~.^~%^~~~~~~~~~~~~~~~~~~~~~~~~~%.~~~~^.^^^~~~~^%~~~~~~~
+~~~~~~~~^.~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~.^.^^.~~~~~~~~~~~~~
+~~~~~~~~.^.~~~~.~~~~~~~~~~~~~~~~~~~~~~~~~~~.~^^^^^^^..~~~~~~~~~~
+~~~~~~~~~~##~.~^^%~~~~~~~~~~~~~~~~~%~~~~~~.^^..^^..^^^^^^^.~~~%~
+~~.^~~~~~~...%~^#.~~~~~~~~~~~~~~~~%%%~~~~~.^^..^^.^.^^^^^^^~~~~~
+~.....^^....~.%%~^%~~~~~~~~~~~~~~^^^#^%.^^^#^^^.....^.^^^^^^^^#~
+~~.....^......^%~..~~~~~~~~~~~~~~^^^^#^^^^^.^^^....^^^^.^^^^^.^.
+~#^^^.......^^.^~%.~~~~~~~~~~~~~%^.^^.^^^^^^^^^^....^^..^^..^^.^
+~~^.....^^..^^%%~..~~~~~~~~~~~~%##.##^^^^#^^^^..^..^^^^.^^.^^^~~
+~^^.....^....^~~~^~~~~~~~~~~~%~##^##.^^^^^^^^^^......^^.^^..^~~~
+~.^.%.....^...~~~^~~~~~~~~~~~%~%##^.^#^^.^^^^^^.....^.^.^^~~.~~~
+~~.%~~.......#~~~.^.~~~~~~~~~~~..%^#^##^.^^^^^^^.^..^...~~~^~~~~
+~~~~~~~#.....^^.....~~~~~~~~~~..#.####^^.^#^^^........^~~~^.~~~~
+~~~~~~~~.......^^...%~~~~~~~~.%######^^^^.^.^^........^#~~.~~~~~
+~~~~~~~~.......^^.^..~~~~~~~~^####^^^##^.^...^.......^^^~~~~~~~~
+~~~~~~~~^^.....^.^^.~~~~~~~~~~######.#^.^^^..^.......^^~~~~~~~~~
+~~~~~~~~.^.......##~~~~~~~~~~~######~~~...^..........^%~~~~~~~~~
+~~~~~~~~.^....^.^%~~~~~~~~~~~^%~~~##~~#.##.^.........%~~~~~~~~~~
+~~~~~~~~^^....^^^~~~~~~~~~~~~~~~~~~~.^..##^^...#...^.~~#~~~~~~~~
+~~~~~~~~~%^..^^^~~~~~~~~~~~~~^^#~~~~~.#..^.#.####..^~~##~~~~~~~~
+~~~~~~~~~~...^^^~~~~~~~~~~~~~#.#^%~~~.^^.^^^^###...^.~#~~~~~~~~~
+~~~~~~~~~~~^^~~~~~~~~~~~~~~~#^^^^.^^^^~^#~~.^###..^.~~~~~~~~~~~~
+~~~~~~~~~~~^.~~~~~~~~~~~~~~~#^^^^^^^^^~~##~..#^^..^.~~~~~~~~~~~~
+~~~~~~~~~~~~.~~~~~~~~~~~~~~%#^^^^^^.^^.~##~^^^~#^^^#~~~~~~~~~~~~
+~~~~~~~~~~~~~%#~~~~~~~~~~~~##^^^^^..^#^~~~~~.~~~#####~~~~~~~~~~~
+~~~~~~~~~~~~~~~%~~%~~~~~~~~~#^#^^...^^^~~~~~%~~%.#%~#~~~~~~~~~~~
+~~~~~~~~~~~~~~~~%^^#~~~~~~~~####^^^^..^~~~~~~~~~~~~~~~~~~~~~~~~~
+~~~~~~~~~~~~~~~~^.^#^~%~~~~~~~~~##^.^^%~~~~~~~~~~.^#~~~~~~~~~~~~
+~~~~~~~~~~~~~~~#^^^^##.~~~~~~~~~###..#~~~~~~~~~~%.~~~~~~~~~~~~~~
+~~~~~~~~~~~~~~#^##^^##.%~~~~~~~~%##^.#~~~~~~~~~~~~~.~~~~~~~~~~~~
+~~~~~~~~~~~~~~##..^#.^^^~~~~~~~~~^^^.^~~~~~~~~~~~~%~%~~.~~~~~~~~
+~~~~~~~~~~~~~~..###^##^~~~~~~~~~~^.^^%~~#~~~~~~~~~~~~~#~~~~~~~~~
+~~~~~~~~~~~~~~~#%%#^#^#~~~~~~~~~~.^^^%~##~~~~~~~~~~~.^^.~~~~~~~~
+~~~~~~~~~~~~~~~%%%^^^#%~~~~~~~~~~^.^#~~#~~~~~~~~~~~.^^^#.~~~~~~~
+~~~~~~~~~~~~~~~%%%###%~~~~~~~~~~%#^##~~~~~~~~~~~~~~#######~~~~~~
+~~~~~~~~~~~~~~~%%%###~~~~~~~~~~~~%^.#~~~~~~~~~~~~~~^####^#~~~~~~
+~~~~~~~~~~~~~~~%#####~~~~~~~~~~~~~#%~~~~~~~~~~~~~~~%%#%###~~~~~~
+~~~~~~~~~~~~~~~%%%^#~~~~~~~~~~~~~~%~~~~~~~~~~~~~~~~%~#~#%%~~~~~~
+~~~~~~~~~~~~~~~%%#^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%~~~~#~~
+~~~~~~~~~~~~~~~~%##~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~.~~
+~~~~~~~~~~~~~~~~~#^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+~~~~~~~~~~~~~~~~~#%~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+~~~~~~~~~~~~~~~~~#%~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+~~~~~~~~~~~~~~~~~%%~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
diff --git a/xtrn/war/worlds/solomoriah/game.orig.json b/xtrn/war/worlds/solomoriah/game.orig.json
new file mode 100644
index 0000000000000000000000000000000000000000..5ea6525e0b91f82be3883ca04522e6299a97c9e8
--- /dev/null
+++ b/xtrn/war/worlds/solomoriah/game.orig.json
@@ -0,0 +1,2047 @@
+{
+	"ncnt": 1,
+	"nations": [
+		{
+			"name": "Overlord",
+			"uid": 0,
+			"city": 0,
+			"mark": "*",
+			"idle_turns": 0
+		},
+		{
+			"name": "",
+			"uid": 0,
+			"city": 0,
+			"mark": "*",
+			"idle_turns": 0
+		},
+		{
+			"name": "",
+			"uid": 0,
+			"city": 0,
+			"mark": "*",
+			"idle_turns": 0
+		},
+		{
+			"name": "",
+			"uid": 0,
+			"city": 0,
+			"mark": "*",
+			"idle_turns": 0
+		},
+		{
+			"name": "",
+			"uid": 0,
+			"city": 0,
+			"mark": "*",
+			"idle_turns": 0
+		},
+		{
+			"name": "",
+			"uid": 0,
+			"city": 0,
+			"mark": "*",
+			"idle_turns": 0
+		},
+		{
+			"name": "",
+			"uid": 0,
+			"city": 0,
+			"mark": "*",
+			"idle_turns": 0
+		},
+		{
+			"name": "",
+			"uid": 0,
+			"city": 0,
+			"mark": "*",
+			"idle_turns": 0
+		},
+		{
+			"name": "",
+			"uid": 0,
+			"city": 0,
+			"mark": "*",
+			"idle_turns": 0
+		},
+		{
+			"name": "",
+			"uid": 0,
+			"city": 0,
+			"mark": "*",
+			"idle_turns": 0
+		},
+		{
+			"name": "",
+			"uid": 0,
+			"city": 0,
+			"mark": "*",
+			"idle_turns": 0
+		},
+		{
+			"name": "",
+			"uid": 0,
+			"city": 0,
+			"mark": "*",
+			"idle_turns": 0
+		},
+		{
+			"name": "",
+			"uid": 0,
+			"city": 0,
+			"mark": "*",
+			"idle_turns": 0
+		},
+		{
+			"name": "",
+			"uid": 0,
+			"city": 0,
+			"mark": "*",
+			"idle_turns": 0
+		},
+		{
+			"name": "",
+			"uid": 0,
+			"city": 0,
+			"mark": "*",
+			"idle_turns": 0
+		},
+		{
+			"name": "",
+			"uid": 0,
+			"city": 0,
+			"mark": "*",
+			"idle_turns": 0
+		},
+		{
+			"name": "",
+			"uid": 0,
+			"city": 0,
+			"mark": "*",
+			"idle_turns": 0
+		},
+		{
+			"name": "",
+			"uid": 0,
+			"city": 0,
+			"mark": "*",
+			"idle_turns": 0
+		},
+		{
+			"name": "",
+			"uid": 0,
+			"city": 0,
+			"mark": "*",
+			"idle_turns": 0
+		},
+		{
+			"name": "",
+			"uid": 0,
+			"city": 0,
+			"mark": "*",
+			"idle_turns": 0
+		},
+		{
+			"name": "",
+			"uid": 0,
+			"city": 0,
+			"mark": "*",
+			"idle_turns": 0
+		},
+		{
+			"name": "",
+			"uid": 0,
+			"city": 0,
+			"mark": "*",
+			"idle_turns": 0
+		},
+		{
+			"name": "",
+			"uid": 0,
+			"city": 0,
+			"mark": "*",
+			"idle_turns": 0
+		},
+		{
+			"name": "",
+			"uid": 0,
+			"city": 0,
+			"mark": "*",
+			"idle_turns": 0
+		},
+		{
+			"name": "",
+			"uid": 0,
+			"city": 0,
+			"mark": "*",
+			"idle_turns": 0
+		},
+		{
+			"name": "",
+			"uid": 0,
+			"city": 0,
+			"mark": "*",
+			"idle_turns": 0
+		},
+		{
+			"name": "",
+			"uid": 0,
+			"city": 0,
+			"mark": "*",
+			"idle_turns": 0
+		},
+		{
+			"name": "Rogue",
+			"uid": -1,
+			"city": 0,
+			"mark": "?",
+			"idle_turns": 0
+		}
+	],
+	"cities": [
+		{
+			"name": "Indigo",
+			"cluster": 1,
+			"nation": 0,
+			"r": 5,
+			"c": 4,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 2,
+			"ntypes": 4,
+			"types": [
+				0,
+				1,
+				2,
+				21
+			],
+			"times": [
+				1,
+				2,
+				2,
+				6
+			],
+			"instance": [
+				0,
+				0,
+				0,
+				0
+			]
+		},
+		{
+			"name": "Lavender",
+			"cluster": 1,
+			"nation": 0,
+			"r": 7,
+			"c": 2,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 2,
+			"ntypes": 4,
+			"types": [
+				0,
+				1,
+				2,
+				14
+			],
+			"times": [
+				1,
+				2,
+				2,
+				6
+			],
+			"instance": [
+				0,
+				0,
+				0,
+				0
+			]
+		},
+		{
+			"name": "Crimson",
+			"cluster": 1,
+			"nation": 0,
+			"r": 3,
+			"c": 5,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 2,
+			"ntypes": 3,
+			"types": [
+				0,
+				1,
+				2,
+				3
+			],
+			"times": [
+				1,
+				2,
+				2,
+				4
+			],
+			"instance": [
+				0,
+				0,
+				0,
+				0
+			]
+		},
+		{
+			"name": "Saffron",
+			"cluster": 1,
+			"nation": 0,
+			"r": 9,
+			"c": 8,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 2,
+			"ntypes": 3,
+			"types": [
+				0,
+				1,
+				2,
+				-1
+			],
+			"times": [
+				1,
+				2,
+				2,
+				-1
+			],
+			"instance": [
+				0,
+				0,
+				0,
+				-1
+			]
+		},
+		{
+			"name": "Verdant",
+			"cluster": 1,
+			"nation": 0,
+			"r": 6,
+			"c": 10,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 2,
+			"ntypes": 4,
+			"types": [
+				0,
+				1,
+				2,
+				14
+			],
+			"times": [
+				1,
+				2,
+				2,
+				6
+			],
+			"instance": [
+				0,
+				0,
+				0,
+				0
+			]
+		},
+		{
+			"name": "Metropolis",
+			"cluster": 2,
+			"nation": 0,
+			"r": 28,
+			"c": 10,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 2,
+			"ntypes": 4,
+			"types": [
+				0,
+				1,
+				2,
+				3
+			],
+			"times": [
+				1,
+				2,
+				2,
+				4
+			],
+			"instance": [
+				0,
+				0,
+				0,
+				0
+			]
+		},
+		{
+			"name": "Gotham",
+			"cluster": 2,
+			"nation": 0,
+			"r": 29,
+			"c": 5,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 2,
+			"ntypes": 3,
+			"types": [
+				0,
+				1,
+				2,
+				-1
+			],
+			"times": [
+				1,
+				2,
+				2,
+				-1
+			],
+			"instance": [
+				0,
+				0,
+				0,
+				-1
+			]
+		},
+		{
+			"name": "Keystone City",
+			"cluster": 2,
+			"nation": 0,
+			"r": 31,
+			"c": 8,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 2,
+			"ntypes": 4,
+			"types": [
+				0,
+				1,
+				2,
+				20
+			],
+			"times": [
+				1,
+				2,
+				2,
+				5
+			],
+			"instance": [
+				0,
+				0,
+				0,
+				0
+			]
+		},
+		{
+			"name": "Central City",
+			"cluster": 2,
+			"nation": 0,
+			"r": 35,
+			"c": 9,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 2,
+			"ntypes": 4,
+			"types": [
+				0,
+				1,
+				2,
+				14
+			],
+			"times": [
+				1,
+				2,
+				2,
+				6
+			],
+			"instance": [
+				0,
+				0,
+				0,
+				0
+			]
+		},
+		{
+			"name": "Heliochrysum",
+			"cluster": 3,
+			"nation": 0,
+			"r": 32,
+			"c": 24,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 2,
+			"ntypes": 4,
+			"types": [
+				0,
+				1,
+				2,
+				3
+			],
+			"times": [
+				1,
+				2,
+				2,
+				4
+			],
+			"instance": [
+				0,
+				0,
+				0,
+				0
+			]
+		},
+		{
+			"name": "Portulaca",
+			"cluster": 3,
+			"nation": 0,
+			"r": 33,
+			"c": 29,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 2,
+			"ntypes": 4,
+			"types": [
+				0,
+				1,
+				2,
+				3
+			],
+			"times": [
+				1,
+				2,
+				2,
+				4
+			],
+			"instance": [
+				0,
+				0,
+				0,
+				0
+			]
+		},
+		{
+			"name": "Gaillardia",
+			"cluster": 3,
+			"nation": 0,
+			"r": 38,
+			"c": 24,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 2,
+			"ntypes": 4,
+			"types": [
+				0,
+				1,
+				2,
+				14
+			],
+			"times": [
+				1,
+				2,
+				2,
+				6
+			],
+			"instance": [
+				0,
+				0,
+				0,
+				0
+			]
+		},
+		{
+			"name": "Coreopsis",
+			"cluster": 3,
+			"nation": 0,
+			"r": 36,
+			"c": 21,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 2,
+			"ntypes": 4,
+			"types": [
+				0,
+				1,
+				2,
+				21
+			],
+			"times": [
+				1,
+				2,
+				2,
+				6
+			],
+			"instance": [
+				0,
+				0,
+				0,
+				0
+			]
+		},
+		{
+			"name": "Delphineum",
+			"cluster": 3,
+			"nation": 0,
+			"r": 33,
+			"c": 19,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 2,
+			"ntypes": 4,
+			"types": [
+				0,
+				1,
+				2,
+				14
+			],
+			"times": [
+				1,
+				2,
+				2,
+				6
+			],
+			"instance": [
+				0,
+				0,
+				0,
+				0
+			]
+		},
+		{
+			"name": "Ruby",
+			"cluster": 4,
+			"nation": 0,
+			"r": 14,
+			"c": 23,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 2,
+			"ntypes": 4,
+			"types": [
+				0,
+				1,
+				2,
+				3
+			],
+			"times": [
+				1,
+				2,
+				2,
+				4
+			],
+			"instance": [
+				0,
+				0,
+				0,
+				0
+			]
+		},
+		{
+			"name": "Amber",
+			"cluster": 4,
+			"nation": 0,
+			"r": 16,
+			"c": 20,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 2,
+			"ntypes": 3,
+			"types": [
+				0,
+				1,
+				2,
+				-1
+			],
+			"times": [
+				1,
+				2,
+				2,
+				-1
+			],
+			"instance": [
+				0,
+				0,
+				0,
+				-1
+			]
+		},
+		{
+			"name": "Emerald",
+			"cluster": 4,
+			"nation": 0,
+			"r": 16,
+			"c": 28,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 2,
+			"ntypes": 4,
+			"types": [
+				0,
+				1,
+				2,
+				14
+			],
+			"times": [
+				1,
+				2,
+				2,
+				6
+			],
+			"instance": [
+				0,
+				0,
+				0,
+				0
+			]
+		},
+		{
+			"name": "Diamond",
+			"cluster": 4,
+			"nation": 0,
+			"r": 18,
+			"c": 25,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 2,
+			"ntypes": 4,
+			"types": [
+				0,
+				1,
+				2,
+				14
+			],
+			"times": [
+				1,
+				2,
+				2,
+				6
+			],
+			"instance": [
+				0,
+				0,
+				0,
+				0
+			]
+		},
+		{
+			"name": "Sapphire",
+			"cluster": 4,
+			"nation": 0,
+			"r": 19,
+			"c": 22,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 2,
+			"ntypes": 4,
+			"types": [
+				0,
+				1,
+				2,
+				20
+			],
+			"times": [
+				1,
+				2,
+				2,
+				5
+			],
+			"instance": [
+				0,
+				0,
+				0,
+				0
+			]
+		},
+		{
+			"name": "Zhentil Keep",
+			"cluster": 5,
+			"nation": 0,
+			"r": 40,
+			"c": 18,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 2,
+			"ntypes": 4,
+			"types": [
+				0,
+				1,
+				2,
+				3
+			],
+			"times": [
+				1,
+				2,
+				2,
+				4
+			],
+			"instance": [
+				0,
+				0,
+				0,
+				0
+			]
+		},
+		{
+			"name": "Shadowdale",
+			"cluster": 5,
+			"nation": 0,
+			"r": 42,
+			"c": 20,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 2,
+			"ntypes": 4,
+			"types": [
+				0,
+				1,
+				2,
+				14
+			],
+			"times": [
+				1,
+				2,
+				2,
+				6
+			],
+			"instance": [
+				0,
+				0,
+				0,
+				0
+			]
+		},
+		{
+			"name": "Silverdale",
+			"cluster": 5,
+			"nation": 0,
+			"r": 45,
+			"c": 22,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 2,
+			"ntypes": 4,
+			"types": [
+				0,
+				1,
+				2,
+				20
+			],
+			"times": [
+				1,
+				2,
+				2,
+				6
+			],
+			"instance": [
+				0,
+				0,
+				0,
+				0
+			]
+		},
+		{
+			"name": "Battledale",
+			"cluster": 5,
+			"nation": 0,
+			"r": 48,
+			"c": 24,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 2,
+			"ntypes": 4,
+			"types": [
+				0,
+				1,
+				2,
+				14
+			],
+			"times": [
+				1,
+				2,
+				2,
+				6
+			],
+			"instance": [
+				0,
+				0,
+				0,
+				0
+			]
+		},
+		{
+			"name": "Dread",
+			"cluster": 6,
+			"nation": 0,
+			"r": 38,
+			"c": 0,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 3,
+			"ntypes": 2,
+			"types": [
+				6,
+				7,
+				-1,
+				-1
+			],
+			"times": [
+				1,
+				4,
+				-1,
+				-1
+			],
+			"instance": [
+				0,
+				0,
+				-1,
+				-1
+			]
+		},
+		{
+			"name": "Doom",
+			"cluster": 6,
+			"nation": 0,
+			"r": 39,
+			"c": 4,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 3,
+			"ntypes": 3,
+			"types": [
+				6,
+				7,
+				15,
+				-1
+			],
+			"times": [
+				1,
+				4,
+				6,
+				-1
+			],
+			"instance": [
+				0,
+				0,
+				0,
+				-1
+			]
+		},
+		{
+			"name": "Despair",
+			"cluster": 6,
+			"nation": 0,
+			"r": 42,
+			"c": 3,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 3,
+			"ntypes": 2,
+			"types": [
+				6,
+				13,
+				-1,
+				-1
+			],
+			"times": [
+				1,
+				3,
+				-1,
+				-1
+			],
+			"instance": [
+				0,
+				0,
+				-1,
+				-1
+			]
+		},
+		{
+			"name": "Death",
+			"cluster": 6,
+			"nation": 0,
+			"r": 43,
+			"c": 9,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 3,
+			"ntypes": 2,
+			"types": [
+				6,
+				7,
+				-1,
+				-1
+			],
+			"times": [
+				1,
+				5,
+				-1,
+				-1
+			],
+			"instance": [
+				0,
+				0,
+				-1,
+				-1
+			]
+		},
+		{
+			"name": "Agony",
+			"cluster": 6,
+			"nation": 0,
+			"r": 45,
+			"c": 4,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 3,
+			"ntypes": 3,
+			"types": [
+				6,
+				13,
+				15,
+				-1
+			],
+			"times": [
+				1,
+				3,
+				6,
+				-1
+			],
+			"instance": [
+				0,
+				0,
+				0,
+				-1
+			]
+		},
+		{
+			"name": "Gloom",
+			"cluster": 6,
+			"nation": 0,
+			"r": 49,
+			"c": 3,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 3,
+			"ntypes": 2,
+			"types": [
+				6,
+				7,
+				-1,
+				-1
+			],
+			"times": [
+				1,
+				5,
+				-1,
+				-1
+			],
+			"instance": [
+				0,
+				0,
+				-1,
+				-1
+			]
+		},
+		{
+			"name": "Iron",
+			"cluster": 7,
+			"nation": 0,
+			"r": 55,
+			"c": 8,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 3,
+			"ntypes": 4,
+			"types": [
+				0,
+				1,
+				8,
+				14
+			],
+			"times": [
+				1,
+				2,
+				3,
+				6
+			],
+			"instance": [
+				0,
+				0,
+				0,
+				0
+			]
+		},
+		{
+			"name": "Gold",
+			"cluster": 7,
+			"nation": 0,
+			"r": 54,
+			"c": 14,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 3,
+			"ntypes": 4,
+			"types": [
+				0,
+				1,
+				8,
+				20
+			],
+			"times": [
+				1,
+				2,
+				3,
+				5
+			],
+			"instance": [
+				0,
+				0,
+				0,
+				0
+			]
+		},
+		{
+			"name": "Silver",
+			"cluster": 7,
+			"nation": 0,
+			"r": 58,
+			"c": 13,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 3,
+			"ntypes": 4,
+			"types": [
+				0,
+				1,
+				8,
+				14
+			],
+			"times": [
+				1,
+				2,
+				3,
+				6
+			],
+			"instance": [
+				0,
+				0,
+				0,
+				0
+			]
+		},
+		{
+			"name": "Tin",
+			"cluster": 7,
+			"nation": 0,
+			"r": 57,
+			"c": 10,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 3,
+			"ntypes": 3,
+			"types": [
+				0,
+				1,
+				8,
+				-1
+			],
+			"times": [
+				1,
+				2,
+				3,
+				-1
+			],
+			"instance": [
+				0,
+				0,
+				0,
+				-1
+			]
+		},
+		{
+			"name": "Lead",
+			"cluster": 7,
+			"nation": 0,
+			"r": 51,
+			"c": 13,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 3,
+			"ntypes": 3,
+			"types": [
+				0,
+				1,
+				8,
+				-1
+			],
+			"times": [
+				1,
+				2,
+				3,
+				-1
+			],
+			"instance": [
+				0,
+				0,
+				0,
+				-1
+			]
+		},
+		{
+			"name": "Nyarlathotep",
+			"cluster": 8,
+			"nation": 0,
+			"r": 34,
+			"c": 55,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 2,
+			"ntypes": 2,
+			"types": [
+				9,
+				12,
+				-1,
+				-1
+			],
+			"times": [
+				1,
+				3,
+				-1,
+				-1
+			],
+			"instance": [
+				0,
+				0,
+				-1,
+				-1
+			]
+		},
+		{
+			"name": "Yogsothoth",
+			"cluster": 8,
+			"nation": 0,
+			"r": 30,
+			"c": 52,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 2,
+			"ntypes": 2,
+			"types": [
+				9,
+				12,
+				-1,
+				-1
+			],
+			"times": [
+				1,
+				3,
+				-1,
+				-1
+			],
+			"instance": [
+				0,
+				0,
+				-1,
+				-1
+			]
+		},
+		{
+			"name": "Cthulhu",
+			"cluster": 8,
+			"nation": 0,
+			"r": 31,
+			"c": 57,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 2,
+			"ntypes": 2,
+			"types": [
+				9,
+				13,
+				-1,
+				-1
+			],
+			"times": [
+				1,
+				3,
+				-1,
+				-1
+			],
+			"instance": [
+				0,
+				0,
+				-1,
+				-1
+			]
+		},
+		{
+			"name": "Hastor",
+			"cluster": 8,
+			"nation": 0,
+			"r": 28,
+			"c": 59,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 2,
+			"ntypes": 2,
+			"types": [
+				9,
+				13,
+				-1,
+				-1
+			],
+			"times": [
+				1,
+				3,
+				-1,
+				-1
+			],
+			"instance": [
+				0,
+				0,
+				-1,
+				-1
+			]
+		},
+		{
+			"name": "Olan",
+			"cluster": 9,
+			"nation": 0,
+			"r": 42,
+			"c": 59,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 3,
+			"ntypes": 2,
+			"types": [
+				4,
+				10,
+				-1,
+				-1
+			],
+			"times": [
+				1,
+				3,
+				-1,
+				-1
+			],
+			"instance": [
+				0,
+				0,
+				-1,
+				-1
+			]
+		},
+		{
+			"name": "Kaxandar",
+			"cluster": 9,
+			"nation": 0,
+			"r": 40,
+			"c": 58,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 3,
+			"ntypes": 2,
+			"types": [
+				4,
+				10,
+				-1,
+				-1
+			],
+			"times": [
+				1,
+				3,
+				-1,
+				-1
+			],
+			"instance": [
+				0,
+				0,
+				-1,
+				-1
+			]
+		},
+		{
+			"name": "Torgar",
+			"cluster": 9,
+			"nation": 0,
+			"r": 46,
+			"c": 60,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 3,
+			"ntypes": 2,
+			"types": [
+				4,
+				10,
+				-1,
+				-1
+			],
+			"times": [
+				1,
+				3,
+				-1,
+				-1
+			],
+			"instance": [
+				0,
+				0,
+				-1,
+				-1
+			]
+		},
+		{
+			"name": "Arras Charka",
+			"cluster": 10,
+			"nation": 0,
+			"r": 18,
+			"c": 43,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 2,
+			"ntypes": 3,
+			"types": [
+				0,
+				1,
+				21,
+				-1
+			],
+			"times": [
+				1,
+				2,
+				6,
+				-1
+			],
+			"instance": [
+				0,
+				0,
+				0,
+				-1
+			]
+		},
+		{
+			"name": "Derzon",
+			"cluster": 10,
+			"nation": 0,
+			"r": 17,
+			"c": 51,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 2,
+			"ntypes": 3,
+			"types": [
+				0,
+				1,
+				2,
+				-1
+			],
+			"times": [
+				1,
+				2,
+				2,
+				-1
+			],
+			"instance": [
+				0,
+				0,
+				0,
+				-1
+			]
+		},
+		{
+			"name": "Ekosiak",
+			"cluster": 10,
+			"nation": 0,
+			"r": 20,
+			"c": 47,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 2,
+			"ntypes": 4,
+			"types": [
+				0,
+				1,
+				2,
+				3
+			],
+			"times": [
+				1,
+				2,
+				2,
+				4
+			],
+			"instance": [
+				0,
+				0,
+				0,
+				0
+			]
+		},
+		{
+			"name": "Ish-Tako",
+			"cluster": 10,
+			"nation": 0,
+			"r": 16,
+			"c": 46,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 2,
+			"ntypes": 4,
+			"types": [
+				0,
+				1,
+				8,
+				14
+			],
+			"times": [
+				1,
+				2,
+				3,
+				6
+			],
+			"instance": [
+				0,
+				0,
+				0,
+				0
+			]
+		},
+		{
+			"name": "Chishata",
+			"cluster": 10,
+			"nation": 0,
+			"r": 23,
+			"c": 50,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 2,
+			"ntypes": 4,
+			"types": [
+				0,
+				1,
+				8,
+				14
+			],
+			"times": [
+				1,
+				2,
+				3,
+				6
+			],
+			"instance": [
+				0,
+				0,
+				0,
+				0
+			]
+		},
+		{
+			"name": "Qualinesti",
+			"cluster": 11,
+			"nation": 0,
+			"r": 53,
+			"c": 54,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 2,
+			"ntypes": 4,
+			"types": [
+				17,
+				5,
+				11,
+				20
+			],
+			"times": [
+				1,
+				2,
+				2,
+				4
+			],
+			"instance": [
+				0,
+				0,
+				0,
+				0
+			]
+		},
+		{
+			"name": "Sylvanesti",
+			"cluster": 11,
+			"nation": 0,
+			"r": 56,
+			"c": 55,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 2,
+			"ntypes": 4,
+			"types": [
+				17,
+				5,
+				11,
+				16
+			],
+			"times": [
+				1,
+				2,
+				2,
+				7
+			],
+			"instance": [
+				0,
+				0,
+				0,
+				0
+			]
+		},
+		{
+			"name": "Rathwynn",
+			"cluster": 11,
+			"nation": 0,
+			"r": 62,
+			"c": 58,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 2,
+			"ntypes": 3,
+			"types": [
+				17,
+				5,
+				11,
+				-1
+			],
+			"times": [
+				1,
+				2,
+				2,
+				-1
+			],
+			"instance": [
+				0,
+				0,
+				0,
+				-1
+			]
+		},
+		{
+			"name": "Caledon",
+			"cluster": 11,
+			"nation": 0,
+			"r": 60,
+			"c": 54,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 2,
+			"ntypes": 4,
+			"types": [
+				17,
+				5,
+				11,
+				16
+			],
+			"times": [
+				1,
+				2,
+				2,
+				7
+			],
+			"instance": [
+				0,
+				0,
+				0,
+				0
+			]
+		},
+		{
+			"name": "Alfheim",
+			"cluster": 11,
+			"nation": 0,
+			"r": 58,
+			"c": 51,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 2,
+			"ntypes": 4,
+			"types": [
+				17,
+				5,
+				11,
+				16
+			],
+			"times": [
+				1,
+				2,
+				2,
+				7
+			],
+			"instance": [
+				0,
+				0,
+				0,
+				0
+			]
+		},
+		{
+			"name": "Atlantis",
+			"cluster": 12,
+			"nation": 0,
+			"r": 49,
+			"c": 41,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 2,
+			"ntypes": 3,
+			"types": [
+				18,
+				19,
+				22,
+				-1
+			],
+			"times": [
+				1,
+				2,
+				8,
+				-1
+			],
+			"instance": [
+				0,
+				0,
+				0,
+				-1
+			]
+		},
+		{
+			"name": "Mu",
+			"cluster": 12,
+			"nation": 0,
+			"r": 49,
+			"c": 37,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 2,
+			"ntypes": 3,
+			"types": [
+				18,
+				19,
+				22,
+				-1
+			],
+			"times": [
+				1,
+				2,
+				8,
+				-1
+			],
+			"instance": [
+				0,
+				0,
+				0,
+				-1
+			]
+		},
+		{
+			"name": "Poseidon",
+			"cluster": 12,
+			"nation": 0,
+			"r": 46,
+			"c": 42,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 2,
+			"ntypes": 3,
+			"types": [
+				18,
+				19,
+				22,
+				-1
+			],
+			"times": [
+				1,
+				2,
+				8,
+				-1
+			],
+			"instance": [
+				0,
+				0,
+				0,
+				-1
+			]
+		},
+		{
+			"name": "Neptune",
+			"cluster": 12,
+			"nation": 0,
+			"r": 44,
+			"c": 38,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 2,
+			"ntypes": 3,
+			"types": [
+				18,
+				19,
+				22,
+				-1
+			],
+			"times": [
+				1,
+				2,
+				8,
+				-1
+			],
+			"instance": [
+				0,
+				0,
+				0,
+				-1
+			]
+		}
+	],
+	"ttypes": [
+		{
+			"name": "Lt. Infantry",
+			"combat": 2,
+			"move_rate": 6,
+			"move_tbl": 0,
+			"special_mv": 0
+		},
+		{
+			"name": "Hv. Infantry",
+			"combat": 3,
+			"move_rate": 4,
+			"move_tbl": 0,
+			"special_mv": 0
+		},
+		{
+			"name": "Lt. Cavalry",
+			"combat": 2,
+			"move_rate": 12,
+			"move_tbl": 1,
+			"special_mv": 0
+		},
+		{
+			"name": "Hv. Cavalry",
+			"combat": 3,
+			"move_rate": 8,
+			"move_tbl": 1,
+			"special_mv": 0
+		},
+		{
+			"name": "Dwarf Legion",
+			"combat": 3,
+			"move_rate": 4,
+			"move_tbl": 2,
+			"special_mv": 0
+		},
+		{
+			"name": "Elven Archers",
+			"combat": 3,
+			"move_rate": 6,
+			"move_tbl": 3,
+			"special_mv": 0
+		},
+		{
+			"name": "Zombie Legion",
+			"combat": 3,
+			"move_rate": 3,
+			"move_tbl": 0,
+			"special_mv": 0
+		},
+		{
+			"name": "Wraith Horde",
+			"combat": 4,
+			"move_rate": 6,
+			"move_tbl": 4,
+			"special_mv": 0
+		},
+		{
+			"name": "Elite Troopers",
+			"combat": 4,
+			"move_rate": 4,
+			"move_tbl": 0,
+			"special_mv": 0
+		},
+		{
+			"name": "Gug",
+			"combat": 3,
+			"move_rate": 4,
+			"move_tbl": 0,
+			"special_mv": 0
+		},
+		{
+			"name": "Dwarf Miners",
+			"combat": 4,
+			"move_rate": 4,
+			"move_tbl": 5,
+			"special_mv": 0
+		},
+		{
+			"name": "Scout",
+			"combat": 1,
+			"move_rate": 8,
+			"move_tbl": 6,
+			"special_mv": 0
+		},
+		{
+			"name": "Byakhee",
+			"combat": 2,
+			"move_rate": 7,
+			"move_tbl": 4,
+			"special_mv": 2
+		},
+		{
+			"name": "Ghouls",
+			"combat": 3,
+			"move_rate": 5,
+			"move_tbl": 0,
+			"special_mv": 0
+		},
+		{
+			"name": "Navy",
+			"combat": 2,
+			"move_rate": 10,
+			"move_tbl": 7,
+			"special_mv": 3
+		},
+		{
+			"name": "Undead Navy",
+			"combat": 3,
+			"move_rate": 8,
+			"move_tbl": 7,
+			"special_mv": 3
+		},
+		{
+			"name": "Elf Clipper",
+			"combat": 2,
+			"move_rate": 12,
+			"move_tbl": 7,
+			"special_mv": 3
+		},
+		{
+			"name": "Elf Infantry",
+			"combat": 2,
+			"move_rate": 8,
+			"move_tbl": 3,
+			"special_mv": 0
+		},
+		{
+			"name": "Mermen",
+			"combat": 2,
+			"move_rate": 6,
+			"move_tbl": 7,
+			"special_mv": 0
+		},
+		{
+			"name": "Tritons",
+			"combat": 3,
+			"move_rate": 4,
+			"move_tbl": 7,
+			"special_mv": 0
+		},
+		{
+			"name": "Pegasus",
+			"combat": 2,
+			"move_rate": 10,
+			"move_tbl": 4,
+			"special_mv": 1
+		},
+		{
+			"name": "Hippogryff",
+			"combat": 3,
+			"move_rate": 8,
+			"move_tbl": 4,
+			"special_mv": 1
+		},
+		{
+			"name": "Leviathan",
+			"combat": 5,
+			"move_rate": 4,
+			"move_tbl": 8,
+			"special_mv": 1
+		}
+	],
+	"armies": [],
+	"move_table": [
+		{
+			"cost": [
+				0,
+				1,
+				2,
+				2,
+				4
+			]
+		},
+		{
+			"cost": [
+				0,
+				1,
+				2,
+				3,
+				0
+			]
+		},
+		{
+			"cost": [
+				0,
+				1,
+				2,
+				1,
+				2
+			]
+		},
+		{
+			"cost": [
+				0,
+				1,
+				1,
+				2,
+				4
+			]
+		},
+		{
+			"cost": [
+				1,
+				1,
+				1,
+				1,
+				2
+			]
+		},
+		{
+			"cost": [
+				0,
+				1,
+				2,
+				2,
+				3
+			]
+		},
+		{
+			"cost": [
+				0,
+				1,
+				1,
+				1,
+				2
+			]
+		},
+		{
+			"cost": [
+				1,
+				0,
+				0,
+				0,
+				0
+			]
+		},
+		{
+			"cost": [
+				1,
+				1,
+				2,
+				3,
+				4
+			]
+		}
+	],
+	"world": "Solomoriah's World",
+	"gen": 0
+}
\ No newline at end of file
diff --git a/xtrn/war/worlds/solomoriah/map b/xtrn/war/worlds/solomoriah/map
new file mode 100644
index 0000000000000000000000000000000000000000..c90877c521388a22c357fe91db72e85a5862cd23
--- /dev/null
+++ b/xtrn/war/worlds/solomoriah/map
@@ -0,0 +1,66 @@
+M 64 64
+
+....~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~.%%%
+....~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
+....%%~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~.
+....%.%.%~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^.
+..^^^~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^
+..^^^.~~~..%^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%%^^
+%%%%%%##...%%~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%%^^
+%%%%%%#.....%%~~~~~~~~~~~~..~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~.%%^^
+###%~~~~....%%%%~~~~~~~~~~~~..~~~~~~~~~~~~~~~...%~~~~~~~~~~~~~~~
+####~~~~^^..%%%%~~~^^##~~~~~~~~~~~~~~~~~~~~#....#~~~~~~~~~~~~~~~
+####~~~~~^##%%%~~~##.###~~~~~~~~~~~~~~~~~~~~....~~~~~~~~~~~~~~~~
+####~~~~~###%%%~~########~~~~~~~~~##~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+%#..~~~~~~%##~~~~~#########%%%...%%##~~~~~~~~~~~~~~~~~~~~~~~~~~~
+~~~~~~~~~~...~~~~~~#######..%....%%%.~~~~~~~~~~~~~~~~~~~~~~~~~~~
+~~~~~~~~~.....~~~~%%####~~........%%..~~~~%%~~~~~~~~~~~~~~~~~~~~
+~~~~~~~~......~~~%%%%%%%~~....##...%..##~%%%%##~~..~~~~~~~~~~~~~
+~~~~~~~...####~~~%%%%%%%#...~~~~~~~..###.%%%%###~...~~~~~~~~~~~~
+~~~~~~~~.#####~~~~~~%%%^^^~~~~~~~~~..###..%%###....#~~~~~~~~~~~~
+~~~~~~~~~####...%~~~%%^^^^~~~~~~~~...^^~....###....##~~~~~~~~~~~
+~~~~~~~~~~^^....%%~~~~..^^~~~~~~~~~~~~~~%%..####..^^#~~~~~~~~~~~
+~~~~...~~~^^....%%%%#~##...~~~~~~~~~~~~~%%%~###%.%##~~~~~~~~~~~~
+~~~%...~~......~%%%%##~~~~~~~~~~~~~~~~~~~%#####%~%#~~..~^~~~~~~~
+~~%%%~~~~.....~~%%%%%~~~~~~~~~~~~~~~~~~~~~##^##~~%~~....^~~~~~~~
+~%%%%~~~~~....~~~%%%%~~~~~~~~~~~~~~~~~~~~~#^^^~~~%%~....~~~~~~~~
+%%%%###~~~~~~~~~~~..~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~%%..%%~~~~.~~~
+%%%%##~~~~~~~~~~~..~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~.%%%%%~~.%%%
+%~~##~~~~~~~~~~~~~~.~~~~~###~~~~~~~~~~~~~~~~~~~~~~~~%%%%%%~^%%%%
+~~~..~~.~~~~~~~~~%%%##^^####~~~~~~~~~~~~~~~~~~~~~~~~%%%%~~~^%%%%
+~~.......##~%%%%%%%##^^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%###~~#%%~~
+~^^......###%%%%%~~##^~~~~~~~~..~~~~~~~~~~~~~~~~~.~~%%%%####%%~~
+^^^^....%###%%%%~~~##^~~~~~~~...~~~~~~~~~~~~~~~~~.#~%%%%#####%~~
+^^..%%%%.%#~~%%%~~~#^^~~~%%%~...%%%~~~~~~~~~~~~~~.~#%%%%%####~~~
+~~~~%%%%%%%~~~~~~~~...~~..%%..%%%%%%%~~~~~~~~~~~~~~~...#.###~~~~
+~~~~%%%~%%%%~~~~~~............%%%%%%%~~~~~~~~~~~~~~~..##..##~~~~
+~###~%~~~%%%~~~~~~..........~~~~...%~~~~~~~~~~~~~~~~~###..##~~~~
+#####~~~~%%%...~~~~..###.~~~~~~~~.~~~~~~~~~~~~~~~~~~~~##~.#~~~~~
+^###~~~~~~~%%...~~~~~###%~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%~~^^
+^.~^~~~~~~~~%...~~~~~~~~%%%%....%~~~~~~~~~~~~~~~~~~~~~~~~~^^%^^^
+..~~~~~~~~~~~~...~~~~~~~%.....#%%%~~~~~~~~~~~~~~~~~~~~~~~^^^%%^^
+....^~~~~~~~~~~.~^~~~~~~~~~~~###%%%~~~~~~~~~~~~~~~~~~~~~~^^^%%%.
+.~.~~~~~~~~~~~~~~~##~~~~~~~~~~#~~~~~~~~~~~~~~~~~~~##~~~~~^^^%%~~
+~~~.~~~~~~~%%~~~~~~.~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~##~~~~~.^^^~~~
+~~%..~~~~~~~%~~~~~~..~~~^^~~~~~~~~~~~~~~~~~~~~~~~###.~~~...^^~~~
+~%%%.~~~.##~%%~~~~^..~~^^^~~~~~~~~~~~~~~~~~~~~~~~###.~~~#..^^~~~
+~#%%.....~##~~~~~^^^..^^###~~~~~~~~~~~~~~~~~~~~~~~~~%%###~^^^^~~
+###%....~~~~~~%%~###..^^####~~~~~~~~~~~~~~~~~~~~~~~~..##~~~#^^%~
+###%~~~~~~~~~%%%%####~~~####~~~~~~~~~~~~~~~~~~~~~~~~...#~~~#^^^%
+###%~~~~~~~~~~%%%####~~~.###~~~~~~~~~~~~~~~~~~~~~~~#.....~~#..%%
+####..~~%%%%~~~.##^^~~~~..~~~~~~~~~~~~~~~~~~~~~~~~~#~~~~...~~~~#
+###...##%%%%~~..##^^~~~~..~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~...~~~~~
+~.....##%%%%##...##^~~~~...~~~~~~~~~~~~~~~~~~~~~~~~~~~~~....~~~~
+~.....##...####...~~~~~.....~~~~~~~~~~~~~~~~~~~~~~~~~~~#....~~~~
+~~...%%%%...####..~~~^^^....~~~~~~~~~~~~~~~~~~~~~~~~~%%%#^^.~~~~
+~~#..%%%%%%%####.~~~~^^^~~~~~~~~~~~~~~~~~~~~~~~~~~~~%%%%%^^^~~~~
+~###~~%%%%%%####~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~.%%%%%^^^~~~~
+####~~~~###%####~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~..%%%%.^^^~~~~
+~~~~~~~~####^###%%%~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~.~~%%..^^~~~~
+~~~~~~~~~#######%%%%%~~~~~~~~~~~~~~~~~~~~~~~~~~~~~..~~~~~~%%~~~~
+~~~~~~~~~~######~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~...~~~~~~~%..~~
+..~~~~~~~~####~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~..~~~~~~~~....
+~~~~~~%%^%%%~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~.....%%%%
+~~~~~~%%^^%~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~......%%%%
+%~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~..%%%%%%%
+%%~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%%%%%%%%%%
diff --git a/xtrn/war/worlds/solomoriah/map.png b/xtrn/war/worlds/solomoriah/map.png
new file mode 100644
index 0000000000000000000000000000000000000000..97d8148bd56a8e62ae23d7d697b284dfd9d26d40
Binary files /dev/null and b/xtrn/war/worlds/solomoriah/map.png differ
diff --git a/xtrn/war/worlds/spacewar/game.orig.json b/xtrn/war/worlds/spacewar/game.orig.json
new file mode 100644
index 0000000000000000000000000000000000000000..71dbc29eba88287b29c282f38a29b42bc1d843a1
--- /dev/null
+++ b/xtrn/war/worlds/spacewar/game.orig.json
@@ -0,0 +1,1612 @@
+{
+	"ncnt": 1,
+	"nations": [
+		{
+			"name": "Overlord",
+			"uid": 0,
+			"city": 0,
+			"mark": "*",
+			"idle_turns": 0
+		},
+		{
+			"name": "",
+			"uid": 0,
+			"city": 0,
+			"mark": "*",
+			"idle_turns": 0
+		},
+		{
+			"name": "",
+			"uid": 0,
+			"city": 0,
+			"mark": "*",
+			"idle_turns": 0
+		},
+		{
+			"name": "",
+			"uid": 0,
+			"city": 0,
+			"mark": "*",
+			"idle_turns": 0
+		},
+		{
+			"name": "",
+			"uid": 0,
+			"city": 0,
+			"mark": "*",
+			"idle_turns": 0
+		},
+		{
+			"name": "",
+			"uid": 0,
+			"city": 0,
+			"mark": "*",
+			"idle_turns": 0
+		},
+		{
+			"name": "",
+			"uid": 0,
+			"city": 0,
+			"mark": "*",
+			"idle_turns": 0
+		},
+		{
+			"name": "",
+			"uid": 0,
+			"city": 0,
+			"mark": "*",
+			"idle_turns": 0
+		},
+		{
+			"name": "",
+			"uid": 0,
+			"city": 0,
+			"mark": "*",
+			"idle_turns": 0
+		},
+		{
+			"name": "",
+			"uid": 0,
+			"city": 0,
+			"mark": "*",
+			"idle_turns": 0
+		},
+		{
+			"name": "",
+			"uid": 0,
+			"city": 0,
+			"mark": "*",
+			"idle_turns": 0
+		},
+		{
+			"name": "",
+			"uid": 0,
+			"city": 0,
+			"mark": "*",
+			"idle_turns": 0
+		},
+		{
+			"name": "",
+			"uid": 0,
+			"city": 0,
+			"mark": "*",
+			"idle_turns": 0
+		},
+		{
+			"name": "",
+			"uid": 0,
+			"city": 0,
+			"mark": "*",
+			"idle_turns": 0
+		},
+		{
+			"name": "",
+			"uid": 0,
+			"city": 0,
+			"mark": "*",
+			"idle_turns": 0
+		},
+		{
+			"name": "",
+			"uid": 0,
+			"city": 0,
+			"mark": "*",
+			"idle_turns": 0
+		},
+		{
+			"name": "",
+			"uid": 0,
+			"city": 0,
+			"mark": "*",
+			"idle_turns": 0
+		},
+		{
+			"name": "",
+			"uid": 0,
+			"city": 0,
+			"mark": "*",
+			"idle_turns": 0
+		},
+		{
+			"name": "",
+			"uid": 0,
+			"city": 0,
+			"mark": "*",
+			"idle_turns": 0
+		},
+		{
+			"name": "",
+			"uid": 0,
+			"city": 0,
+			"mark": "*",
+			"idle_turns": 0
+		},
+		{
+			"name": "",
+			"uid": 0,
+			"city": 0,
+			"mark": "*",
+			"idle_turns": 0
+		},
+		{
+			"name": "",
+			"uid": 0,
+			"city": 0,
+			"mark": "*",
+			"idle_turns": 0
+		},
+		{
+			"name": "",
+			"uid": 0,
+			"city": 0,
+			"mark": "*",
+			"idle_turns": 0
+		},
+		{
+			"name": "",
+			"uid": 0,
+			"city": 0,
+			"mark": "*",
+			"idle_turns": 0
+		},
+		{
+			"name": "",
+			"uid": 0,
+			"city": 0,
+			"mark": "*",
+			"idle_turns": 0
+		},
+		{
+			"name": "",
+			"uid": 0,
+			"city": 0,
+			"mark": "*",
+			"idle_turns": 0
+		},
+		{
+			"name": "",
+			"uid": 0,
+			"city": 0,
+			"mark": "*",
+			"idle_turns": 0
+		},
+		{
+			"name": "Rogue",
+			"uid": -1,
+			"city": 0,
+			"mark": "?",
+			"idle_turns": 0
+		}
+	],
+	"cities": [
+		{
+			"name": "Mercury",
+			"cluster": 1,
+			"nation": 0,
+			"r": 4,
+			"c": 0,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 2,
+			"ntypes": 4,
+			"types": [
+				0,
+				1,
+				2,
+				21
+			],
+			"times": [
+				1,
+				2,
+				2,
+				6
+			],
+			"instance": [
+				12,
+				0,
+				0,
+				0
+			]
+		},
+		{
+			"name": "Venus",
+			"cluster": 1,
+			"nation": 0,
+			"r": 4,
+			"c": 8,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 2,
+			"ntypes": 4,
+			"types": [
+				0,
+				1,
+				2,
+				21
+			],
+			"times": [
+				1,
+				2,
+				2,
+				6
+			],
+			"instance": [
+				12,
+				0,
+				0,
+				0
+			]
+		},
+		{
+			"name": "Earth",
+			"cluster": 1,
+			"nation": 0,
+			"r": 5,
+			"c": 4,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 2,
+			"ntypes": 4,
+			"types": [
+				0,
+				1,
+				2,
+				21
+			],
+			"times": [
+				1,
+				2,
+				2,
+				6
+			],
+			"instance": [
+				12,
+				0,
+				0,
+				0
+			]
+		},
+		{
+			"name": "Mars",
+			"cluster": 1,
+			"nation": 0,
+			"r": 9,
+			"c": 4,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 2,
+			"ntypes": 4,
+			"types": [
+				0,
+				1,
+				2,
+				21
+			],
+			"times": [
+				1,
+				2,
+				2,
+				6
+			],
+			"instance": [
+				12,
+				0,
+				0,
+				0
+			]
+		},
+		{
+			"name": "Jupiter",
+			"cluster": 1,
+			"nation": 0,
+			"r": 0,
+			"c": 5,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 2,
+			"ntypes": 4,
+			"types": [
+				0,
+				1,
+				2,
+				21
+			],
+			"times": [
+				1,
+				2,
+				2,
+				6
+			],
+			"instance": [
+				12,
+				0,
+				0,
+				0
+			]
+		},
+		{
+			"name": "Jinx",
+			"cluster": 2,
+			"nation": 0,
+			"r": 4,
+			"c": 56,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 2,
+			"ntypes": 4,
+			"types": [
+				0,
+				1,
+				2,
+				21
+			],
+			"times": [
+				1,
+				2,
+				2,
+				6
+			],
+			"instance": [
+				12,
+				0,
+				0,
+				0
+			]
+		},
+		{
+			"name": "Wemadeit",
+			"cluster": 2,
+			"nation": 0,
+			"r": 9,
+			"c": 50,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 2,
+			"ntypes": 4,
+			"types": [
+				0,
+				1,
+				2,
+				21
+			],
+			"times": [
+				1,
+				2,
+				2,
+				6
+			],
+			"instance": [
+				12,
+				0,
+				0,
+				0
+			]
+		},
+		{
+			"name": "Wunderland",
+			"cluster": 2,
+			"nation": 0,
+			"r": 8,
+			"c": 55,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 2,
+			"ntypes": 4,
+			"types": [
+				0,
+				1,
+				2,
+				21
+			],
+			"times": [
+				1,
+				2,
+				2,
+				6
+			],
+			"instance": [
+				12,
+				0,
+				0,
+				0
+			]
+		},
+		{
+			"name": "Shaster",
+			"cluster": 2,
+			"nation": 0,
+			"r": 5,
+			"c": 47,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 2,
+			"ntypes": 4,
+			"types": [
+				0,
+				1,
+				2,
+				21
+			],
+			"times": [
+				1,
+				2,
+				2,
+				6
+			],
+			"instance": [
+				12,
+				0,
+				0,
+				0
+			]
+		},
+		{
+			"name": "Crashland",
+			"cluster": 2,
+			"nation": 0,
+			"r": 2,
+			"c": 52,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 2,
+			"ntypes": 4,
+			"types": [
+				0,
+				1,
+				2,
+				21
+			],
+			"times": [
+				1,
+				2,
+				2,
+				6
+			],
+			"instance": [
+				12,
+				0,
+				0,
+				0
+			]
+		},
+		{
+			"name": "Vulcan",
+			"cluster": 3,
+			"nation": 0,
+			"r": 13,
+			"c": 15,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 2,
+			"ntypes": 4,
+			"types": [
+				0,
+				1,
+				2,
+				21
+			],
+			"times": [
+				1,
+				2,
+				2,
+				6
+			],
+			"instance": [
+				12,
+				0,
+				0,
+				0
+			]
+		},
+		{
+			"name": "Qo'noS",
+			"cluster": 3,
+			"nation": 0,
+			"r": 9,
+			"c": 18,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 2,
+			"ntypes": 4,
+			"types": [
+				0,
+				1,
+				2,
+				21
+			],
+			"times": [
+				1,
+				2,
+				2,
+				6
+			],
+			"instance": [
+				12,
+				0,
+				0,
+				0
+			]
+		},
+		{
+			"name": "Andoria",
+			"cluster": 3,
+			"nation": 0,
+			"r": 14,
+			"c": 19,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 2,
+			"ntypes": 4,
+			"types": [
+				0,
+				1,
+				2,
+				21
+			],
+			"times": [
+				1,
+				2,
+				2,
+				6
+			],
+			"instance": [
+				12,
+				0,
+				0,
+				0
+			]
+		},
+		{
+			"name": "Trill",
+			"cluster": 3,
+			"nation": 0,
+			"r": 13,
+			"c": 24,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 2,
+			"ntypes": 4,
+			"types": [
+				0,
+				1,
+				2,
+				21
+			],
+			"times": [
+				1,
+				2,
+				2,
+				6
+			],
+			"instance": [
+				12,
+				0,
+				0,
+				0
+			]
+		},
+		{
+			"name": "Bajor",
+			"cluster": 3,
+			"nation": 0,
+			"r": 7,
+			"c": 22,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 2,
+			"ntypes": 4,
+			"types": [
+				0,
+				1,
+				2,
+				21
+			],
+			"times": [
+				1,
+				2,
+				2,
+				6
+			],
+			"instance": [
+				12,
+				0,
+				0,
+				0
+			]
+		},
+		{
+			"name": "Romulus",
+			"cluster": 4,
+			"nation": 0,
+			"r": 61,
+			"c": 17,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 2,
+			"ntypes": 4,
+			"types": [
+				0,
+				1,
+				2,
+				21
+			],
+			"times": [
+				1,
+				2,
+				2,
+				6
+			],
+			"instance": [
+				12,
+				0,
+				0,
+				0
+			]
+		},
+		{
+			"name": "Remus",
+			"cluster": 4,
+			"nation": 0,
+			"r": 59,
+			"c": 19,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 2,
+			"ntypes": 4,
+			"types": [
+				0,
+				1,
+				2,
+				21
+			],
+			"times": [
+				1,
+				2,
+				2,
+				6
+			],
+			"instance": [
+				12,
+				0,
+				0,
+				0
+			]
+		},
+		{
+			"name": "Cardassia",
+			"cluster": 4,
+			"nation": 0,
+			"r": 63,
+			"c": 21,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 2,
+			"ntypes": 4,
+			"types": [
+				0,
+				1,
+				2,
+				21
+			],
+			"times": [
+				1,
+				2,
+				2,
+				6
+			],
+			"instance": [
+				12,
+				0,
+				0,
+				0
+			]
+		},
+		{
+			"name": "Tholia",
+			"cluster": 4,
+			"nation": 0,
+			"r": 59,
+			"c": 25,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 2,
+			"ntypes": 4,
+			"types": [
+				0,
+				1,
+				2,
+				21
+			],
+			"times": [
+				1,
+				2,
+				2,
+				6
+			],
+			"instance": [
+				12,
+				0,
+				0,
+				0
+			]
+		},
+		{
+			"name": "Ceti Alpha V",
+			"cluster": 4,
+			"nation": 0,
+			"r": 55,
+			"c": 22,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 2,
+			"ntypes": 4,
+			"types": [
+				0,
+				1,
+				2,
+				21
+			],
+			"times": [
+				1,
+				2,
+				2,
+				6
+			],
+			"instance": [
+				12,
+				0,
+				0,
+				0
+			]
+		},
+		{
+			"name": "Unimatrix 01",
+			"cluster": 5,
+			"nation": 0,
+			"r": 44,
+			"c": 20,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 2,
+			"ntypes": 4,
+			"types": [
+				0,
+				1,
+				2,
+				21
+			],
+			"times": [
+				1,
+				2,
+				2,
+				6
+			],
+			"instance": [
+				12,
+				0,
+				0,
+				0
+			]
+		},
+		{
+			"name": "Unimatrix 02",
+			"cluster": 5,
+			"nation": 0,
+			"r": 40,
+			"c": 21,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 2,
+			"ntypes": 4,
+			"types": [
+				0,
+				1,
+				2,
+				21
+			],
+			"times": [
+				1,
+				2,
+				2,
+				6
+			],
+			"instance": [
+				12,
+				0,
+				0,
+				0
+			]
+		},
+		{
+			"name": "Unimatrix 03",
+			"cluster": 5,
+			"nation": 0,
+			"r": 45,
+			"c": 24,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 2,
+			"ntypes": 4,
+			"types": [
+				0,
+				1,
+				2,
+				21
+			],
+			"times": [
+				1,
+				2,
+				2,
+				6
+			],
+			"instance": [
+				12,
+				0,
+				0,
+				0
+			]
+		},
+		{
+			"name": "Unimatrix 04",
+			"cluster": 5,
+			"nation": 0,
+			"r": 43,
+			"c": 16,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 2,
+			"ntypes": 4,
+			"types": [
+				0,
+				1,
+				2,
+				21
+			],
+			"times": [
+				1,
+				2,
+				2,
+				6
+			],
+			"instance": [
+				12,
+				0,
+				0,
+				0
+			]
+		},
+		{
+			"name": "Unimatrix 05",
+			"cluster": 5,
+			"nation": 0,
+			"r": 48,
+			"c": 18,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 2,
+			"ntypes": 4,
+			"types": [
+				0,
+				1,
+				2,
+				21
+			],
+			"times": [
+				1,
+				2,
+				2,
+				6
+			],
+			"instance": [
+				12,
+				0,
+				0,
+				0
+			]
+		},
+		{
+			"name": "Centauri",
+			"cluster": 6,
+			"nation": 0,
+			"r": 56,
+			"c": 61,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 2,
+			"ntypes": 4,
+			"types": [
+				0,
+				1,
+				2,
+				21
+			],
+			"times": [
+				1,
+				2,
+				2,
+				6
+			],
+			"instance": [
+				12,
+				0,
+				0,
+				0
+			]
+		},
+		{
+			"name": "Narn",
+			"cluster": 6,
+			"nation": 0,
+			"r": 52,
+			"c": 58,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 2,
+			"ntypes": 4,
+			"types": [
+				0,
+				1,
+				2,
+				21
+			],
+			"times": [
+				1,
+				2,
+				2,
+				6
+			],
+			"instance": [
+				12,
+				0,
+				0,
+				0
+			]
+		},
+		{
+			"name": "Minbar",
+			"cluster": 6,
+			"nation": 0,
+			"r": 57,
+			"c": 55,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 2,
+			"ntypes": 4,
+			"types": [
+				0,
+				1,
+				2,
+				21
+			],
+			"times": [
+				1,
+				2,
+				2,
+				6
+			],
+			"instance": [
+				12,
+				0,
+				0,
+				0
+			]
+		},
+		{
+			"name": "Epsilon 3",
+			"cluster": 6,
+			"nation": 0,
+			"r": 60,
+			"c": 59,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 2,
+			"ntypes": 4,
+			"types": [
+				0,
+				1,
+				2,
+				21
+			],
+			"times": [
+				1,
+				2,
+				2,
+				6
+			],
+			"instance": [
+				12,
+				0,
+				0,
+				0
+			]
+		},
+		{
+			"name": "Vorlon",
+			"cluster": 6,
+			"nation": 0,
+			"r": 53,
+			"c": 51,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 2,
+			"ntypes": 4,
+			"types": [
+				0,
+				1,
+				2,
+				21
+			],
+			"times": [
+				1,
+				2,
+				2,
+				6
+			],
+			"instance": [
+				12,
+				0,
+				0,
+				0
+			]
+		},
+		{
+			"name": "Coruscant",
+			"cluster": 7,
+			"nation": 0,
+			"r": 20,
+			"c": 44,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 2,
+			"ntypes": 4,
+			"types": [
+				0,
+				1,
+				2,
+				21
+			],
+			"times": [
+				1,
+				2,
+				2,
+				6
+			],
+			"instance": [
+				12,
+				0,
+				0,
+				0
+			]
+		},
+		{
+			"name": "Naboo",
+			"cluster": 7,
+			"nation": 0,
+			"r": 25,
+			"c": 38,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 2,
+			"ntypes": 4,
+			"types": [
+				0,
+				1,
+				2,
+				21
+			],
+			"times": [
+				1,
+				2,
+				2,
+				6
+			],
+			"instance": [
+				12,
+				0,
+				0,
+				0
+			]
+		},
+		{
+			"name": "Kamino",
+			"cluster": 7,
+			"nation": 0,
+			"r": 21,
+			"c": 37,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 2,
+			"ntypes": 4,
+			"types": [
+				0,
+				1,
+				2,
+				21
+			],
+			"times": [
+				1,
+				2,
+				2,
+				6
+			],
+			"instance": [
+				12,
+				0,
+				0,
+				0
+			]
+		},
+		{
+			"name": "Geonosis",
+			"cluster": 7,
+			"nation": 0,
+			"r": 24,
+			"c": 42,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 2,
+			"ntypes": 4,
+			"types": [
+				0,
+				1,
+				2,
+				21
+			],
+			"times": [
+				1,
+				2,
+				2,
+				6
+			],
+			"instance": [
+				12,
+				0,
+				0,
+				0
+			]
+		},
+		{
+			"name": "Alderaan",
+			"cluster": 7,
+			"nation": 0,
+			"r": 18,
+			"c": 41,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 2,
+			"ntypes": 4,
+			"types": [
+				0,
+				1,
+				2,
+				21
+			],
+			"times": [
+				1,
+				2,
+				2,
+				6
+			],
+			"instance": [
+				12,
+				0,
+				0,
+				0
+			]
+		},
+		{
+			"name": "Tattooine",
+			"cluster": 8,
+			"nation": 0,
+			"r": 27,
+			"c": 55,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 2,
+			"ntypes": 4,
+			"types": [
+				0,
+				1,
+				2,
+				21
+			],
+			"times": [
+				1,
+				2,
+				2,
+				6
+			],
+			"instance": [
+				12,
+				0,
+				0,
+				0
+			]
+		},
+		{
+			"name": "Dagobah",
+			"cluster": 8,
+			"nation": 0,
+			"r": 23,
+			"c": 53,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 2,
+			"ntypes": 4,
+			"types": [
+				0,
+				1,
+				2,
+				21
+			],
+			"times": [
+				1,
+				2,
+				2,
+				6
+			],
+			"instance": [
+				12,
+				0,
+				0,
+				0
+			]
+		},
+		{
+			"name": "Hoth",
+			"cluster": 8,
+			"nation": 0,
+			"r": 22,
+			"c": 56,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 2,
+			"ntypes": 4,
+			"types": [
+				0,
+				1,
+				2,
+				21
+			],
+			"times": [
+				1,
+				2,
+				2,
+				6
+			],
+			"instance": [
+				12,
+				0,
+				0,
+				0
+			]
+		},
+		{
+			"name": "Yavin",
+			"cluster": 8,
+			"nation": 0,
+			"r": 19,
+			"c": 52,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 2,
+			"ntypes": 4,
+			"types": [
+				0,
+				1,
+				2,
+				21
+			],
+			"times": [
+				1,
+				2,
+				2,
+				6
+			],
+			"instance": [
+				12,
+				0,
+				0,
+				0
+			]
+		},
+		{
+			"name": "Endor",
+			"cluster": 8,
+			"nation": 0,
+			"r": 18,
+			"c": 56,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 2,
+			"ntypes": 4,
+			"types": [
+				0,
+				1,
+				2,
+				21
+			],
+			"times": [
+				1,
+				2,
+				2,
+				6
+			],
+			"instance": [
+				12,
+				0,
+				0,
+				0
+			]
+		}
+	],
+	"ttypes": [
+		{
+			"name": "Lt. Infantry",
+			"combat": 2,
+			"move_rate": 6,
+			"move_tbl": 0,
+			"special_mv": 0
+		},
+		{
+			"name": "Hv. Infantry",
+			"combat": 3,
+			"move_rate": 4,
+			"move_tbl": 0,
+			"special_mv": 0
+		},
+		{
+			"name": "Lt. Cavalry",
+			"combat": 2,
+			"move_rate": 12,
+			"move_tbl": 1,
+			"special_mv": 0
+		},
+		{
+			"name": "Hv. Cavalry",
+			"combat": 3,
+			"move_rate": 8,
+			"move_tbl": 1,
+			"special_mv": 0
+		},
+		{
+			"name": "Dwarf Legion",
+			"combat": 3,
+			"move_rate": 4,
+			"move_tbl": 2,
+			"special_mv": 0
+		},
+		{
+			"name": "Elven Archers",
+			"combat": 3,
+			"move_rate": 6,
+			"move_tbl": 3,
+			"special_mv": 0
+		},
+		{
+			"name": "Zombie Legion",
+			"combat": 3,
+			"move_rate": 3,
+			"move_tbl": 0,
+			"special_mv": 0
+		},
+		{
+			"name": "Wraith Horde",
+			"combat": 4,
+			"move_rate": 6,
+			"move_tbl": 4,
+			"special_mv": 0
+		},
+		{
+			"name": "Elite Troopers",
+			"combat": 4,
+			"move_rate": 4,
+			"move_tbl": 0,
+			"special_mv": 0
+		},
+		{
+			"name": "Gug",
+			"combat": 3,
+			"move_rate": 4,
+			"move_tbl": 0,
+			"special_mv": 0
+		},
+		{
+			"name": "Dwarf Miners",
+			"combat": 4,
+			"move_rate": 4,
+			"move_tbl": 5,
+			"special_mv": 0
+		},
+		{
+			"name": "Scout",
+			"combat": 1,
+			"move_rate": 8,
+			"move_tbl": 6,
+			"special_mv": 0
+		},
+		{
+			"name": "Byakhee",
+			"combat": 2,
+			"move_rate": 7,
+			"move_tbl": 4,
+			"special_mv": 2
+		},
+		{
+			"name": "Ghouls",
+			"combat": 3,
+			"move_rate": 5,
+			"move_tbl": 0,
+			"special_mv": 0
+		},
+		{
+			"name": "Navy",
+			"combat": 2,
+			"move_rate": 10,
+			"move_tbl": 7,
+			"special_mv": 3
+		},
+		{
+			"name": "Undead Navy",
+			"combat": 3,
+			"move_rate": 8,
+			"move_tbl": 7,
+			"special_mv": 3
+		},
+		{
+			"name": "Elf Clipper",
+			"combat": 2,
+			"move_rate": 12,
+			"move_tbl": 7,
+			"special_mv": 3
+		},
+		{
+			"name": "Elf Infantry",
+			"combat": 2,
+			"move_rate": 8,
+			"move_tbl": 3,
+			"special_mv": 0
+		},
+		{
+			"name": "Mermen",
+			"combat": 2,
+			"move_rate": 6,
+			"move_tbl": 7,
+			"special_mv": 0
+		},
+		{
+			"name": "Tritons",
+			"combat": 3,
+			"move_rate": 4,
+			"move_tbl": 7,
+			"special_mv": 0
+		},
+		{
+			"name": "Pegasus",
+			"combat": 2,
+			"move_rate": 10,
+			"move_tbl": 4,
+			"special_mv": 1
+		},
+		{
+			"name": "Hippogryff",
+			"combat": 3,
+			"move_rate": 8,
+			"move_tbl": 4,
+			"special_mv": 1
+		},
+		{
+			"name": "Leviathan",
+			"combat": 5,
+			"move_rate": 4,
+			"move_tbl": 8,
+			"special_mv": 1
+		}
+	],
+	"armies": [],
+	"move_table": [
+		{
+			"cost": [
+				0,
+				1,
+				2,
+				2,
+				4
+			]
+		},
+		{
+			"cost": [
+				0,
+				1,
+				2,
+				3,
+				0
+			]
+		},
+		{
+			"cost": [
+				0,
+				1,
+				2,
+				1,
+				2
+			]
+		},
+		{
+			"cost": [
+				0,
+				1,
+				1,
+				2,
+				4
+			]
+		},
+		{
+			"cost": [
+				1,
+				1,
+				1,
+				1,
+				2
+			]
+		},
+		{
+			"cost": [
+				0,
+				1,
+				2,
+				2,
+				3
+			]
+		},
+		{
+			"cost": [
+				0,
+				1,
+				1,
+				1,
+				2
+			]
+		},
+		{
+			"cost": [
+				1,
+				0,
+				0,
+				0,
+				0
+			]
+		},
+		{
+			"cost": [
+				1,
+				1,
+				2,
+				3,
+				4
+			]
+		}
+	],
+	"world": "Space War",
+	"gen": 54
+}
\ No newline at end of file
diff --git a/xtrn/war/worlds/spacewar/map b/xtrn/war/worlds/spacewar/map
new file mode 100644
index 0000000000000000000000000000000000000000..973ae1675cc7d331f05d982ea7ca3db5c9804824
--- /dev/null
+++ b/xtrn/war/worlds/spacewar/map
@@ -0,0 +1,66 @@
+M 64 64
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
diff --git a/xtrn/war/worlds/spacewar/map.png b/xtrn/war/worlds/spacewar/map.png
new file mode 100644
index 0000000000000000000000000000000000000000..f4791ba0ce52037665b7bea775e06fe90447b5f0
Binary files /dev/null and b/xtrn/war/worlds/spacewar/map.png differ
diff --git a/xtrn/war/worlds/tolivar/game.orig.json b/xtrn/war/worlds/tolivar/game.orig.json
new file mode 100644
index 0000000000000000000000000000000000000000..69585d0acbfe2cc8c76f1ca6fdf472de6367de26
--- /dev/null
+++ b/xtrn/war/worlds/tolivar/game.orig.json
@@ -0,0 +1,2047 @@
+{
+	"ncnt": 1,
+	"nations": [
+		{
+			"name": "Overlord",
+			"uid": 0,
+			"city": 0,
+			"mark": "*",
+			"idle_turns": 0
+		},
+		{
+			"name": "",
+			"uid": 0,
+			"city": 0,
+			"mark": "*",
+			"idle_turns": 0
+		},
+		{
+			"name": "",
+			"uid": 0,
+			"city": 0,
+			"mark": "*",
+			"idle_turns": 0
+		},
+		{
+			"name": "",
+			"uid": 0,
+			"city": 0,
+			"mark": "*",
+			"idle_turns": 0
+		},
+		{
+			"name": "",
+			"uid": 0,
+			"city": 0,
+			"mark": "*",
+			"idle_turns": 0
+		},
+		{
+			"name": "",
+			"uid": 0,
+			"city": 0,
+			"mark": "*",
+			"idle_turns": 0
+		},
+		{
+			"name": "",
+			"uid": 0,
+			"city": 0,
+			"mark": "*",
+			"idle_turns": 0
+		},
+		{
+			"name": "",
+			"uid": 0,
+			"city": 0,
+			"mark": "*",
+			"idle_turns": 0
+		},
+		{
+			"name": "",
+			"uid": 0,
+			"city": 0,
+			"mark": "*",
+			"idle_turns": 0
+		},
+		{
+			"name": "",
+			"uid": 0,
+			"city": 0,
+			"mark": "*",
+			"idle_turns": 0
+		},
+		{
+			"name": "",
+			"uid": 0,
+			"city": 0,
+			"mark": "*",
+			"idle_turns": 0
+		},
+		{
+			"name": "",
+			"uid": 0,
+			"city": 0,
+			"mark": "*",
+			"idle_turns": 0
+		},
+		{
+			"name": "",
+			"uid": 0,
+			"city": 0,
+			"mark": "*",
+			"idle_turns": 0
+		},
+		{
+			"name": "",
+			"uid": 0,
+			"city": 0,
+			"mark": "*",
+			"idle_turns": 0
+		},
+		{
+			"name": "",
+			"uid": 0,
+			"city": 0,
+			"mark": "*",
+			"idle_turns": 0
+		},
+		{
+			"name": "",
+			"uid": 0,
+			"city": 0,
+			"mark": "*",
+			"idle_turns": 0
+		},
+		{
+			"name": "",
+			"uid": 0,
+			"city": 0,
+			"mark": "*",
+			"idle_turns": 0
+		},
+		{
+			"name": "",
+			"uid": 0,
+			"city": 0,
+			"mark": "*",
+			"idle_turns": 0
+		},
+		{
+			"name": "",
+			"uid": 0,
+			"city": 0,
+			"mark": "*",
+			"idle_turns": 0
+		},
+		{
+			"name": "",
+			"uid": 0,
+			"city": 0,
+			"mark": "*",
+			"idle_turns": 0
+		},
+		{
+			"name": "",
+			"uid": 0,
+			"city": 0,
+			"mark": "*",
+			"idle_turns": 0
+		},
+		{
+			"name": "",
+			"uid": 0,
+			"city": 0,
+			"mark": "*",
+			"idle_turns": 0
+		},
+		{
+			"name": "",
+			"uid": 0,
+			"city": 0,
+			"mark": "*",
+			"idle_turns": 0
+		},
+		{
+			"name": "",
+			"uid": 0,
+			"city": 0,
+			"mark": "*",
+			"idle_turns": 0
+		},
+		{
+			"name": "",
+			"uid": 0,
+			"city": 0,
+			"mark": "*",
+			"idle_turns": 0
+		},
+		{
+			"name": "",
+			"uid": 0,
+			"city": 0,
+			"mark": "*",
+			"idle_turns": 0
+		},
+		{
+			"name": "",
+			"uid": 0,
+			"city": 0,
+			"mark": "*",
+			"idle_turns": 0
+		},
+		{
+			"name": "Rogue",
+			"uid": -1,
+			"city": 0,
+			"mark": "?",
+			"idle_turns": 0
+		}
+	],
+	"cities": [
+		{
+			"name": "Indigo",
+			"cluster": 1,
+			"nation": 0,
+			"r": 5,
+			"c": 4,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 2,
+			"ntypes": 4,
+			"types": [
+				0,
+				1,
+				2,
+				21
+			],
+			"times": [
+				1,
+				2,
+				2,
+				6
+			],
+			"instance": [
+				0,
+				0,
+				0,
+				0
+			]
+		},
+		{
+			"name": "Lavender",
+			"cluster": 1,
+			"nation": 0,
+			"r": 7,
+			"c": 2,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 2,
+			"ntypes": 4,
+			"types": [
+				0,
+				1,
+				2,
+				14
+			],
+			"times": [
+				1,
+				2,
+				2,
+				6
+			],
+			"instance": [
+				0,
+				0,
+				0,
+				0
+			]
+		},
+		{
+			"name": "Crimson",
+			"cluster": 1,
+			"nation": 0,
+			"r": 3,
+			"c": 5,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 2,
+			"ntypes": 3,
+			"types": [
+				0,
+				1,
+				2,
+				3
+			],
+			"times": [
+				1,
+				2,
+				2,
+				4
+			],
+			"instance": [
+				0,
+				0,
+				0,
+				0
+			]
+		},
+		{
+			"name": "Saffron",
+			"cluster": 1,
+			"nation": 0,
+			"r": 9,
+			"c": 8,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 2,
+			"ntypes": 3,
+			"types": [
+				0,
+				1,
+				2,
+				-1
+			],
+			"times": [
+				1,
+				2,
+				2,
+				-1
+			],
+			"instance": [
+				0,
+				0,
+				0,
+				0
+			]
+		},
+		{
+			"name": "Verdant",
+			"cluster": 1,
+			"nation": 0,
+			"r": 6,
+			"c": 10,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 2,
+			"ntypes": 4,
+			"types": [
+				0,
+				1,
+				2,
+				14
+			],
+			"times": [
+				1,
+				2,
+				2,
+				6
+			],
+			"instance": [
+				0,
+				0,
+				0,
+				0
+			]
+		},
+		{
+			"name": "Metropolis",
+			"cluster": 2,
+			"nation": 0,
+			"r": 28,
+			"c": 10,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 2,
+			"ntypes": 4,
+			"types": [
+				0,
+				1,
+				2,
+				3
+			],
+			"times": [
+				1,
+				2,
+				2,
+				4
+			],
+			"instance": [
+				0,
+				0,
+				0,
+				0
+			]
+		},
+		{
+			"name": "Gotham",
+			"cluster": 2,
+			"nation": 0,
+			"r": 29,
+			"c": 5,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 2,
+			"ntypes": 3,
+			"types": [
+				0,
+				1,
+				2,
+				-1
+			],
+			"times": [
+				1,
+				2,
+				2,
+				-1
+			],
+			"instance": [
+				0,
+				0,
+				0,
+				0
+			]
+		},
+		{
+			"name": "Keystone City",
+			"cluster": 2,
+			"nation": 0,
+			"r": 31,
+			"c": 8,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 2,
+			"ntypes": 4,
+			"types": [
+				0,
+				1,
+				2,
+				20
+			],
+			"times": [
+				1,
+				2,
+				2,
+				5
+			],
+			"instance": [
+				0,
+				0,
+				0,
+				0
+			]
+		},
+		{
+			"name": "Central City",
+			"cluster": 2,
+			"nation": 0,
+			"r": 35,
+			"c": 9,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 2,
+			"ntypes": 4,
+			"types": [
+				0,
+				1,
+				2,
+				14
+			],
+			"times": [
+				1,
+				2,
+				2,
+				6
+			],
+			"instance": [
+				0,
+				0,
+				0,
+				0
+			]
+		},
+		{
+			"name": "Heliochrysum",
+			"cluster": 3,
+			"nation": 0,
+			"r": 32,
+			"c": 24,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 2,
+			"ntypes": 4,
+			"types": [
+				0,
+				1,
+				2,
+				3
+			],
+			"times": [
+				1,
+				2,
+				2,
+				4
+			],
+			"instance": [
+				0,
+				0,
+				0,
+				0
+			]
+		},
+		{
+			"name": "Portulaca",
+			"cluster": 3,
+			"nation": 0,
+			"r": 33,
+			"c": 29,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 2,
+			"ntypes": 4,
+			"types": [
+				0,
+				1,
+				2,
+				3
+			],
+			"times": [
+				1,
+				2,
+				2,
+				4
+			],
+			"instance": [
+				0,
+				0,
+				0,
+				0
+			]
+		},
+		{
+			"name": "Gaillardia",
+			"cluster": 3,
+			"nation": 0,
+			"r": 38,
+			"c": 24,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 2,
+			"ntypes": 4,
+			"types": [
+				0,
+				1,
+				2,
+				14
+			],
+			"times": [
+				1,
+				2,
+				2,
+				6
+			],
+			"instance": [
+				0,
+				0,
+				0,
+				0
+			]
+		},
+		{
+			"name": "Coreopsis",
+			"cluster": 3,
+			"nation": 0,
+			"r": 36,
+			"c": 21,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 2,
+			"ntypes": 4,
+			"types": [
+				0,
+				1,
+				2,
+				21
+			],
+			"times": [
+				1,
+				2,
+				2,
+				6
+			],
+			"instance": [
+				0,
+				0,
+				0,
+				0
+			]
+		},
+		{
+			"name": "Delphineum",
+			"cluster": 3,
+			"nation": 0,
+			"r": 33,
+			"c": 19,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 2,
+			"ntypes": 4,
+			"types": [
+				0,
+				1,
+				2,
+				14
+			],
+			"times": [
+				1,
+				2,
+				2,
+				6
+			],
+			"instance": [
+				0,
+				0,
+				0,
+				0
+			]
+		},
+		{
+			"name": "Ruby",
+			"cluster": 4,
+			"nation": 0,
+			"r": 14,
+			"c": 23,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 2,
+			"ntypes": 4,
+			"types": [
+				0,
+				1,
+				2,
+				3
+			],
+			"times": [
+				1,
+				2,
+				2,
+				4
+			],
+			"instance": [
+				0,
+				0,
+				0,
+				0
+			]
+		},
+		{
+			"name": "Amber",
+			"cluster": 4,
+			"nation": 0,
+			"r": 16,
+			"c": 20,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 2,
+			"ntypes": 3,
+			"types": [
+				0,
+				1,
+				2,
+				-1
+			],
+			"times": [
+				1,
+				2,
+				2,
+				-1
+			],
+			"instance": [
+				0,
+				0,
+				0,
+				0
+			]
+		},
+		{
+			"name": "Emerald",
+			"cluster": 4,
+			"nation": 0,
+			"r": 16,
+			"c": 28,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 2,
+			"ntypes": 4,
+			"types": [
+				0,
+				1,
+				2,
+				14
+			],
+			"times": [
+				1,
+				2,
+				2,
+				6
+			],
+			"instance": [
+				0,
+				0,
+				0,
+				0
+			]
+		},
+		{
+			"name": "Diamond",
+			"cluster": 4,
+			"nation": 0,
+			"r": 18,
+			"c": 25,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 2,
+			"ntypes": 4,
+			"types": [
+				0,
+				1,
+				2,
+				14
+			],
+			"times": [
+				1,
+				2,
+				2,
+				6
+			],
+			"instance": [
+				0,
+				0,
+				0,
+				0
+			]
+		},
+		{
+			"name": "Sapphire",
+			"cluster": 4,
+			"nation": 0,
+			"r": 19,
+			"c": 22,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 2,
+			"ntypes": 4,
+			"types": [
+				0,
+				1,
+				2,
+				20
+			],
+			"times": [
+				1,
+				2,
+				2,
+				5
+			],
+			"instance": [
+				0,
+				0,
+				0,
+				0
+			]
+		},
+		{
+			"name": "Zhentil Keep",
+			"cluster": 5,
+			"nation": 0,
+			"r": 40,
+			"c": 18,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 2,
+			"ntypes": 4,
+			"types": [
+				0,
+				1,
+				2,
+				3
+			],
+			"times": [
+				1,
+				2,
+				2,
+				4
+			],
+			"instance": [
+				0,
+				0,
+				0,
+				0
+			]
+		},
+		{
+			"name": "Shadowdale",
+			"cluster": 5,
+			"nation": 0,
+			"r": 42,
+			"c": 20,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 2,
+			"ntypes": 4,
+			"types": [
+				0,
+				1,
+				2,
+				14
+			],
+			"times": [
+				1,
+				2,
+				2,
+				6
+			],
+			"instance": [
+				0,
+				0,
+				0,
+				0
+			]
+		},
+		{
+			"name": "Silverdale",
+			"cluster": 5,
+			"nation": 0,
+			"r": 45,
+			"c": 22,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 2,
+			"ntypes": 4,
+			"types": [
+				0,
+				1,
+				2,
+				20
+			],
+			"times": [
+				1,
+				2,
+				2,
+				6
+			],
+			"instance": [
+				0,
+				0,
+				0,
+				0
+			]
+		},
+		{
+			"name": "Battledale",
+			"cluster": 5,
+			"nation": 0,
+			"r": 48,
+			"c": 24,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 2,
+			"ntypes": 4,
+			"types": [
+				0,
+				1,
+				2,
+				14
+			],
+			"times": [
+				1,
+				2,
+				2,
+				6
+			],
+			"instance": [
+				0,
+				0,
+				0,
+				0
+			]
+		},
+		{
+			"name": "Dread",
+			"cluster": 6,
+			"nation": 0,
+			"r": 38,
+			"c": 0,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 3,
+			"ntypes": 2,
+			"types": [
+				6,
+				7,
+				-1,
+				-1
+			],
+			"times": [
+				1,
+				4,
+				-1,
+				-1
+			],
+			"instance": [
+				0,
+				0,
+				0,
+				0
+			]
+		},
+		{
+			"name": "Doom",
+			"cluster": 6,
+			"nation": 0,
+			"r": 39,
+			"c": 4,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 3,
+			"ntypes": 3,
+			"types": [
+				6,
+				7,
+				15,
+				-1
+			],
+			"times": [
+				1,
+				4,
+				6,
+				-1
+			],
+			"instance": [
+				0,
+				0,
+				0,
+				0
+			]
+		},
+		{
+			"name": "Despair",
+			"cluster": 6,
+			"nation": 0,
+			"r": 42,
+			"c": 3,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 3,
+			"ntypes": 2,
+			"types": [
+				6,
+				13,
+				-1,
+				-1
+			],
+			"times": [
+				1,
+				3,
+				-1,
+				-1
+			],
+			"instance": [
+				0,
+				0,
+				0,
+				0
+			]
+		},
+		{
+			"name": "Death",
+			"cluster": 6,
+			"nation": 0,
+			"r": 43,
+			"c": 9,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 3,
+			"ntypes": 2,
+			"types": [
+				6,
+				7,
+				-1,
+				-1
+			],
+			"times": [
+				1,
+				5,
+				-1,
+				-1
+			],
+			"instance": [
+				0,
+				0,
+				0,
+				0
+			]
+		},
+		{
+			"name": "Agony",
+			"cluster": 6,
+			"nation": 0,
+			"r": 45,
+			"c": 4,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 3,
+			"ntypes": 3,
+			"types": [
+				6,
+				13,
+				15,
+				-1
+			],
+			"times": [
+				1,
+				3,
+				6,
+				-1
+			],
+			"instance": [
+				0,
+				0,
+				0,
+				0
+			]
+		},
+		{
+			"name": "Gloom",
+			"cluster": 6,
+			"nation": 0,
+			"r": 49,
+			"c": 3,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 3,
+			"ntypes": 2,
+			"types": [
+				6,
+				7,
+				-1,
+				-1
+			],
+			"times": [
+				1,
+				5,
+				-1,
+				-1
+			],
+			"instance": [
+				0,
+				0,
+				0,
+				0
+			]
+		},
+		{
+			"name": "Iron",
+			"cluster": 7,
+			"nation": 0,
+			"r": 55,
+			"c": 8,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 3,
+			"ntypes": 4,
+			"types": [
+				0,
+				1,
+				8,
+				14
+			],
+			"times": [
+				1,
+				2,
+				3,
+				6
+			],
+			"instance": [
+				0,
+				0,
+				0,
+				0
+			]
+		},
+		{
+			"name": "Gold",
+			"cluster": 7,
+			"nation": 0,
+			"r": 54,
+			"c": 14,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 3,
+			"ntypes": 4,
+			"types": [
+				0,
+				1,
+				8,
+				20
+			],
+			"times": [
+				1,
+				2,
+				3,
+				5
+			],
+			"instance": [
+				0,
+				0,
+				0,
+				0
+			]
+		},
+		{
+			"name": "Silver",
+			"cluster": 7,
+			"nation": 0,
+			"r": 58,
+			"c": 13,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 3,
+			"ntypes": 4,
+			"types": [
+				0,
+				1,
+				8,
+				14
+			],
+			"times": [
+				1,
+				2,
+				3,
+				6
+			],
+			"instance": [
+				0,
+				0,
+				0,
+				0
+			]
+		},
+		{
+			"name": "Tin",
+			"cluster": 7,
+			"nation": 0,
+			"r": 57,
+			"c": 10,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 3,
+			"ntypes": 3,
+			"types": [
+				0,
+				1,
+				8,
+				-1
+			],
+			"times": [
+				1,
+				2,
+				3,
+				-1
+			],
+			"instance": [
+				0,
+				0,
+				0,
+				0
+			]
+		},
+		{
+			"name": "Lead",
+			"cluster": 7,
+			"nation": 0,
+			"r": 51,
+			"c": 13,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 3,
+			"ntypes": 3,
+			"types": [
+				0,
+				1,
+				8,
+				-1
+			],
+			"times": [
+				1,
+				2,
+				3,
+				-1
+			],
+			"instance": [
+				0,
+				0,
+				0,
+				0
+			]
+		},
+		{
+			"name": "Nyarlathotep",
+			"cluster": 8,
+			"nation": 0,
+			"r": 34,
+			"c": 55,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 2,
+			"ntypes": 2,
+			"types": [
+				9,
+				12,
+				-1,
+				-1
+			],
+			"times": [
+				1,
+				3,
+				-1,
+				-1
+			],
+			"instance": [
+				0,
+				0,
+				0,
+				0
+			]
+		},
+		{
+			"name": "Yogsothoth",
+			"cluster": 8,
+			"nation": 0,
+			"r": 30,
+			"c": 52,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 2,
+			"ntypes": 2,
+			"types": [
+				9,
+				12,
+				-1,
+				-1
+			],
+			"times": [
+				1,
+				3,
+				-1,
+				-1
+			],
+			"instance": [
+				0,
+				0,
+				0,
+				0
+			]
+		},
+		{
+			"name": "Cthulhu",
+			"cluster": 8,
+			"nation": 0,
+			"r": 31,
+			"c": 57,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 2,
+			"ntypes": 2,
+			"types": [
+				9,
+				13,
+				-1,
+				-1
+			],
+			"times": [
+				1,
+				3,
+				-1,
+				-1
+			],
+			"instance": [
+				0,
+				0,
+				0,
+				0
+			]
+		},
+		{
+			"name": "Hastor",
+			"cluster": 8,
+			"nation": 0,
+			"r": 28,
+			"c": 59,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 2,
+			"ntypes": 2,
+			"types": [
+				9,
+				13,
+				-1,
+				-1
+			],
+			"times": [
+				1,
+				3,
+				-1,
+				-1
+			],
+			"instance": [
+				0,
+				0,
+				0,
+				0
+			]
+		},
+		{
+			"name": "Olan",
+			"cluster": 9,
+			"nation": 0,
+			"r": 42,
+			"c": 59,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 3,
+			"ntypes": 2,
+			"types": [
+				4,
+				10,
+				-1,
+				-1
+			],
+			"times": [
+				1,
+				3,
+				-1,
+				-1
+			],
+			"instance": [
+				0,
+				0,
+				0,
+				0
+			]
+		},
+		{
+			"name": "Kaxandar",
+			"cluster": 9,
+			"nation": 0,
+			"r": 40,
+			"c": 58,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 3,
+			"ntypes": 2,
+			"types": [
+				4,
+				10,
+				-1,
+				-1
+			],
+			"times": [
+				1,
+				3,
+				-1,
+				-1
+			],
+			"instance": [
+				0,
+				0,
+				0,
+				0
+			]
+		},
+		{
+			"name": "Torgar",
+			"cluster": 9,
+			"nation": 0,
+			"r": 46,
+			"c": 60,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 3,
+			"ntypes": 2,
+			"types": [
+				4,
+				10,
+				-1,
+				-1
+			],
+			"times": [
+				1,
+				3,
+				-1,
+				-1
+			],
+			"instance": [
+				0,
+				0,
+				0,
+				0
+			]
+		},
+		{
+			"name": "Arras Charka",
+			"cluster": 10,
+			"nation": 0,
+			"r": 18,
+			"c": 43,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 2,
+			"ntypes": 3,
+			"types": [
+				0,
+				1,
+				21,
+				-1
+			],
+			"times": [
+				1,
+				2,
+				6,
+				-1
+			],
+			"instance": [
+				0,
+				0,
+				0,
+				0
+			]
+		},
+		{
+			"name": "Derzon",
+			"cluster": 10,
+			"nation": 0,
+			"r": 17,
+			"c": 51,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 2,
+			"ntypes": 3,
+			"types": [
+				0,
+				1,
+				2,
+				-1
+			],
+			"times": [
+				1,
+				2,
+				2,
+				-1
+			],
+			"instance": [
+				0,
+				0,
+				0,
+				0
+			]
+		},
+		{
+			"name": "Ekosiak",
+			"cluster": 10,
+			"nation": 0,
+			"r": 20,
+			"c": 47,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 2,
+			"ntypes": 4,
+			"types": [
+				0,
+				1,
+				2,
+				3
+			],
+			"times": [
+				1,
+				2,
+				2,
+				4
+			],
+			"instance": [
+				0,
+				0,
+				0,
+				0
+			]
+		},
+		{
+			"name": "Ish-Tako",
+			"cluster": 10,
+			"nation": 0,
+			"r": 16,
+			"c": 46,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 2,
+			"ntypes": 4,
+			"types": [
+				0,
+				1,
+				8,
+				14
+			],
+			"times": [
+				1,
+				2,
+				3,
+				6
+			],
+			"instance": [
+				0,
+				0,
+				0,
+				0
+			]
+		},
+		{
+			"name": "Chishata",
+			"cluster": 10,
+			"nation": 0,
+			"r": 23,
+			"c": 50,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 2,
+			"ntypes": 4,
+			"types": [
+				0,
+				1,
+				8,
+				14
+			],
+			"times": [
+				1,
+				2,
+				3,
+				6
+			],
+			"instance": [
+				0,
+				0,
+				0,
+				0
+			]
+		},
+		{
+			"name": "Qualinesti",
+			"cluster": 11,
+			"nation": 0,
+			"r": 53,
+			"c": 54,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 2,
+			"ntypes": 4,
+			"types": [
+				17,
+				5,
+				11,
+				20
+			],
+			"times": [
+				1,
+				2,
+				2,
+				4
+			],
+			"instance": [
+				0,
+				0,
+				0,
+				0
+			]
+		},
+		{
+			"name": "Sylvanesti",
+			"cluster": 11,
+			"nation": 0,
+			"r": 56,
+			"c": 55,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 2,
+			"ntypes": 4,
+			"types": [
+				17,
+				5,
+				11,
+				16
+			],
+			"times": [
+				1,
+				2,
+				2,
+				7
+			],
+			"instance": [
+				0,
+				0,
+				0,
+				0
+			]
+		},
+		{
+			"name": "Rathwynn",
+			"cluster": 11,
+			"nation": 0,
+			"r": 62,
+			"c": 58,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 2,
+			"ntypes": 3,
+			"types": [
+				17,
+				5,
+				11,
+				-1
+			],
+			"times": [
+				1,
+				2,
+				2,
+				-1
+			],
+			"instance": [
+				0,
+				0,
+				0,
+				0
+			]
+		},
+		{
+			"name": "Caledon",
+			"cluster": 11,
+			"nation": 0,
+			"r": 60,
+			"c": 54,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 2,
+			"ntypes": 4,
+			"types": [
+				17,
+				5,
+				11,
+				16
+			],
+			"times": [
+				1,
+				2,
+				2,
+				7
+			],
+			"instance": [
+				0,
+				0,
+				0,
+				0
+			]
+		},
+		{
+			"name": "Alfheim",
+			"cluster": 11,
+			"nation": 0,
+			"r": 58,
+			"c": 51,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 2,
+			"ntypes": 4,
+			"types": [
+				17,
+				5,
+				11,
+				16
+			],
+			"times": [
+				1,
+				2,
+				2,
+				7
+			],
+			"instance": [
+				0,
+				0,
+				0,
+				0
+			]
+		},
+		{
+			"name": "Atlantis",
+			"cluster": 12,
+			"nation": 0,
+			"r": 49,
+			"c": 41,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 2,
+			"ntypes": 3,
+			"types": [
+				18,
+				19,
+				22,
+				-1
+			],
+			"times": [
+				1,
+				2,
+				8,
+				-1
+			],
+			"instance": [
+				0,
+				0,
+				0,
+				0
+			]
+		},
+		{
+			"name": "Mu",
+			"cluster": 12,
+			"nation": 0,
+			"r": 49,
+			"c": 37,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 2,
+			"ntypes": 3,
+			"types": [
+				18,
+				19,
+				22,
+				-1
+			],
+			"times": [
+				1,
+				2,
+				8,
+				-1
+			],
+			"instance": [
+				0,
+				0,
+				0,
+				0
+			]
+		},
+		{
+			"name": "Poseidon",
+			"cluster": 12,
+			"nation": 0,
+			"r": 46,
+			"c": 42,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 2,
+			"ntypes": 3,
+			"types": [
+				18,
+				19,
+				22,
+				-1
+			],
+			"times": [
+				1,
+				2,
+				8,
+				-1
+			],
+			"instance": [
+				0,
+				0,
+				0,
+				0
+			]
+		},
+		{
+			"name": "Neptune",
+			"cluster": 12,
+			"nation": 0,
+			"r": 44,
+			"c": 38,
+			"prod_type": 0,
+			"turns_left": 1,
+			"defense": 2,
+			"ntypes": 3,
+			"types": [
+				18,
+				19,
+				22,
+				-1
+			],
+			"times": [
+				1,
+				2,
+				8,
+				-1
+			],
+			"instance": [
+				0,
+				0,
+				0,
+				0
+			]
+		}
+	],
+	"ttypes": [
+		{
+			"name": "Lt. Infantry",
+			"combat": 2,
+			"move_rate": 6,
+			"move_tbl": 0,
+			"special_mv": 0
+		},
+		{
+			"name": "Hv. Infantry",
+			"combat": 3,
+			"move_rate": 4,
+			"move_tbl": 0,
+			"special_mv": 0
+		},
+		{
+			"name": "Lt. Cavalry",
+			"combat": 2,
+			"move_rate": 12,
+			"move_tbl": 1,
+			"special_mv": 0
+		},
+		{
+			"name": "Hv. Cavalry",
+			"combat": 3,
+			"move_rate": 8,
+			"move_tbl": 1,
+			"special_mv": 0
+		},
+		{
+			"name": "Dwarf Legion",
+			"combat": 3,
+			"move_rate": 4,
+			"move_tbl": 2,
+			"special_mv": 0
+		},
+		{
+			"name": "Elven Archers",
+			"combat": 3,
+			"move_rate": 6,
+			"move_tbl": 3,
+			"special_mv": 0
+		},
+		{
+			"name": "Zombie Legion",
+			"combat": 3,
+			"move_rate": 3,
+			"move_tbl": 0,
+			"special_mv": 0
+		},
+		{
+			"name": "Wraith Horde",
+			"combat": 4,
+			"move_rate": 6,
+			"move_tbl": 4,
+			"special_mv": 0
+		},
+		{
+			"name": "Elite Troopers",
+			"combat": 4,
+			"move_rate": 4,
+			"move_tbl": 0,
+			"special_mv": 0
+		},
+		{
+			"name": "Gug",
+			"combat": 3,
+			"move_rate": 4,
+			"move_tbl": 0,
+			"special_mv": 0
+		},
+		{
+			"name": "Dwarf Miners",
+			"combat": 4,
+			"move_rate": 4,
+			"move_tbl": 5,
+			"special_mv": 0
+		},
+		{
+			"name": "Scout",
+			"combat": 1,
+			"move_rate": 8,
+			"move_tbl": 6,
+			"special_mv": 0
+		},
+		{
+			"name": "Byakhee",
+			"combat": 2,
+			"move_rate": 7,
+			"move_tbl": 4,
+			"special_mv": 2
+		},
+		{
+			"name": "Ghouls",
+			"combat": 3,
+			"move_rate": 5,
+			"move_tbl": 0,
+			"special_mv": 0
+		},
+		{
+			"name": "Navy",
+			"combat": 2,
+			"move_rate": 10,
+			"move_tbl": 7,
+			"special_mv": 3
+		},
+		{
+			"name": "Undead Navy",
+			"combat": 3,
+			"move_rate": 8,
+			"move_tbl": 7,
+			"special_mv": 3
+		},
+		{
+			"name": "Elf Clipper",
+			"combat": 2,
+			"move_rate": 12,
+			"move_tbl": 7,
+			"special_mv": 3
+		},
+		{
+			"name": "Elf Infantry",
+			"combat": 2,
+			"move_rate": 8,
+			"move_tbl": 3,
+			"special_mv": 0
+		},
+		{
+			"name": "Mermen",
+			"combat": 2,
+			"move_rate": 6,
+			"move_tbl": 7,
+			"special_mv": 0
+		},
+		{
+			"name": "Tritons",
+			"combat": 3,
+			"move_rate": 4,
+			"move_tbl": 7,
+			"special_mv": 0
+		},
+		{
+			"name": "Pegasus",
+			"combat": 2,
+			"move_rate": 10,
+			"move_tbl": 4,
+			"special_mv": 1
+		},
+		{
+			"name": "Hippogryff",
+			"combat": 3,
+			"move_rate": 8,
+			"move_tbl": 4,
+			"special_mv": 1
+		},
+		{
+			"name": "Leviathan",
+			"combat": 5,
+			"move_rate": 4,
+			"move_tbl": 8,
+			"special_mv": 1
+		}
+	],
+	"armies": [],
+	"move_table": [
+		{
+			"cost": [
+				0,
+				1,
+				2,
+				2,
+				4
+			]
+		},
+		{
+			"cost": [
+				0,
+				1,
+				2,
+				3,
+				0
+			]
+		},
+		{
+			"cost": [
+				0,
+				1,
+				2,
+				1,
+				2
+			]
+		},
+		{
+			"cost": [
+				0,
+				1,
+				1,
+				2,
+				4
+			]
+		},
+		{
+			"cost": [
+				1,
+				1,
+				1,
+				1,
+				2
+			]
+		},
+		{
+			"cost": [
+				0,
+				1,
+				2,
+				2,
+				3
+			]
+		},
+		{
+			"cost": [
+				0,
+				1,
+				1,
+				1,
+				2
+			]
+		},
+		{
+			"cost": [
+				1,
+				0,
+				0,
+				0,
+				0
+			]
+		},
+		{
+			"cost": [
+				1,
+				1,
+				2,
+				3,
+				4
+			]
+		}
+	],
+	"world": "Solomoriah's World",
+	"gen": 0
+}
\ No newline at end of file
diff --git a/xtrn/war/worlds/tolivar/map b/xtrn/war/worlds/tolivar/map
new file mode 100644
index 0000000000000000000000000000000000000000..417f7641ccada1b60607548ff9f3b98f12fd36df
--- /dev/null
+++ b/xtrn/war/worlds/tolivar/map
@@ -0,0 +1,66 @@
+M 64 64
+
+~~##~~~~~~~~~~~~%%%%~~~~~~~~~~~~~~~~~.....~~~~~~~~~~~###~~~~~~~~
+~~~~~~~~~~~~~~~%%%..~~~~~~~~~~~~~~~~~~....~~~~~~%%~~~.##~~~~~~~~
+~~~~~~~~~~~~~~~%%%..~~~~~~~~~~~%%%~~~....~~~~~~%%%%~....~~~~~~~~
+~~~~~~~~~~~~~~%%%%..~~~~~~~~~~~%%%......~~~~~~%%%%%~....~~~~~~~~
+~~~~~~~~~~~~~%%%%%..~~~~~~~~~~~~%........~~^^^%%%%%~....~~~~~~~~
+~~~~~~~~~~~~%%%%~~~~..~~~~~~~~~~~.........^^^^..%%~~~..~~~~~~~~~
+##~~~~~~~...%%%~~~~....~~~~~~~~~~~........^^^^...~~~~~~~~~~~~~~~
+###..~~~....###~~~~....~~~##~~~~~~~~.......^^....~~~~~~~~~~~~~~#
+###...^^^...###~~~~~....~####~~~~~~~###~~~~~....~~~~~~~~~~~~~~~#
+%%~~..^^^^^^##~~~~~~......##..~~~~~####~~~%%...~~~~~~~~~~~~~~~~%
+%%%%..^^^^^^^^^~~~~~~.........~~~~~#####%%%%%~~~~~~~~~~~~~~~~~~%
+%%%%%..^^^^^^^^^~~~~~~........~~~~#~###%%%%%~~~~~~~~~~~~~~~~~~~~
+%%%%~~~.^^^...^^^~~~~~~~~~~~~~~~~#####%%%%%~~~~~~~~~~~~~~~~~~~~~
+%%%~~~~~~......^^~~~~~~~~~~~~~~~~####^%%%%%~~~~~~.~~~~~~~~~~~~~~
+%%~~~~~~~~....%%%~~~~~~~~~~~~~~~~~##^^^%%%~~~~~~...~~~~~~~~~~~~~
+%%%~~~~~~~~...%%%~~~~~~~~~~~~~~~~~^^^^^^~%%~~~~~~.~~~~~~~~~~~##%
+%%%~~~~^^^....%%~~~~~~~~~~~~~~~~~~^^^^^^~~##~~~~~~~~~~~~~~~~###%
+%%%~~~^^^^....~~~~~~~~~~~~~~~~~~~~.^^^^~~~###~~~~~~~~~~~~~~..##%
+%%~~~~^^^.....~~~~~~~~~~~~~~~~~~~...~~~~~####~~.~~~~~~~~~~~.....
+.~~~...~~.....~~~~~~~~~~~~~~~~~~~~.~~~~~~###~~...~~~~~~~~~~.....
+..~....~~~...~~~~~~~~~~~~~~~~~~~~~~~~~~~~###~~~..~~~~~~~~~~.....
+.......~~~~~~~~~~~~~~~~~~~~~~~~~~~~~##~~~~##~~~^^%~~~~~~~~~.....
+.....%%%~~~~~~~~~~~~~~~~~~~~~~~~~~~####~~~##~~~^^^~~~~~~~~~.....
+~~~~%%%%.~~~~~~~~~~~~~~~~~~~~~~~~~~####~~###~~~^^~~~~~~~^^~~..~~
+~~~~%%%...~~~~~~~~~~~~~~~~~~~~~~~~~~#######~~~~~~~~~~~~^^^^~~~~~
+~~~~%%%....~~~~~~~~~~~~~~~~~~~~~~~~#######~~~~~~~~~~~~~^^^^~~~~~
+~~~~~~~~~.~~~~~~~~~~~~~~~~~~~~~~~~~~#####~%%%~~~~~~~~%%%^^~~~~~~
+^^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%%%.~~~~~~%%%%%~~~~~~~
+^^^~~~~~~~~~~~~~~~~...%%~~~~~~~~~~~~~~~~~~%%...~~~~~%%%%%~~~~~~.
+^^^~~~~~~~~~~~~~~......%~~~~~~~~~~~~~~~~~~~%......%%%~%%~~~~~~~~
+~^%%~~~~~~~~~~~~~.....~~~~~~~~~~~~~~~~~%~~%%......%%%~~~~~~~~~~~
+~~%%~~~~~~~~~~~~~~...~~~~~~~~~~~~~~~~~%%%%%%.......%%~~~~~~~~~~~
+~....~~~~~~~~~~~~~...~~~~~~~~~~~~~~~~~~%~~%%%.......~~~~~~~~~~~~
+.......~~~~~~~~~~~~......~~~~~~~~~~~~~~~~~~%~~~~....~~~~~~~~~~~~
+........%%%~~~~~~~~.......~~~~~~~~~~~~~~~~~~~~~~~..~~~~~~~~~~...
+.~.....%%%%%~~~~~~~~......~~~~~~~~~~~~~~~~~~~~~~~##~~~~~~~~~~...
+~~%....%%%%%~~~~~~~~~~~....~~~~~##~~~~~~~~~~~~~~~##~~~~~~...~~..
+^%%%%%%~~~%%#~~~~~~~~~~~.....#####.~~~~~~~~~~~~~.##~~~~~....~~~^
+^%%%%%%~~~~^^^~~~~~~~~~~~....###~...^^~~~~~~~~~~^##~~~~~....~~~^
+^^%%%%~~~~~^^^^~~~~~~~~~~~..~~~~...^^^^~~~~..~~^^^.~~~~##.~^~~~~
+~~~%%~~~~~~~^^~~~~~~~~~~~~~~~~~%...^^^..~~....^^^...~~###~^^^~~~
+~~~~~~~~~~~~##~~~~~~~~~~~~~~~~%%%.~~..........^^^......#~~^^~~~~
+~~~~~~~~~~~~###~~~~~~~~~..~~~%%%%%~~......~~...^~~.....~~~..~~~~
+~~~~~~...~~~~###%%%%~~~.......%%%#~~~..........~~~~...~~~~.~~~~~
+~~~~~.....~~~~~#%%%%%~~........####~~~.........~~~~~~~~~~~~~~~~~
+~~~~......~~~~~##%%%%%~~...~...####.~~~..%%.....~~~~~~~~~~~~~~~~
+~~~......~~~~~~###%%%%~~~..~...###...~~%%%%%....~~~~~~~~~~~~~~~~
+~~##.~..%%~~~~~~#^^^^.......%%~~~^....%%%%%%....~~~~~~~~~~~~~~~~
+.###~~~%%%%~~~~~~^^^^.....%%%%%^^^^..~%%%%%%~..~~~~~~~~~~~~~~~~.
+#####~~%%%%%~~~~~^^^^....~%%%%^^^^%%%%%%%..~~~~~~~~~~~~~~~~~~~..
+####^^..%%%%~~~~^^^^^^..~~~~~~^^^%%%%%%%...~~~~~~~~~~~~~~~~~~..#
+###^^^...%%~~~~~^^^^^^%%~~~~~~~^^%%%%%%%...~~~~~~~~~~~~~~~~~~~.#
+###^^^....~~~~~~~^^^^^%%~~~~~~~~~%%%%%~~~.~~~~~~~~~~~~~~~~~~~~.#
+#~~^^^....%~~~~~~.^^^%%%~~~~~~~~~%%%%%~~~~~~~~~~~~~~~~.~..~~~...
+~~~~^^.%%%%%~~~....^%%%%~~~~~~~~~~%%%%~~~~~~~~~~~~~~~~....%%....
+~~~~~~%%%%%%%......%%%%%~~~~~~~~~~~%%%%~~~#~~~~~~~~~.~.~.%%%...~
+~~~~~~%%%%%%%.....~~%%%~~~~~~~~~~~~~%%%~~###~~~~~~~...%%%%%%%.~~
+~~~~~~%%%%%%~~.%%~~~~~~~~~~~~~~~~~~~~%%%~~#..~~~~~...%%%%%%%%~~~
+~~~~~~%%%%..~~%%%%~~~~~~~~~~~~~~~~~~~%%%~~~..........%%%^^^%%~~~
+~~~~~~~%%...~~%%%%~~~~~~~~~~~~~~~~~~~~~~~~~.........#^%..^^~~~~~
+~~~~~~~~....~~~%%%~~~~~~~~~~~~~~~~~~~~~~~~~~.....~~~^^^....~~~~~
+~~~~~~~~~.##~~~~%%%%~~~~~~~~~~~~~~~~~~~~~~~~~....~~~^^^^....~~~~
+~~~~~~~~~###~~~~~%%%%~~~~~~~~~~~~~~~..~~~~~~~~..~~~~~^^^^...~~~~
+~~~~~~~~~~~~~~~~~%%%~~~~~~~~~~~~~~~~.....~~~~~~~~~~~~##^^..~~~~~