aboutsummaryrefslogtreecommitdiffstats
path: root/data/maps.lua
diff options
context:
space:
mode:
authorEmil A. Overbeck <emil.a.overbeck@gmail.com>2026-07-19 04:19:48 +0200
committerEmil A. Overbeck <emil.a.overbeck@gmail.com>2026-07-19 04:19:48 +0200
commit521b5da83485a956811fc510cba9f139acad8b26 (patch)
tree29b210263300479e9a565af568812c5e707d23f7 /data/maps.lua
parentff85499d5567c36ce63e2d7903d5f872fd9aef1d (diff)
downloadforts_clone-main.tar.gz
forts_clone-main.zip
New maps and map selectormain
Diffstat (limited to 'data/maps.lua')
-rw-r--r--data/maps.lua198
1 files changed, 198 insertions, 0 deletions
diff --git a/data/maps.lua b/data/maps.lua
new file mode 100644
index 0000000..d49d9e6
--- /dev/null
+++ b/data/maps.lua
@@ -0,0 +1,198 @@
+-- Selectable scenarios. The engine loads every entry of the global `Maps` array
+-- and the Dev panel ("Map" section) switches between them at runtime; switching
+-- tears the world down and rebuilds it from the chosen entry. Maps[1] is the
+-- one the game starts on.
+--
+-- Each map is self-contained:
+-- name, description shown in the Dev panel
+-- ground_level height of the ground plane. Terrain is still a flat
+-- half-plane, so this moves the ground up/down but cannot
+-- change its SHAPE (real terrain is M6).
+-- deposits { {x, y}, ... } mines only produce while on one
+-- devices { {type=, x=, y=, team=}, ... } team 0 = player
+-- weapons { {type=, x=, y=}, ... } the player's starting guns
+-- structures { {name=, beams={ {x1,y1,x2,y2,material}, ... }}, ... }
+--
+-- Building rules the beams must respect (see data/materials.lua):
+-- * a beam should be <= 3 units (wood/armour/bg-brace max_length); prebuilt
+-- beams are welded raw and are NOT auto-subdivided
+-- * TRIANGULATE. An un-triangulated strut snaps once it rotates ~30 degrees,
+-- so every bay wants a diagonal or the fort folds up on the first hit
+-- * an endpoint at y == ground_level becomes a pinned foundation; keep other
+-- nodes clear of the ground+0.3 band so they don't pin by accident
+
+Maps = Maps or {}
+
+-- 1. Open ground, a wide firing lane, and a boxy enemy fort with an armour face
+-- turned towards you. The balanced default.
+table.insert(Maps, {
+ name = "Proving Ground",
+ description = "Open lane, boxy enemy fort with an armoured front.",
+ ground_level = 1.0,
+ deposits = { {-24, 1}, {-11, 1}, {23, 1}, {31, 1} },
+ devices = {
+ { type = "reactor", x = -22, y = 2.0, team = 0 },
+ { type = "reactor", x = 27, y = 3.0, team = 1 },
+ },
+ weapons = {
+ { type = "cannon", x = -18, y = 2.6 },
+ { type = "laser", x = -14, y = 2.6 },
+ },
+ structures = {
+ {
+ name = "player deck", -- gun platform; gives recoil something to shove
+ beams = {
+ {-20,1,-20,2,"wood"}, {-18,1,-18,2,"wood"}, {-16,1,-16,2,"wood"},
+ {-14,1,-14,2,"wood"}, {-12,1,-12,2,"wood"},
+ {-20,2,-18,2,"wood"}, {-18,2,-16,2,"wood"},
+ {-16,2,-14,2,"wood"}, {-14,2,-12,2,"wood"},
+ {-20,1,-18,2,"wood"}, {-18,1,-16,2,"wood"},
+ {-16,1,-14,2,"wood"}, {-14,1,-12,2,"wood"},
+ },
+ },
+ {
+ name = "enemy fort",
+ beams = {
+ -- front column facing the player is armour, the rest is wood
+ {25,1,25,3,"armour"}, {25,3,25,5,"armour"},
+ {27,1,27,3,"wood"}, {27,3,27,5,"wood"},
+ {29,1,29,3,"wood"}, {29,3,29,5,"wood"},
+ {25,1,27,1,"wood"}, {27,1,29,1,"wood"},
+ {25,3,27,3,"wood"}, {27,3,29,3,"wood"},
+ {25,5,27,5,"wood"}, {27,5,29,5,"wood"},
+ {25,1,27,3,"wood"}, {27,1,29,3,"wood"},
+ {25,3,27,5,"wood"}, {27,3,29,5,"wood"},
+ },
+ },
+ },
+})
+
+-- 2. A tall armoured tower braced internally with background bracing: shells
+-- pass straight through the bracing, so you have to chew the armour or burn
+-- the bracing out from under it. Vertical fight.
+table.insert(Maps, {
+ name = "Iron Bastion",
+ description = "A two-storey gun emplacement against a walled keep: armoured "
+ .. "outer wall, a bridge back to the tower, bg-brace interior.",
+ ground_level = 1.0,
+ deposits = { {-28, 1}, {-13, 1}, {19, 1}, {34, 1} },
+ devices = {
+ { type = "reactor", x = -26, y = 2.0, team = 0 },
+ { type = "reactor", x = 28, y = 3.0, team = 1 },
+ },
+ weapons = {
+ { type = "cannon", x = -21, y = 5.6 }, -- upper deck
+ { type = "laser", x = -17, y = 3.6 }, -- lower deck
+ },
+ structures = {
+ {
+ name = "player emplacement",
+ beams = {
+ -- lower storey; armour on the RIGHT column, the face the enemy
+ -- actually shoots at
+ {-24,1,-24,3,"wood"}, {-22,1,-22,3,"wood"}, {-20,1,-20,3,"wood"},
+ {-18,1,-18,3,"wood"}, {-16,1,-16,3,"armour"},
+ {-24,3,-22,3,"wood"}, {-22,3,-20,3,"wood"},
+ {-20,3,-18,3,"wood"}, {-18,3,-16,3,"wood"},
+ {-24,1,-22,3,"wood"}, {-22,1,-20,3,"wood"},
+ {-20,1,-18,3,"wood"}, {-18,1,-16,3,"wood"},
+ -- upper storey over the middle bays
+ {-22,3,-22,5,"wood"}, {-20,3,-20,5,"wood"}, {-18,3,-18,5,"wood"},
+ {-22,5,-20,5,"wood"}, {-20,5,-18,5,"wood"},
+ {-22,3,-20,5,"wood"}, {-20,3,-18,5,"wood"},
+ },
+ },
+ {
+ name = "outer wall", -- fully armoured, soaks the first volleys
+ beams = {
+ {22,1,22,3,"armour"}, {22,3,22,5,"armour"},
+ {24,1,24,3,"armour"}, {24,3,24,5,"armour"},
+ {22,1,24,1,"wood"}, {22,3,24,3,"wood"}, {22,5,24,5,"wood"},
+ {22,1,24,3,"wood"}, {22,3,24,5,"wood"},
+ },
+ },
+ {
+ name = "curtain bridge", -- cut this and the wall fights alone
+ beams = {
+ {24,3,26,3,"wood"}, {24,5,26,5,"wood"}, {24,3,26,5,"wood"},
+ },
+ },
+ {
+ name = "the keep",
+ beams = {
+ -- armoured outer face, full height
+ {26,1,26,3,"armour"}, {26,3,26,5,"armour"},
+ {26,5,26,7,"armour"}, {26,7,26,9,"armour"},
+ {28,1,28,3,"wood"}, {28,3,28,5,"wood"},
+ {28,5,28,7,"wood"}, {28,7,28,9,"wood"},
+ {30,1,30,3,"wood"}, {30,3,30,5,"wood"},
+ {30,5,30,7,"wood"}, {30,7,30,9,"wood"},
+ -- floors
+ {26,1,28,1,"wood"}, {28,1,30,1,"wood"},
+ {26,3,28,3,"wood"}, {28,3,30,3,"wood"},
+ {26,5,28,5,"wood"}, {28,5,30,5,"wood"},
+ {26,7,28,7,"wood"}, {28,7,30,7,"wood"},
+ {26,9,28,9,"wood"}, {28,9,30,9,"wood"},
+ -- internal bracing: shells pass through it, fire eats it fast
+ {26,1,28,3,"bgbrace"}, {28,1,30,3,"bgbrace"},
+ {26,3,28,5,"bgbrace"}, {28,3,30,5,"bgbrace"},
+ {26,5,28,7,"bgbrace"}, {28,5,30,7,"bgbrace"},
+ {26,7,28,9,"bgbrace"}, {28,7,30,9,"bgbrace"},
+ },
+ },
+ },
+})
+
+-- 3. Raised ground and forts almost in each other's faces: short flight times,
+-- both sides armoured on the facing wall. A brawl rather than a siege.
+table.insert(Maps, {
+ name = "The Narrows",
+ description = "Raised ground, two three-storey redoubts almost muzzle to "
+ .. "muzzle, armour facing armour. Reactors sit inside the forts.",
+ ground_level = 2.0,
+ deposits = { {-18, 2}, {-4, 2}, {4, 2}, {18, 2} },
+ devices = {
+ { type = "reactor", x = -13, y = 3.0, team = 0 },
+ { type = "reactor", x = 11, y = 3.0, team = 1 },
+ },
+ weapons = {
+ { type = "cannon", x = -12, y = 6.6 }, -- on the roof
+ { type = "laser", x = -10, y = 6.6 },
+ },
+ structures = {
+ {
+ name = "player redoubt", -- armour on the inward (enemy-facing) column
+ beams = {
+ {-14,2,-14,4,"wood"}, {-12,2,-12,4,"wood"},
+ {-10,2,-10,4,"wood"}, {-8,2,-8,4,"armour"},
+ {-14,4,-14,6,"wood"}, {-12,4,-12,6,"wood"},
+ {-10,4,-10,6,"wood"}, {-8,4,-8,6,"armour"},
+ {-14,4,-12,4,"wood"}, {-12,4,-10,4,"wood"}, {-10,4,-8,4,"wood"},
+ {-14,6,-12,6,"wood"}, {-12,6,-10,6,"wood"}, {-10,6,-8,6,"wood"},
+ {-14,2,-12,4,"wood"}, {-12,2,-10,4,"wood"}, {-10,2,-8,4,"wood"},
+ {-14,4,-12,6,"wood"}, {-12,4,-10,6,"wood"}, {-10,4,-8,6,"wood"},
+ },
+ },
+ {
+ name = "enemy redoubt",
+ beams = {
+ {8,2,8,4,"armour"}, {10,2,10,4,"wood"},
+ {12,2,12,4,"wood"}, {14,2,14,4,"wood"},
+ {8,4,8,6,"armour"}, {10,4,10,6,"wood"},
+ {12,4,12,6,"wood"}, {14,4,14,6,"wood"},
+ {8,4,10,4,"wood"}, {10,4,12,4,"wood"}, {12,4,14,4,"wood"},
+ {8,6,10,6,"wood"}, {10,6,12,6,"wood"}, {12,6,14,6,"wood"},
+ {8,2,10,4,"wood"}, {10,2,12,4,"wood"}, {12,2,14,4,"wood"},
+ {8,4,10,6,"wood"}, {10,4,12,6,"wood"}, {12,4,14,6,"wood"},
+ },
+ },
+ },
+})
+
+function IndexOfMap(name)
+ for i, m in ipairs(Maps) do if m.name == name then return i end end
+ return nil
+end
+function FindMap(name)
+ local i = IndexOfMap(name); if i then return Maps[i] end; return nil
+end