<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://wiki.warexpand.com/index.php?action=history&amp;feed=atom&amp;title=Module%3AFortificationStats</id>
	<title>Module:FortificationStats - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.warexpand.com/index.php?action=history&amp;feed=atom&amp;title=Module%3AFortificationStats"/>
	<link rel="alternate" type="text/html" href="https://wiki.warexpand.com/index.php?title=Module:FortificationStats&amp;action=history"/>
	<updated>2026-10-12T07:07:12Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.43.11</generator>
	<entry>
		<id>https://wiki.warexpand.com/index.php?title=Module:FortificationStats&amp;diff=189&amp;oldid=prev</id>
		<title>Warmaninger: Import generated wiki content (units, buildings, fortifications, overview, categories)</title>
		<link rel="alternate" type="text/html" href="https://wiki.warexpand.com/index.php?title=Module:FortificationStats&amp;diff=189&amp;oldid=prev"/>
		<updated>2026-08-21T22:48:51Z</updated>

		<summary type="html">&lt;p&gt;Import generated wiki content (units, buildings, fortifications, overview, categories)&lt;/p&gt;
&lt;table style=&quot;background-color: #fff; color: #202122;&quot; data-mw=&quot;interface&quot;&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;en&quot;&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;← Older revision&lt;/td&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;Revision as of 22:48, 21 August 2026&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l88&quot;&gt;Line 88:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 88:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;end&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;end&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;-- &quot;&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;2–10&lt;/del&gt;%&quot; for the Trade Hub tax band.&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;-- &quot;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;2-10&lt;/ins&gt;%&quot; for the Trade Hub tax band.&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;local function taxBandOf( stats )&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;local function taxBandOf( stats )&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;	local lo, hi = stats.trade_tax_min, stats.trade_tax_max&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;	local lo, hi = stats.trade_tax_min, stats.trade_tax_max&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l95&quot;&gt;Line 95:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 95:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;	end&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;	end&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;	if lo ~= nil and hi ~= nil then&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;	if lo ~= nil and hi ~= nil then&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;		return string.format( &#039;%s&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&amp;amp;ndash;&lt;/del&gt;%s%%&#039;, lo, hi )&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;		return string.format( &#039;%s&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;-&lt;/ins&gt;%s%%&#039;, lo, hi )&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;	end&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;	end&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;	return string.format( &amp;#039;%s%%&amp;#039;, lo or hi )&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;	return string.format( &amp;#039;%s%%&amp;#039;, lo or hi )&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l152&quot;&gt;Line 152:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 152:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;	return table.concat( {&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;	return table.concat( {&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;		&amp;#039;{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;float:right; margin:0 0 1em 1em; min-width:18em&amp;quot;\n&amp;#039;,&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;		&amp;#039;{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;float:right; margin:0 0 1em 1em; min-width:18em&amp;quot;\n&amp;#039;,&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;		string.format( &#039;|+ %s &lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&amp;amp;mdash; &lt;/del&gt;level %d\n&#039;, fort.name, level ),&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;		string.format( &#039;|+ %s &lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;(&lt;/ins&gt;level %d&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;)&lt;/ins&gt;\n&#039;, fort.name, level ),&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;		row( &amp;#039;Kind&amp;#039;, &amp;#039;Country fortification&amp;#039; ),&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;		row( &amp;#039;Kind&amp;#039;, &amp;#039;Country fortification&amp;#039; ),&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;		row( &amp;#039;Max level&amp;#039;, levelsLabel ),&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;		row( &amp;#039;Max level&amp;#039;, levelsLabel ),&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l206&quot;&gt;Line 206:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 206:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;	local out = {&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;	local out = {&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;		&amp;#039;{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:center&amp;quot;\n&amp;#039;,&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;		&amp;#039;{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:center&amp;quot;\n&amp;#039;,&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;		string.format( &#039;|+ %s &lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&amp;amp;mdash; &lt;/del&gt;stats by level\n&#039;, fort.name ),&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;		string.format( &#039;|+ %s&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;: &lt;/ins&gt;stats by level\n&#039;, fort.name ),&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;		&amp;#039;! Stat\n&amp;#039;,&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;		&amp;#039;! Stat\n&amp;#039;,&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;	}&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;	}&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l222&quot;&gt;Line 222:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 222:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;				cells[#cells + 1] = string.format( &amp;#039;| %s\n&amp;#039;, value )&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;				cells[#cells + 1] = string.format( &amp;#039;| %s\n&amp;#039;, value )&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;			else&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;			else&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;				cells[#cells + 1] = &#039;| &lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&amp;amp;mdash;&lt;/del&gt;\n&#039;&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;				cells[#cells + 1] = &#039;| &lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;-&lt;/ins&gt;\n&#039;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;			end&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;			end&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;		end&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;		end&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;

