World Map Structures
# Modulus Widget
Convert a World r,q
to a 3x9 Tessellation
rTemplate, qTemplate
# Cells
Tessellation Cells
0, 0 City Tier 1 Elixir Marble Crystal
0, 1 Planks Filler
0, 2 Steel Boost
0, 3 City Tier 1 MDust Steel Scrolls
0, 4 Marble Filler
0, 5 Planks Boost
0, 6 City Tier 1 Gems Planks Silk
0, 7 Steel Filler
0, 8 Marble Boost
0, 9 Belongs to downstairs neighbor
1, 0 Crystal Boost
1, 1 City Tier 1 Steel Crystal Elixir
1, 2 Silk Filler
1, 3 Scrolls Boost
1, 4 City Tier 1 Planks Scrolls MDust
1, 5 Crystal Filler
1, 6 Silk Boost
1, 7 City Tier 1 Marble Silk Gems
1, 8 Scrolls Filler
1, 9 Belongs to downstairs neighbor
2, 0 Belongs to upstairs neighbor
2, 1 MDust Filler
2, 2 Elixir Boost
2, 3 City Tier 1 Scrolls Elixir Steel
2, 4 Gems Filler
2, 5 MDust Boost
2, 6 City Tier 1 Silk MDust Planks
2, 7 Elixir Filler
2, 8 Gems Boost
2, 9 City Tier 1 Crystal Gems Marble
# Flying Ducks
Tessellation
The basic building block for the World Map is a staggered 9x3 parallelogram that contains:
9 Cities
9 Resources, each listed twice
Staggered and repeated over and over and over again
Tessellation isn’t the sort of thing that one can describe with words, but it’s visually obvious.
# Template Span
rTemplate = Mod( r, 3)
qTemplate = Mod(q,10)
Because the flat topped hexagonal cells zig-zag vertically, horizontal even/odd pairs will have the same vertical index value, although they “look like” they’re off by half a cell.
The (r.q) indexes for the top and bott0m three cells in the tessellated parallelogram group are:
(0,0) City
(1,0) Crystal
(2,1) Magic Dust
thru
(0,8) Marble
(1,8) Scrolls
(2,9) City
# Browser Console
Browser Console
Your desktop browser has a Developer Tool that allows you to look at the underlying code that controls what you see on your screen. In particular, we can use it to look at the attributes of the various elements on the world map.
In-Game, get ready to use your World Map Icon, which will land on your city when the map opens.
Now press Ctrl+Shift+I or
Menu > More Tools > Developer Tools
Now set up your Browser Console environment for looking at cells on the Elvenar World Map.
Network Tab
Record (Red Circle Square for top window)
Filter for json (Funnel and enter json)
Search for Your Name (Magnifier and Search Sidebar, which may need to be a bit wider.)
Clear the existing data (BOTH Circle Bars)
Now click on your World Map Icon and chase down the r and q values that we will soon plug into the above rqConvert widget.
Then drag the World Map over to an UNDISCOVERED area, plug in the new search Name, and click on their city. Lo and Behold! A neat list of Building Locations!!
But Alas! It’s too good to be true. You can’t get at the data if there’s a lot of it, because the Developer Tools only expect to see a few API calls at a time, and manages the Browser Cache accordingly.
Your own city
Other cities in your discovered Neighborhood
Other cities in your Fellowship
Other cities that have a current contribution to one of your AWs
And probably some more stuff
We’ll eventually isolate the API calls that are related to Building Location, but it’s a low priority task because the In game Move display with the buildings flattened, and the similar display on Elven Architect make it easy to hunt for a building.
An in-game solution, similar to the Summons widget that we already have for Teleported and Awarded buildings, would be VERY nice and would make a LOT of sense as a “click on my building” tab for the Builder’s Hut.
Developer Mode allows you to do a lot of things on the fly, for troubleshooting. In the Browser Console (the lower window) try typing:
———-> console.log(“Hello World!”)
followed by a semi-colon and Enter.
Once you've set up your Developer Environment, and have poked around a bit, open a new tab for ElvenPathways.com/worldmap
Now drag the tabs to show both the Modulus widget and the Browser Console for the game in a split window, and start converting coordinates. Hooray!
# Production
Squarespace, as is typical of most hosting sites, requires all of the "Behind the Curtain" JavaScript code to be placed in a special repository. What you're seeing, when a page is rendered, is HTML lipstick. The bones and muscles are JanaScript or some other advanced language. // <script> // Not really though - this text is HUMAN readable (sort of) // We'd encourage you to read through this code block, // and buff your JavaScript skills. Pay particular attention to the // nested switch code that describes all 3*9+3 = 30 cells in the Template. /* The following chunk of code has been commented out to avoid contamination of the JavaScript repository. {script} // Here's the actual JavaScript code for Elvenar, that's called by the Submit button, // or by using Console.log(rqConvert(r,q)); with your own numbers. let r = -6; // Elvenar Global Horizontal_Index let q = -11; // Elvenar Global Vertical_Index function rqConvert(r,q) { // Find the Template coordinates const rModulus = 3; // The horizontal span of the Template const qModulus = 10; // The vertical span of the Template let rTemplate = 0; // Maps onto the 0,0 Template (for r = -6) let qTemplate = 9; // Maps onto the 0,0 Template (for q = -11) let rqMap= "Result"; // The new results for the Template cell const rqMapReturn = document.getElementById("rqMapReturn"); // Which is where we will actually display the results // Calculate the Modulus Remainder for r and q console.log(r + "," + q + " is the World Coordinate"); rTemplate = ((r % rModulus) + rModulus) % rModulus; qTemplate = ((q % qModulus) + qModulus) % qModulus; console.log(" " + rTemplate + ", " + qTemplate + " is the Template Coordinate"); // switch looks up the related description switch(rTemplate) { // r index for the row case 0: switch(qTemplate) { // q index for the column case 0: rqMap = " 0, 0 City Tier 1 Elixir Marble Crystal"; break; case 1: rqMap = " 0, 1 Planks Filler "; break; case 2: rqMap = " 0, 2 Steel Boost "; break; case 3: rqMap = " 0, 3 City Tier 1 MDust Steel Scrolls"; break; case 4: rqMap = " 0, 4 Marble Filler "; break; case 5: rqMap = " 0, 5 Planks Boost "; break; case 6: rqMap = " 0, 6 City Tier 1 Gems Planks Silk "; break; case 7: rqMap = " 0, 7 Steel Filler "; break; case 8: rqMap = " 0, 8 Marble Boost "; break; case 9: rqMap = " 0, 9 Belongs to downstairs neighbor "; break; default: rqMap = " 0, q Default shouldn't ever happen "; break; } ; break; case 1: switch(qTemplate) { case 0: rqMap = " 1, 0 Crystal Boost "; break; case 1: rqMap = " 1, 1 City Tier 1 Steel Crystal Elixir "; break; case 2: rqMap = " 1, 2 Silk Filler "; break; case 3: rqMap = " 1, 3 Scrolls Boost "; break; case 4: rqMap = " 1, 4 City Tier 1 Planks Scrolls MDust "; break; case 5: rqMap = " 1, 5 Crystal Filler "; break; case 6: rqMap = " 1, 6 Silk Boost "; break; case 7: rqMap = " 1, 7 City Tier 1 Marble Silk Gems "; break; case 8: rqMap = " 1, 8 Scrolls Filler "; break; case 9: rqMap = " 1, 9 Belongs to downstairs neighbor "; break; default: rqMap = " 1, q Default shouldn't ever happen "; break; } ; break; case 2: switch(qTemplate) { case 0: rqMap = " 2, 0 Belongs to upstairs neighbor "; break; case 1: rqMap = " 2, 1 MDust Filler "; break; case 2: rqMap = " 2, 2 Elixir Boost "; break; case 3: rqMap = " 2, 3 City Tier 1 Scrolls Elixir Steel "; break; case 4: rqMap = " 2, 4 Gems Filler "; break; case 5: rqMap = " 2, 5 MDust Boost "; break; case 6: rqMap = " 2, 6 City Tier 1 Silk Dust Planks"; break; case 7: rqMap = " 2, 7 Elixir Filler "; break; case 8: rqMap = " 2, 8 Gems Boost "; break; case 9: rqMap = " 2, 9 City Tier 1 Crystal Gems Marble"; break; default: rqMap = " 2, q Default should never happen "; break; } ; break; case 3: rqMap = " 3, q Doesn't exist "; break; default: rqMap = " r, q Default should never happen"; // NO break; }; // Push the results to the console console.log(rqMap); // Push the results to the HTML page rqMapReturn.innerHTML = rqMap; } // End of the rqConvert() function </script> */
Production JavaScript
# Discovered Neighbors
In the World Map widget on the Desktop version of Elvenar, there’s a very handy list of your Neighbors. If you go total geek, you can use the Chrome Developer tools to trace the list of Neighbors, and you’ll find that the sequence exactly matches the sketch of the Manhattan Distance spiral.
The spiral is used for Immigration, Relocation, Scouting Costs, Provincial Difficulty, and Tournament sequencing, so it’s important, but fortunately there are a lot of well designed popups that do a nice job of guiding your attention, so a vague awareness of the structural details is all that you really need.
The Elvenar Wiki discusses the World map at https://en.wiki.elvenar.com/index.php?title=World_Map#The_World_Map, but the information that’s presented is handwavish. While concentric rings are easy to explain, the devil is in the details. The world map actually uses Manhattan Distances (Taxicab distance) = ( |r|+|q| ). The basic idea is that you have to use the streets. You can’t ignore the terrain.
# Manhattan Distances
# Exercises
Here are some simple JavaScript exercises that will actually work in the Chrome Browser Console (Ctrl+Shift+I) but, if you're the slightest bit interested in programming, there's a starting point that's a lot more fun. >> codeSwing by Jonathan Carter << Click on the link in the Page Footer. // Exercise #1 // Hello World! is the traditional // introduction to any new // programming enviornment. console.log("Hello World!"); // Exercise #2 /* ---------------------------------- Copy Paste or Type these code fragments into the Browser Console now, and once again after you've completed the rest of the exercises. Better yet, just use use codeSwing. JavaScript is case sensitive and weakly typed. Use camelCase for naming, and use the Strict === Equality Operator when things look right, but won't work. At the end of each statement you need either a semicolon or Enter. Get in habit of including the ; Your first pass will have several errors, because the functions and global variables have not yet been defined. This is, by the way, a VERY common programming problem, so pay attention to the various error flags. -----------------------------------*/ <script> console.log("Hello World!"); // 2a baProduct = null; // 2b console.log(baProduct(6, 10)); // 2b g = 234; // 234 2c // 2c f = "234"; // '234' 2c // 2c g === f; // false 2c g == f; // true 2c g = f; // '234' 2c g; // '234' 2c f; // '234' 2c g = +f; // 234 2c f; // '234' 2c g = ++f; // 235 2c f; // 235 2c g = ++f // 236 2c f; // 236 2c f = "234" + "567"; // '234567' 2c g = +f; // 234567 2c </script> // Exercise #3 // Return the product of a and b <script> function baProduct( b, a) { return b * a; }; console.log(baProduct(6, 10)); // Or plug in your own numbers </script> /* Exercise #4 A simple Hello World function, using global variables. The reason for the goofy reverse order, rather than the usual a,b,c i,j,k q,r,s x,y,z order, is because the programmers were thinking (Row,Column), for switching convenience on the World Map, and they continued listing it that way in the Elvenar code. But at least the City Buildings use the normal x,y convention, although those files are obscured most of the time. */ <script> i = "Hello World! "; h = 16; // This is a GotCha // The Result will be 15 g = 5; f = 10; // The console is a very primitive // editor, so enter the entire // function without pressing Enter function simple(g,f) { console.log("A simple function"); h = f + g; return i + " " + h + " times over."; }; simple(g,f); // Or plug in your own numbers // Exercise 5 /* Are you up to a Programming Challenge? 1. Pick any three digit number 2. Concatinate (NOT add) it to itself, so 345345, to obtain a 6 digit number 3. Divide the number by 7 4. Divide the result by 11 5. Divide the result by 13 6. Your original number??? Strange, huh? Fun with Primes :-} */
JavaScript Exercises
# Innogames on GitHub
Innogames on GitHub
Innogames has published a LOT of code on GitHub. They have 132 different repositories for your enjoyment.