&lt;!-- diff cache key warexpand_wiki:diff:1.41:old-111:rev-189:php=table --&gt;
&lt;/table&gt;</summary>
		<author><name>Warmaninger</name></author>
	</entry>
	<entry>
		<id>https://wiki.warexpand.com/index.php?title=Module:FortificationStats&amp;diff=111&amp;oldid=prev</id>
		<title>Warmaninger: Import generated wiki content (units, buildings, fortifications, overview, categories)</title>
		<link rel="alternate" type="text/html" href="https://wiki.warexpand.com/index.php?title=Module:FortificationStats&amp;diff=111&amp;oldid=prev"/>
		<updated>2026-08-21T22:33:10Z</updated>

		<summary type="html">&lt;p&gt;Import generated wiki content (units, buildings, fortifications, overview, categories)&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;-- Renders fortification statistics from [[Module:Data/Fortifications]].&lt;br /&gt;
--&lt;br /&gt;
-- This module is hand-written, in the same style as Module:UnitStats and&lt;br /&gt;
-- Module:BuildingStats. Module:Data/Fortifications is meant to be generated by&lt;br /&gt;
-- scripts/export-wiki-data.cjs (which only writes under the Module:Data/&lt;br /&gt;
-- prefix), so this file is never overwritten by the export.&lt;br /&gt;
--&lt;br /&gt;
-- Entry points:&lt;br /&gt;
--   infobox  - stat box for ONE level        {{#invoke:FortificationStats|infobox|code=auto_turret|level=1}}&lt;br /&gt;
--   levels   - comparison table, ALL levels  {{#invoke:FortificationStats|levels|code=auto_turret}}&lt;br /&gt;
--&lt;br /&gt;
-- Expected shape of Module:Data/Fortifications (field names follow the game&amp;#039;s&lt;br /&gt;
-- country fortification tier table: attack, defense, durability, range,&lt;br /&gt;
-- detection_chance, trade_tax_min_pct, trade_tax_max_pct, build_time,&lt;br /&gt;
-- required_&amp;lt;resource&amp;gt;, upkeep_&amp;lt;resource&amp;gt;):&lt;br /&gt;
--&lt;br /&gt;
--   return {&lt;br /&gt;
--     auto_turret = {&lt;br /&gt;
--       name      = &amp;#039;Automatic Turret&amp;#039;,&lt;br /&gt;
--       ammo      = &amp;#039;Turret Belts&amp;#039;,            -- optional&lt;br /&gt;
--       max_level = 5,                         -- optional&lt;br /&gt;
--       levels = {&lt;br /&gt;
--         [1] = {&lt;br /&gt;
--           attack        = 10,&lt;br /&gt;
--           defense       = 5,&lt;br /&gt;
--           durability    = 100,&lt;br /&gt;
--           range         = 5,                 -- km, optional&lt;br /&gt;
--           detection     = 0.25,              -- detection_chance, 0..1, optional (Strategic Radar)&lt;br /&gt;
--           trade_tax_min = 2,                 -- trade_tax_min_pct, optional (Trade Hub)&lt;br /&gt;
--           trade_tax_max = 10,                -- trade_tax_max_pct, optional (Trade Hub)&lt;br /&gt;
--           build_time    = &amp;#039;2h&amp;#039;,&lt;br /&gt;
--           cost   = { money = 100, food = 0, metal = 0, concrete = 50, petrol = 0, uranium = 0 },&lt;br /&gt;
--           upkeep = { money = 5, metal = 0, concrete = 0, petrol = 0, uranium = 0 },&lt;br /&gt;
--         },&lt;br /&gt;
--         [2] = { ... },&lt;br /&gt;
--       },&lt;br /&gt;
--     },&lt;br /&gt;
--   }&lt;br /&gt;
&lt;br /&gt;
local p = {}&lt;br /&gt;
&lt;br /&gt;
-- Module:Data/Fortifications is absent until the export has run; fail soft&lt;br /&gt;
-- instead of printing a Lua error on every fortification page.&lt;br /&gt;
local loaded, data = pcall( mw.loadData, &amp;#039;Module:Data/Fortifications&amp;#039; )&lt;br /&gt;
if not loaded then&lt;br /&gt;
	data = nil&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local PENDING = &amp;quot;&amp;#039;&amp;#039;Stats not yet available.&amp;#039;&amp;#039;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
local RESOURCES = { &amp;#039;money&amp;#039;, &amp;#039;food&amp;#039;, &amp;#039;metal&amp;#039;, &amp;#039;concrete&amp;#039;, &amp;#039;petrol&amp;#039;, &amp;#039;uranium&amp;#039; }&lt;br /&gt;
&lt;br /&gt;
-- &amp;quot;100 money, 50 concrete&amp;quot;, or &amp;quot;free&amp;quot; when nothing is required.&lt;br /&gt;
local function formatResources( bundle )&lt;br /&gt;
	if not bundle then&lt;br /&gt;
		return nil&lt;br /&gt;
	end&lt;br /&gt;
	local parts = {}&lt;br /&gt;
	for _, name in ipairs( RESOURCES ) do&lt;br /&gt;
		local amount = bundle[name]&lt;br /&gt;
		if amount and amount &amp;gt; 0 then&lt;br /&gt;
			parts[#parts + 1] = string.format( &amp;#039;%s %s&amp;#039;, amount, name )&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	if #parts == 0 then&lt;br /&gt;
		return &amp;#039;free&amp;#039;&lt;br /&gt;
	end&lt;br /&gt;
	return table.concat( parts, &amp;#039;, &amp;#039; )&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Emits nothing at all for a missing value, so empty rows never show up.&lt;br /&gt;
local function row( label, value )&lt;br /&gt;
	if value == nil or value == &amp;#039;&amp;#039; then&lt;br /&gt;
		return &amp;#039;&amp;#039;&lt;br /&gt;
	end&lt;br /&gt;
	return string.format( &amp;#039;|-\n! %s\n| %s\n&amp;#039;, label, value )&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- &amp;quot;25%&amp;quot; from a 0..1 chance (also accepts a value already in percent).&lt;br /&gt;
local function percentOf( value )&lt;br /&gt;
	if value == nil then&lt;br /&gt;
		return nil&lt;br /&gt;
	end&lt;br /&gt;
	if value &amp;lt;= 1 then&lt;br /&gt;
		value = value * 100&lt;br /&gt;
	end&lt;br /&gt;
	return string.format( &amp;#039;%d%%&amp;#039;, math.floor( value + 0.5 ) )&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- &amp;quot;2–10%&amp;quot; for the Trade Hub tax band.&lt;br /&gt;
local function taxBandOf( stats )&lt;br /&gt;
	local lo, hi = stats.trade_tax_min, stats.trade_tax_max&lt;br /&gt;
	if lo == nil and hi == nil then&lt;br /&gt;
		return nil&lt;br /&gt;
	end&lt;br /&gt;
	if lo ~= nil and hi ~= nil then&lt;br /&gt;
		return string.format( &amp;#039;%s&amp;amp;ndash;%s%%&amp;#039;, lo, hi )&lt;br /&gt;
	end&lt;br /&gt;
	return string.format( &amp;#039;%s%%&amp;#039;, lo or hi )&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Level numbers of a fortification, sorted ascending. Works on mw.loadData&lt;br /&gt;
-- tables (which support pairs() but not the # operator) and tolerates gaps.&lt;br /&gt;
local function levelNumbers( fort )&lt;br /&gt;
	local nums = {}&lt;br /&gt;
	for key in pairs( fort.levels or {} ) do&lt;br /&gt;
		local n = tonumber( key )&lt;br /&gt;
		if n then&lt;br /&gt;
			nums[#nums + 1] = n&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	table.sort( nums )&lt;br /&gt;
	return nums&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function unknownFort( code )&lt;br /&gt;
	return string.format(&lt;br /&gt;
		&amp;#039;&amp;lt;strong class=&amp;quot;error&amp;quot;&amp;gt;Unknown fortification code: %s&amp;lt;/strong&amp;gt;&amp;#039;,&lt;br /&gt;
		tostring( code )&lt;br /&gt;
	)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--- Stat box for one level of one fortification.&lt;br /&gt;
-- Usage: {{#invoke:FortificationStats|infobox|code=auto_turret|level=1}}&lt;br /&gt;
function p.infobox( frame )&lt;br /&gt;
	local code = frame.args.code&lt;br /&gt;
	local level = tonumber( frame.args.level ) or 1&lt;br /&gt;
&lt;br /&gt;
	if not data then&lt;br /&gt;
		return PENDING&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local fort = data[code]&lt;br /&gt;
	if not fort then&lt;br /&gt;
		return unknownFort( code )&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local stats = fort.levels and fort.levels[level]&lt;br /&gt;
	if not stats then&lt;br /&gt;
		return string.format(&lt;br /&gt;
			&amp;#039;&amp;lt;strong class=&amp;quot;error&amp;quot;&amp;gt;%s has no level %s&amp;lt;/strong&amp;gt;&amp;#039;,&lt;br /&gt;
			fort.name, tostring( level )&lt;br /&gt;
		)&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local maxLevel = fort.max_level or #levelNumbers( fort )&lt;br /&gt;
	local levelsLabel = nil&lt;br /&gt;
	if maxLevel and maxLevel &amp;gt; 1 then&lt;br /&gt;
		levelsLabel = string.format( &amp;#039;%d (see [[#Stats|all levels]])&amp;#039;, maxLevel )&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	return table.concat( {&lt;br /&gt;
		&amp;#039;{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;float:right; margin:0 0 1em 1em; min-width:18em&amp;quot;\n&amp;#039;,&lt;br /&gt;
		string.format( &amp;#039;|+ %s &amp;amp;mdash; level %d\n&amp;#039;, fort.name, level ),&lt;br /&gt;
		row( &amp;#039;Kind&amp;#039;, &amp;#039;Country fortification&amp;#039; ),&lt;br /&gt;
		row( &amp;#039;Max level&amp;#039;, levelsLabel ),&lt;br /&gt;
		row( &amp;#039;Attack&amp;#039;, stats.attack ),&lt;br /&gt;
		row( &amp;#039;Defense&amp;#039;, stats.defense ),&lt;br /&gt;
		row( &amp;#039;Durability&amp;#039;, stats.durability ),&lt;br /&gt;
		row( &amp;#039;Range&amp;#039;, stats.range ),&lt;br /&gt;
		row( &amp;#039;Detection chance&amp;#039;, percentOf( stats.detection ) ),&lt;br /&gt;
		row( &amp;#039;Trade tax&amp;#039;, taxBandOf( stats ) ),&lt;br /&gt;
		row( &amp;#039;Ammunition&amp;#039;, fort.ammo ),&lt;br /&gt;
		row( &amp;#039;Build time&amp;#039;, stats.build_time ),&lt;br /&gt;
		row( &amp;#039;Cost&amp;#039;, formatResources( stats.cost ) ),&lt;br /&gt;
		row( &amp;#039;Upkeep&amp;#039;, formatResources( stats.upkeep ) ),&lt;br /&gt;
		&amp;#039;|}&amp;#039;,&lt;br /&gt;
	} )&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Rows of the level comparison table: label + accessor. A row is skipped&lt;br /&gt;
-- entirely when no level has a value for it.&lt;br /&gt;
local LEVEL_ROWS = {&lt;br /&gt;
	{ &amp;#039;Attack&amp;#039;,           function( s ) return s.attack end },&lt;br /&gt;
	{ &amp;#039;Defense&amp;#039;,          function( s ) return s.defense end },&lt;br /&gt;
	{ &amp;#039;Durability&amp;#039;,       function( s ) return s.durability end },&lt;br /&gt;
	{ &amp;#039;Range&amp;#039;,            function( s ) return s.range end },&lt;br /&gt;
	{ &amp;#039;Detection chance&amp;#039;, function( s ) return percentOf( s.detection ) end },&lt;br /&gt;
	{ &amp;#039;Trade tax&amp;#039;,        taxBandOf },&lt;br /&gt;
	{ &amp;#039;Build time&amp;#039;,       function( s ) return s.build_time end },&lt;br /&gt;
	{ &amp;#039;Cost&amp;#039;,             function( s ) return formatResources( s.cost ) end },&lt;br /&gt;
	{ &amp;#039;Upkeep&amp;#039;,           function( s ) return formatResources( s.upkeep ) end },&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
--- Comparison table of every level of one fortification (levels as columns).&lt;br /&gt;
-- Usage: {{#invoke:FortificationStats|levels|code=auto_turret}}&lt;br /&gt;
function p.levels( frame )&lt;br /&gt;
	local code = frame.args.code&lt;br /&gt;
&lt;br /&gt;
	if not data then&lt;br /&gt;
		return PENDING&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local fort = data[code]&lt;br /&gt;
	if not fort then&lt;br /&gt;
		return unknownFort( code )&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local nums = levelNumbers( fort )&lt;br /&gt;
	if #nums == 0 then&lt;br /&gt;
		return string.format(&lt;br /&gt;
			&amp;#039;&amp;lt;strong class=&amp;quot;error&amp;quot;&amp;gt;%s has no level data&amp;lt;/strong&amp;gt;&amp;#039;, fort.name&lt;br /&gt;
		)&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local out = {&lt;br /&gt;
		&amp;#039;{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:center&amp;quot;\n&amp;#039;,&lt;br /&gt;
		string.format( &amp;#039;|+ %s &amp;amp;mdash; stats by level\n&amp;#039;, fort.name ),&lt;br /&gt;
		&amp;#039;! Stat\n&amp;#039;,&lt;br /&gt;
	}&lt;br /&gt;
	for _, n in ipairs( nums ) do&lt;br /&gt;
		out[#out + 1] = string.format( &amp;#039;! Level %d\n&amp;#039;, n )&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	for _, def in ipairs( LEVEL_ROWS ) do&lt;br /&gt;
		local label, get = def[1], def[2]&lt;br /&gt;
		local cells, any = {}, false&lt;br /&gt;
		for _, n in ipairs( nums ) do&lt;br /&gt;
			local value = get( fort.levels[n] )&lt;br /&gt;
			if value ~= nil and value ~= &amp;#039;&amp;#039; then&lt;br /&gt;
				any = true&lt;br /&gt;
				cells[#cells + 1] = string.format( &amp;#039;| %s\n&amp;#039;, value )&lt;br /&gt;
			else&lt;br /&gt;
				cells[#cells + 1] = &amp;#039;| &amp;amp;mdash;\n&amp;#039;&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
		if any then&lt;br /&gt;
			out[#out + 1] = string.format( &amp;#039;|-\n! style=&amp;quot;text-align:left&amp;quot; | %s\n&amp;#039;, label )&lt;br /&gt;
			out[#out + 1] = table.concat( cells )&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	out[#out + 1] = &amp;#039;|}&amp;#039;&lt;br /&gt;
	return table.concat( out )&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
return p&lt;/div&gt;</summary>
		<author><name>Warmaninger</name></author>
	</entry>
</feed>