summaryrefslogtreecommitdiff
path: root/1mb/data.js
diff options
context:
space:
mode:
Diffstat (limited to '1mb/data.js')
-rw-r--r--1mb/data.js1255
1 files changed, 1255 insertions, 0 deletions
diff --git a/1mb/data.js b/1mb/data.js
new file mode 100644
index 0000000..1a9e32f
--- /dev/null
+++ b/1mb/data.js
@@ -0,0 +1,1255 @@
+// Game data — edit this file to mod the run (floors, relics, hazards, balance).
+// Loaded before the engine in index.html.
+const W=12,H=12,FUEL=16
+const BEAST_CALM_RADIUS=4,BEAST_ENRAGED_SPEED=2,TORCH_DRAIN_BASE=1,TORCH_DRAIN_HAZARD=2,RELIC_SLOTS_LOW=2,RELIC_SLOTS_MID=3,RELIC_SLOTS_HIGH=4,RELIC_SLOTS_RICH_BONUS=1
+const P={g:[5,2],b:[2,2],e:[2,9],h:[2,9],p:[2,2],i:[2,2],c:[2,2],v:[2,2],d:[2,2]}
+const PITS=[[
+"############",
+"#OOOOOOOOOO#",
+"#O....F...O#",
+"#O...OO...O#",
+"#O........O#",
+"#O....>...O#",
+"#O........O#",
+"#O...OO...O#",
+"#O........O#",
+"#O........O#",
+"#OOOOOOOOOO#",
+"############"],[
+"############",
+"#OOOOOOOOOO#",
+"#O.......OO#",
+"#O.OOOOO..O#",
+"#O.......OO#",
+"#O..>.....O#",
+"#O....F...O#",
+"#O..OOOOO.O#",
+"#O........O#",
+"#O........O#",
+"#OOOOOOOOOO#",
+"############"],[
+"############",
+"#OOOOOOOOOO#",
+"#O........O#",
+"#O..OO....O#",
+"#O........O#",
+"#OF....>..O#",
+"#O....OO..O#",
+"#O........O#",
+"#O..OO....O#",
+"#O........O#",
+"#OOOOOOOOOO#",
+"############"]]
+const IDOLS=[[
+"############",
+"#..........#",
+"#...ggg....#",
+"#...gIg....#",
+"#...ggg....#",
+"#..........#",
+"#..........#",
+"#..........#",
+"#..........#",
+"#..........#",
+"#....>.....#",
+"############"],[
+"############",
+"#..........#",
+"#....gg....#",
+"#...gIg....#",
+"#....ggg...#",
+"#..........#",
+"#..........#",
+"#..........#",
+"#..........#",
+"#..........#",
+"#....>.....#",
+"############"],[
+"############",
+"#..........#",
+"#...gg.....#",
+"#...gIgg...#",
+"#.....gg...#",
+"#..........#",
+"#..........#",
+"#..........#",
+"#..........#",
+"#..........#",
+"#....>.....#",
+"############"]]
+const IDOLS2=[[
+"############",
+"#..........#",
+"#..ggg.....#",
+"#..gIgg....#",
+"#....gg....#",
+"#..........#",
+"#.....#....#",
+"#..........#",
+"#..........#",
+"#..........#",
+"#...>......#",
+"############"],[
+"############",
+"#..........#",
+"#....ggg...#",
+"#...ggIg...#",
+"#....gg....#",
+"#..........#",
+"#..........#",
+"#....#.....#",
+"#..........#",
+"#..........#",
+"#.....>....#",
+"############"],[
+"############",
+"#..........#",
+"#...gg.....#",
+"#..ggIg....#",
+"#...gg.....#",
+"#..........#",
+"#..........#",
+"#.....#....#",
+"#..........#",
+"#..........#",
+"#....>.....#",
+"############"]]
+const CRACKS=[[
+"############",
+"#..........#",
+"#.####.....#",
+"#....#.....#",
+"#..x.>.....#",
+"#....#.....#",
+"#....#.....#",
+"#..........#",
+"#..........#",
+"#..........#",
+"#..........#",
+"############"],[
+"############",
+"#..........#",
+"#.....####.#",
+"#.....#....#",
+"#.....#....#",
+"#...x.>....#",
+"#.....#....#",
+"#.....####.#",
+"#..........#",
+"#..........#",
+"#..........#",
+"############"],[
+"############",
+"#..........#",
+"#..######..#",
+"#.......#..#",
+"#...x...#..#",
+"#....>..#..#",
+"#.......#..#",
+"#..######..#",
+"#..........#",
+"#..........#",
+"#..........#",
+"############"]]
+const HALLS=[[
+"############",
+"#..........#",
+"#..a.......#",
+"#......b...#",
+"#..........#",
+"#....c.....#",
+"#......d...#",
+"#..........#",
+"#....F.....#",
+"#....>.....#",
+"#..........#",
+"############"],[
+"############",
+"#..........#",
+"#......b...#",
+"#..........#",
+"#..a.......#",
+"#..........#",
+"#....c..d..#",
+"#..........#",
+"#..F.>.....#",
+"#..........#",
+"#..........#",
+"############"],[
+"############",
+"#..........#",
+"#..a....b..#",
+"#..........#",
+"#..........#",
+"#....c..F..#",
+"#..........#",
+"#......d...#",
+"#..........#",
+"#....>.....#",
+"#..........#",
+"############"]]
+const ESCAPES=[[
+"############",
+"#..........#",
+"#..........#",
+"#..........#",
+"#..........#",
+"#....>.....#",
+"#..........#",
+"#..........#",
+"#..........#",
+"#..........#",
+"#..........#",
+"############"],[
+"############",
+"#..........#",
+"#..........#",
+"#...##.....#",
+"#......>...#",
+"#..........#",
+"#.....##...#",
+"#..........#",
+"#..........#",
+"#..........#",
+"#..........#",
+"############"],[
+"############",
+"#..........#",
+"#....##....#",
+"#..........#",
+"#..........#",
+"#..>.......#",
+"#.......##.#",
+"#..........#",
+"#..........#",
+"#..........#",
+"#..........#",
+"############"]]
+const BEASTS=[[10,8],[9,7]]
+const PITS2=[[
+"############",
+"#OOOOOOOOOO#",
+"#O..FOOO..O#",
+"#O...OO...O#",
+"#O........O#",
+"#O...O>O..O#",
+"#O........O#",
+"#O...OO...O#",
+"#O..OOOO..O#",
+"#O........O#",
+"#OOOOOOOOOO#",
+"############"],[
+"############",
+"#OOOOOOOOOO#",
+"#O......OOO#",
+"#O.OOOOO..O#",
+"#O....O...O#",
+"#O..O>O...O#",
+"#O....F...O#",
+"#O..OOOOO.O#",
+"#O....O...O#",
+"#O........O#",
+"#OOOOOOOOOO#",
+"############"],[
+"############",
+"#OOOOOOOOOO#",
+"#O....O...O#",
+"#O..OOO...O#",
+"#O........O#",
+"#OF..O.>..O#",
+"#O....OOO.O#",
+"#O........O#",
+"#O..OOO...O#",
+"#O....O...O#",
+"#OOOOOOOOOO#",
+"############"],[
+"############",
+"#OOOOOOOOOO#",
+"#O..F.....O#",
+"#O.OOOO...O#",
+"#O.....O..O#",
+"#O..>.OO..O#",
+"#O.....O..O#",
+"#O...OOOO.O#",
+"#O........O#",
+"#O........O#",
+"#OOOOOOOOOO#",
+"############"]]
+const CRACKS2=[[
+"############",
+"#.....x....#",
+"#.#####....#",
+"#....##....#",
+"#..x.>#....#",
+"#....##....#",
+"#....##....#",
+"#.....x....#",
+"#..........#",
+"#..........#",
+"#..........#",
+"############"],[
+"############",
+"#....x.....#",
+"#.....####.#",
+"#....##....#",
+"#....##....#",
+"#...x.>....#",
+"#....##....#",
+"#.....####.#",
+"#....x.....#",
+"#..........#",
+"#..........#",
+"############"],[
+"############",
+"#....x.....#",
+"#..######..#",
+"#.... ..#..#",
+"#...x...#..#",
+"#..x.>..#..#",
+"#.......#..#",
+"#..######..#",
+"#....x.....#",
+"#..........#",
+"#..........#",
+"############"]].map(m=>m.map(r=>r.replace(/ /g,".")))
+const HALLS2=[[
+"############",
+"#..........#",
+"#..a...b...#",
+"#..........#",
+"#....F.....#",
+"#....c.....#",
+"#......d...#",
+"#..........#",
+"#....>.....#",
+"#..........#",
+"#..........#",
+"############"],[
+"############",
+"#..........#",
+"#....b.....#",
+"#..a.......#",
+"#....F.....#",
+"#....c..d..#",
+"#..........#",
+"#....>.....#",
+"#..........#",
+"#..........#",
+"#..........#",
+"############"],[
+"############",
+"#..........#",
+"#..a....b..#",
+"#....F.....#",
+"#..........#",
+"#....c.....#",
+"#......d...#",
+"#..........#",
+"#....>.....#",
+"#..........#",
+"#..........#",
+"############"]]
+const ESCAPES2=[[
+"############",
+"#....##....#",
+"#..........#",
+"#..........#",
+"#...>......#",
+"#..........#",
+"#..##......#",
+"#..........#",
+"#......##..#",
+"#..........#",
+"#..........#",
+"############"],[
+"############",
+"#..........#",
+"#...##.....#",
+"#..........#",
+"#..>.......#",
+"#..........#",
+"#.....##...#",
+"#..........#",
+"#..........#",
+"#..........#",
+"#..........#",
+"############"],[
+"############",
+"#..........#",
+"#..##......#",
+"#..........#",
+"#..>....##.#",
+"#..........#",
+"#......##..#",
+"#..........#",
+"#..........#",
+"#..........#",
+"#..........#",
+"############"]]
+const BEASTS2=[[9,8],[9,7],[10,7]]
+const PITS3=[[
+"############",
+"#OOOOOOOOOO#",
+"#O..SFOO..O#",
+"#O...OO...O#",
+"#O........O#",
+"#O...O>O..O#",
+"#O........O#",
+"#O...OO...O#",
+"#O..OOOO..O#",
+"#O........O#",
+"#OOOOOOOOOO#",
+"############"],[
+"############",
+"#OOOOOOOOOO#",
+"#O.....SOOO#",
+"#O.OOOOO..O#",
+"#O....O...O#",
+"#O..O>O...O#",
+"#O....F...O#",
+"#O..OOOOO.O#",
+"#O....O...O#",
+"#O........O#",
+"#OOOOOOOOOO#",
+"############"],[
+"############",
+"#OOOOOOOOOO#",
+"#O....O...O#",
+"#O..OOO...O#",
+"#O....S...O#",
+"#OF..O.>..O#",
+"#O....OOO.O#",
+"#O........O#",
+"#O..OOO...O#",
+"#O....O...O#",
+"#OOOOOOOOOO#",
+"############"],[
+"############",
+"#OOOOOOOOOO#",
+"#O..S.O...O#",
+"#O..OOO...O#",
+"#O........O#",
+"#O...O.>..O#",
+"#O....OOO.O#",
+"#O....F...O#",
+"#O..OOO...O#",
+"#O....O...O#",
+"#OOOOOOOOOO#",
+"############"]]
+const IDOLS3=[[
+"############",
+"#..........#",
+"#..ggg.....#",
+"#..gISg....#",
+"#....gg....#",
+"#..........#",
+"#.....#....#",
+"#..........#",
+"#..........#",
+"#..........#",
+"#...>......#",
+"############"],[
+"############",
+"#..........#",
+"#....ggg...#",
+"#...gSIg...#",
+"#....gg....#",
+"#..........#",
+"#..........#",
+"#....#.....#",
+"#..........#",
+"#..........#",
+"#.....>....#",
+"############"],[
+"############",
+"#..........#",
+"#...gg.....#",
+"#..gSIg....#",
+"#...gg.....#",
+"#..........#",
+"#..........#",
+"#.....#....#",
+"#..........#",
+"#..........#",
+"#....>.....#",
+"############"]]
+const CRACKS3=[[
+"############",
+"#....Sx....#",
+"#.#####....#",
+"#....##....#",
+"#..x.>#....#",
+"#....##....#",
+"#....##....#",
+"#.....x....#",
+"#..........#",
+"#..........#",
+"#..........#",
+"############"],[
+"############",
+"#....x.....#",
+"#...S.####.#",
+"#....##....#",
+"#....##....#",
+"#...x.>....#",
+"#....##....#",
+"#.....####.#",
+"#....x.....#",
+"#..........#",
+"#..........#",
+"############"],[
+"############",
+"#....x.....#",
+"#..######..#",
+"#....S..#..#",
+"#...x...#..#",
+"#..x.>..#..#",
+"#.......#..#",
+"#..######..#",
+"#....x.....#",
+"#..........#",
+"#..........#",
+"############"]]
+const HALLS3=[[
+"############",
+"#..........#",
+"#..a..S.b..#",
+"#..........#",
+"#....F.....#",
+"#....c.....#",
+"#......d...#",
+"#..........#",
+"#....>.....#",
+"#..........#",
+"#..........#",
+"############"],[
+"############",
+"#..........#",
+"#....b..S..#",
+"#..a.......#",
+"#....F.....#",
+"#....c..d..#",
+"#..........#",
+"#....>.....#",
+"#..........#",
+"#..........#",
+"#..........#",
+"############"],[
+"############",
+"#..........#",
+"#..a....b..#",
+"#....F..S..#",
+"#..........#",
+"#....c.....#",
+"#......d...#",
+"#..........#",
+"#....>.....#",
+"#..........#",
+"#..........#",
+"############"],[
+"############",
+"#..........#",
+"#..a..S.b..#",
+"#....F.....#",
+"#..........#",
+"#....c.....#",
+"#......d...#",
+"#..........#",
+"#....>..F..#",
+"#..........#",
+"#..........#",
+"############"]]
+const ESCAPES3=[[
+"############",
+"#....##....#",
+"#..........#",
+"#....S.....#",
+"#...>......#",
+"#..........#",
+"#..##......#",
+"#..........#",
+"#......##..#",
+"#..........#",
+"#..........#",
+"############"],[
+"############",
+"#..........#",
+"#...##.....#",
+"#....S.....#",
+"#....>.....#",
+"#..........#",
+"#.....##...#",
+"#..........#",
+"#..##......#",
+"#..........#",
+"#..........#",
+"############"],[
+"############",
+"#..........#",
+"#..##......#",
+"#....S.....#",
+"#..>....##.#",
+"#..........#",
+"#......##..#",
+"#..........#",
+"#..........#",
+"#..........#",
+"#..........#",
+"############"],[
+"############",
+"#....##....#",
+"#..........#",
+"#..S.......#",
+"#....>.....#",
+"#..........#",
+"#..##..S...#",
+"#..........#",
+"#......##..#",
+"#..........#",
+"#..........#",
+"############"]]
+const BEASTS3=[[9,8],[9,7],[9,6],[10,7]]
+const ESCAPES4=[[
+"############",
+"#....##....#",
+"#....S.....#",
+"#..........#",
+"#...>......#",
+"#..........#",
+"#..##......#",
+"#......S...#",
+"#......##..#",
+"#..........#",
+"#..........#",
+"############"],[
+"############",
+"#..........#",
+"#...##.....#",
+"#....S.....#",
+"#..>.......#",
+"#..........#",
+"#.....##...#",
+"#.....S....#",
+"#..........#",
+"#..........#",
+"#..........#",
+"############"],[
+"############",
+"#..........#",
+"#..##......#",
+"#....S.....#",
+"#..>....##.#",
+"#..........#",
+"#......##..#",
+"#.....S....#",
+"#..........#",
+"#..........#",
+"#..........#",
+"############"],[
+"############",
+"#....##....#",
+"#..........#",
+"#..S.......#",
+"#....>.....#",
+"#..........#",
+"#..##..S...#",
+"#..........#",
+"#......##..#",
+"#..........#",
+"#..........#",
+"############"]]
+const BEASTS4=[[9,8],[10,8],[9,7],[10,7]]
+const PITS4=[[
+"############",
+"#OOOOOOOOOO#",
+"#O..SFOO..O#",
+"#O.O.OO...O#",
+"#O........O#",
+"#O..OO>O..O#",
+"#O........O#",
+"#O...OO...O#",
+"#O..OOOO..O#",
+"#O........O#",
+"#OOOOOOOOOO#",
+"############"],[
+"############",
+"#OOOOOOOOOO#",
+"#O....SO..O#",
+"#O.OOOOO..O#",
+"#O....O...O#",
+"#O..O>O...O#",
+"#O....F...O#",
+"#O..OOOOO.O#",
+"#O....O...O#",
+"#O........O#",
+"#OOOOOOOOOO#",
+"############"],[
+"############",
+"#OOOOOOOOOO#",
+"#O....O...O#",
+"#O..OOO...O#",
+"#O....S...O#",
+"#OF..O.>..O#",
+"#O....OOO.O#",
+"#O........O#",
+"#O..OOO...O#",
+"#O....O...O#",
+"#OOOOOOOOOO#",
+"############"],[
+"############",
+"#OOOOOOOOOO#",
+"#O..F.O...O#",
+"#O..OOO...O#",
+"#O....S...O#",
+"#O...O.>..O#",
+"#O....OOO.O#",
+"#O........O#",
+"#O..OOO...O#",
+"#O....O...O#",
+"#OOOOOOOOOO#",
+"############"]]
+const IDOLS4=[[
+"############",
+"#..........#",
+"#..ggg.....#",
+"#..gISg....#",
+"#...Sgg....#",
+"#..........#",
+"#.....#....#",
+"#..........#",
+"#..........#",
+"#..........#",
+"#...>......#",
+"############"],[
+"############",
+"#..........#",
+"#....ggg...#",
+"#...gSIg...#",
+"#....gg....#",
+"#....S.....#",
+"#..........#",
+"#....#.....#",
+"#..........#",
+"#..........#",
+"#.....>....#",
+"############"],[
+"############",
+"#..........#",
+"#...gg.....#",
+"#..gSIg....#",
+"#...gg..S..#",
+"#..........#",
+"#..........#",
+"#.....#....#",
+"#..........#",
+"#..........#",
+"#....>.....#",
+"############"]]
+const CRACKS4=[[
+"############",
+"#....Sx....#",
+"#.#####....#",
+"#....##....#",
+"#..x.>#....#",
+"#....##....#",
+"#....##....#",
+"#..x.......#",
+"#..........#",
+"#..........#",
+"#..........#",
+"############"],[
+"############",
+"#....x.....#",
+"#...S.####.#",
+"#....##....#",
+"#....##....#",
+"#..xx.>....#",
+"#....##....#",
+"#.....####.#",
+"#....x.....#",
+"#..........#",
+"#..........#",
+"############"],[
+"############",
+"#....x.....#",
+"#..######..#",
+"#....S..#..#",
+"#...x...#..#",
+"#..x.>..#..#",
+"#...x...#..#",
+"#..######..#",
+"#....x.....#",
+"#..........#",
+"#..........#",
+"############"],[
+"############",
+"#..S.x.....#",
+"#..######..#",
+"#.......#..#",
+"#..xx...#..#",
+"#....>..#..#",
+"#.......#..#",
+"#..######..#",
+"#....x.....#",
+"#..........#",
+"#..........#",
+"############"]]
+const HALLS4=[[
+"############",
+"#..........#",
+"#..a..S.b..#",
+"#..........#",
+"#....F.....#",
+"#....c.....#",
+"#......d...#",
+"#.....S....#",
+"#....>.....#",
+"#..........#",
+"#..........#",
+"############"],[
+"############",
+"#..........#",
+"#....b..S..#",
+"#..a.......#",
+"#....F.....#",
+"#....c..d..#",
+"#.....S....#",
+"#....>.....#",
+"#..........#",
+"#..........#",
+"#..........#",
+"############"],[
+"############",
+"#..........#",
+"#..a....b..#",
+"#....F..S..#",
+"#..........#",
+"#....c.....#",
+"#......d...#",
+"#.....S....#",
+"#....>.....#",
+"#..........#",
+"#..........#",
+"############"],[
+"############",
+"#..........#",
+"#..a..S.b..#",
+"#....F.....#",
+"#..........#",
+"#....c.....#",
+"#...S..d...#",
+"#..........#",
+"#....>..F..#",
+"#..........#",
+"#..........#",
+"############"]]
+const ESCAPES5=[[
+"############",
+"#....##....#",
+"#....S.....#",
+"#..........#",
+"#...>......#",
+"#..........#",
+"#..##......#",
+"#..........#",
+"#......##..#",
+"#....S.....#",
+"#..........#",
+"############"],[
+"############",
+"#..........#",
+"#...##.....#",
+"#....S.....#",
+"#..>.......#",
+"#..........#",
+"#.....##...#",
+"#....S.....#",
+"#..........#",
+"#..........#",
+"#..........#",
+"############"],[
+"############",
+"#..........#",
+"#..##......#",
+"#....S.....#",
+"#..>....##.#",
+"#..........#",
+"#......##..#",
+"#....S.....#",
+"#..........#",
+"#..........#",
+"#..........#",
+"############"],[
+"############",
+"#....##....#",
+"#..........#",
+"#..S.......#",
+"#....>.....#",
+"#..........#",
+"#..##..S...#",
+"#..........#",
+"#......##..#",
+"#....S.....#",
+"#..........#",
+"############"]]
+const BEASTS5=[[10,8],[10,7],[9,7],[9,6]]
+const ESCAPES6=[[
+"############",
+"#....##....#",
+"#....S.....#",
+"#..........#",
+"#...>......#",
+"#....S.....#",
+"#..##......#",
+"#......S...#",
+"#......##..#",
+"#..........#",
+"#..........#",
+"############"],[
+"############",
+"#..........#",
+"#...##.....#",
+"#....S.....#",
+"#..>.......#",
+"#.....S....#",
+"#.....##...#",
+"#.....S....#",
+"#..........#",
+"#..........#",
+"#..........#",
+"############"],[
+"############",
+"#..........#",
+"#..##......#",
+"#....S.....#",
+"#..>....##.#",
+"#.....S....#",
+"#......##..#",
+"#.....S....#",
+"#..........#",
+"#..........#",
+"#..........#",
+"############"],[
+"############",
+"#....##....#",
+"#....S.....#",
+"#..S.......#",
+"#....>.....#",
+"#..........#",
+"#..##..S...#",
+"#..........#",
+"#......##..#",
+"#..........#",
+"#..........#",
+"############"]]
+const BEASTS6=[[10,8],[10,7],[9,7],[10,6]]
+const LEVEL_ORDER=[1,2,3,4,5,6]
+const LEVEL_ARCS={1:"foundation",2:"pressure",3:"ward",4:"hunt",5:"hollow",6:"finale",7:"afterglow"}
+const MODES={
+ standard:{label:"standard",desc:"full campaign"},
+ iron:{label:"iron",desc:"early beast"},
+ greed:{label:"greed",desc:"hot relics, costly gold"},
+ dark:{label:"dark",desc:"weak flame, fast dread"},
+ daily:{label:"daily",desc:"fixed daily seed"},
+ heavy:{label:"heavy torch",desc:"starts lit, more fuel"},
+ swift:{label:"swift",desc:"pits never catch you"},
+ warded:{label:"warded",desc:"starts warded, wards hold longer"}
+}
+const MODE_IDS=Object.keys(MODES)
+const MODS={
+ thin:{label:"thin flame",desc:"torches burn faster"},
+ wake:{label:"wakeful beast",desc:"the beast starts hotter"},
+ rich:{label:"rich relics",desc:"more relics surface"},
+ gloom:{label:"heavy dread",desc:"darkness grips sooner"},
+ grace:{label:"strong shrines",desc:"wards hold longer"}
+}
+const MOD_IDS=Object.keys(MODS)
+const FLOOR_TEXT={
+ 1:["A first descent through stale rites.","The old ruin still pretends to be fair."],
+ 2:["Pressure arrives before understanding catches up.","Every branch feels closer to pursuit."],
+ 3:["Wards answer, but never for free.","Blessing and burden share the same stone."],
+ 4:["The hunt floor wants you heard.","Noise becomes destiny down here."],
+ 5:["The hollow floor strips runs to their bones.","Only the sharpest choices still matter."],
+ 6:["The last gate weighs what you became.","Every surviving system cashes in here."],
+ 7:["Dawn should have ended this. The ruin has other plans.","Nothing left down here owes you mercy."]
+}
+const FLOOR_THEMES={
+ 1:{name:"foundation",tag:"stale rite",accent:"verdigris",fog:"soft lantern fog"},
+ 2:{name:"pressure",tag:"ember choke",accent:"rust flare",fog:"hot dust"},
+ 3:{name:"ward",tag:"cold liturgy",accent:"aqua ward",fog:"glass mist"},
+ 4:{name:"hunt",tag:"rose alarm",accent:"pink hunt",fog:"thin red haze"},
+ 5:{name:"hollow",tag:"ash hush",accent:"bone gray",fog:"dry blackout"},
+ 6:{name:"finale",tag:"crown weather",accent:"gold ruin",fog:"judging dark"},
+ 7:{name:"afterglow",tag:"borrowed dawn",accent:"ash gold",fog:"embered haze"}
+}
+const ENEMY_TEXT={
+ beast:["A one-eyed pursuer that reads space better than fear.","It wants a lane, not a duel."],
+ shade:["A cold pass-through that feeds dread and tells on you.","It does not block the path; it poisons it."],
+ watcher:["A fixed witness that turns position into pursuit.","Quiet fails where it stands."],
+ leech:["A grave thing that eats ward and heat.","It survives by thinning what protects you."],
+ effigy:["A second relic, and a third. Only one is true.","The others were never meant to be found."]
+}
+const SHRINE_TEXT=[
+ "The shrine lends shape to your nerve.",
+ "A ward forms, thin and listening.",
+ "The shrine answers, and the answer is costly."
+]
+const BRAZIER_TEXT=[
+ "The brazier spits up old warmth.",
+ "A hungry flame leans toward your torch.",
+ "The coals remember better fires than yours."
+]
+const CURSE_TEXT=[
+ "The stone bites back.",
+ "A mean seam in the floor wakes underfoot.",
+ "The room answers touch with dread."
+]
+const SFX_MAP={
+ hit:{freq:180,dur:.08,type:"square"},
+ beast:{freq:90,dur:.12,type:"sawtooth"},
+ win:{freq:660,dur:.4,type:"sine"},
+ relic:{freq:520,dur:.15,type:"triangle"},
+ ward:{freq:340,dur:.2,type:"sine"},
+ shift:{freq:220,dur:.1,type:"sine"},
+ dead:{freq:70,dur:.5,type:"sawtooth"}
+}
+const FINALE_NAMES=["Ash Gate","Gold Gate","Hush Gate","Ward Gate"]
+const INTRO_TEXT=["Move with arrows or WASD.","Carry flame. Bow for gold.","Wards hold. Cracks strip. The beast reads haste."].join("\n")
+const HINT_TEXT={
+ torch:"Take the torch early. Darkness taxes every step without it.",
+ ward:"Shrines raise ward. Ward softens dark pressure, then burns down.",
+ crack:"Cracks are fast but costly. Mask or ward makes the crossing safer.",
+ beast:"Fire slows pursuit. A dropped torch can buy one clean lane."
+}
+const RELICS={
+ ember:{name:"ember heart",label:"ember",up:"slower torch drain",down:"beast ignores dropped flame"},
+ tooth:{name:"gold tooth",label:"tooth",up:"gold slips the crack",down:"beast enrages sooner"},
+ hush:{name:"hush bell",label:"hush",up:"dread stays low",down:"fire never slows beast"},
+ eye:{name:"idol eye",label:"eye",up:"idol bows easier, shrines strengthen",down:"crown scorches torch"},
+ brand:{name:"night brand",label:"brand",up:"shades break on touch",down:"cursed ground bites harder"},
+ wick:{name:"long wick",label:"wick",up:"sight and dropped flame last longer",down:"carried torch burns hotter"},
+ chain:{name:"ward chain",label:"chain",up:"wards and shrines linger",down:"gold no longer softens torch loss"},
+ veil:{name:"veil thread",label:"veil",up:"mask protects torch through the crack",down:"shrines grant less"},
+ greave:{name:"pit greaves",label:"greave",up:"pit footing stays sure",down:"crack crossings cost extra"},
+ lure:{name:"lure spool",label:"lure",up:"dropped flame always pulls the beast",down:"carried fire never slows it"},
+ salt:{name:"salt sigil",label:"salt",up:"watchers and curses bite softer",down:"shades drain more torch"},
+ ash:{name:"ash lung",label:"ash",up:"braziers flare stronger",down:"shrines sip your torch"}
+}
+const RELIC_IDS=Object.keys(RELICS)
+const RELIC_SPOTS={
+1:[["b",7,2],["v",8,8],["h",6,6]],
+2:[["h",6,6],["v",5,8],["p",8,8]],
+3:[["i",2,8],["c",2,1],["v",8,8],["h",6,6]],
+4:[["h",5,6],["i",5,8],["p",8,8],["v",8,8]],
+5:[["h",5,6],["i",5,8],["c",2,1],["v",5,8],["p",8,8]],
+6:[["e",7,3],["e",9,5],["e",5,8]],
+7:[["h",5,6],["i",5,8],["c",2,1],["v",5,8],["p",8,8]]
+}
+const EFFIGY_SPOTS={
+1:[],
+2:[["v",9,8]],
+3:[["v",9,8]],
+4:[["v",9,8]],
+5:[["v",9,8]],
+6:[],
+7:[["v",9,8]]
+}
+const BRAZIER_SPOTS={
+1:[["h",8,8],["p",2,8]],
+2:[["h",8,8],["v",2,8],["c",8,8]],
+3:[["h",8,8],["i",8,8],["p",2,8],["v",2,8]],
+4:[["h",8,8],["i",8,8],["p",2,8],["v",2,8]],
+5:[["h",8,8],["i",8,8],["p",2,8],["v",2,8],["c",8,8]],
+6:[["e",8,2],["e",2,8],["e",8,8]],
+7:[["h",8,8],["i",8,8],["p",2,8],["v",2,8],["c",8,8]]
+}
+const SHRINE_SPOTS={
+1:[["i",2,8]],
+2:[["h",8,4],["v",8,8]],
+3:[["h",8,4],["i",8,8],["c",8,8]],
+4:[["h",8,4],["i",8,8],["c",8,8],["p",8,4]],
+5:[["h",8,4],["i",8,8],["c",8,8],["v",8,8],["p",8,4]],
+6:[["e",8,4],["e",3,3],["e",8,8]],
+7:[["h",8,4],["i",8,8],["c",8,8],["v",8,8],["p",8,4]]
+}
+const CURSE_SPOTS={
+1:[["h",8,8],["p",8,2],["c",8,8]],
+2:[["h",7,4],["c",2,1],["p",8,8],["v",8,4]],
+3:[["h",7,4],["i",8,8],["c",7,1],["p",8,8],["v",8,4]],
+4:[["h",7,4],["i",8,8],["c",7,1],["p",8,8],["v",8,4]],
+5:[["h",7,4],["i",8,8],["c",7,1],["p",8,8],["v",8,4],["b",8,8]],
+6:[["e",8,8],["e",2,2],["e",8,2],["e",3,8]],
+7:[["h",7,4],["i",8,8],["c",7,1],["p",8,8],["v",8,4],["b",8,8]]
+}
+const SHADE_SPOTS={
+1:[["h",9,4],["p",8,8]],
+2:[["h",9,4],["c",8,8],["v",8,8]],
+3:[["h",9,4],["i",8,8],["c",8,8],["p",8,4]],
+4:[["h",9,4],["i",8,8],["c",8,8],["p",8,4],["v",8,8]],
+5:[["h",9,4],["i",8,8],["c",8,8],["p",8,4],["v",8,8],["b",8,8]],
+6:[["e",8,8],["e",2,8],["e",8,2],["e",3,8]],
+7:[["h",9,4],["i",8,8],["c",8,8],["p",8,4],["v",8,8],["b",8,8]]
+}
+const BLOCK_SPOTS={
+1:[],
+2:[["h",7,8],["p",2,8],["v",2,4]],
+3:[["h",7,8],["p",2,8],["c",8,2],["v",2,4]],
+4:[["h",7,8],["p",2,8],["c",8,2],["v",2,4],["b",8,8]],
+5:[["h",7,8],["p",2,8],["c",8,2],["v",2,4],["b",8,8],["i",8,4]],
+6:[["e",2,4],["e",7,7],["e",2,7]],
+7:[["h",7,8],["p",2,8],["c",8,2],["v",2,4],["b",8,8],["i",8,4]]
+}
+const WATCHER_SPOTS={
+1:[],
+2:[["h",8,8],["v",8,8]],
+3:[["h",8,8],["c",2,8],["v",8,8]],
+4:[["h",8,8],["c",2,8],["p",8,8],["v",8,8]],
+5:[["h",8,8],["c",2,8],["p",8,8],["v",8,8],["i",8,8]],
+6:[["e",8,2],["e",2,8]],
+7:[["h",8,8],["c",2,8],["p",8,8],["v",8,8],["i",8,8]]
+}
+const LEECH_SPOTS={
+1:[],
+2:[],
+3:[["p",8,8],["c",8,8]],
+4:[["p",8,8],["c",8,8],["v",8,8]],
+5:[["p",8,8],["c",8,8],["v",8,8],["h",8,4]],
+6:[["e",8,8],["e",3,3]],
+7:[["p",8,8],["c",8,8],["v",8,8],["h",8,4]]
+}
+const LEVELS={
+1:{pits:PITS,idols:IDOLS,cracks:CRACKS,halls:HALLS,escapes:ESCAPES,beasts:BEASTS,dark:"pecv",tone:"The air is stale with old rites."},
+2:{pits:PITS2,idols:IDOLS2,cracks:CRACKS2,halls:HALLS2,escapes:ESCAPES2,beasts:BEASTS2,dark:"behipcv",tone:"The ruin tightens. It knows your name now."},
+3:{pits:PITS3,idols:IDOLS3,cracks:CRACKS3,halls:HALLS3,escapes:ESCAPES3,beasts:BEASTS3,dark:"behipcv",tone:"The shrines still answer, but every blessing exacts a price."},
+4:{pits:PITS4,idols:IDOLS4,cracks:CRACKS4,halls:HALLS4,escapes:ESCAPES4,beasts:BEASTS4,dark:"behipcv",tone:"The hunt floor listens for every sound you make."},
+5:{pits:PITS4,idols:IDOLS4,cracks:CRACKS4,halls:HALLS4,escapes:ESCAPES5,beasts:BEASTS5,dark:"behipcv",tone:"The hollow floor strips away whatever was merely enough."},
+6:{pits:PITS4,idols:IDOLS4,cracks:CRACKS4,halls:HALLS4,escapes:ESCAPES6,beasts:BEASTS6,dark:"behipcv",tone:"The final gate wakes. Everything left in you will be tested."},
+7:{pits:PITS4,idols:IDOLS4,cracks:CRACKS4,halls:HALLS4,escapes:ESCAPES6,beasts:BEASTS6,dark:"behipcv",tone:"You already won. The ruin didn't agree to let you leave."}
+}
+const BASE={
+g:{m:[
+"############",
+"#..........#",
+"#..L.....R.#",
+"#..........#",
+"#..........#",
+"#....>.....#",
+"#..........#",
+"#..........#",
+"#..........#",
+"#..........#",
+"#..........#",
+"############"],ex:{">":"h",L:"b",R:"e"}},
+b:{m:[
+"############",
+"#..........#",
+"#...MT.....#",
+"#..........#",
+"#..........#",
+"#.....>....#",
+"#..........#",
+"#..........#",
+"#..........#",
+"#..........#",
+"#..........#",
+"############"],ex:{">":"h"}},
+v:{m:[
+"############",
+"#..........#",
+"#....C.K...#",
+"#..........#",
+"#..........#",
+"#..........#",
+"#..........#",
+"#..........#",
+"#..........#",
+"#....>.....#",
+"#..........#",
+"############"],ex:{">":"e"}},
+d:{m:["############","#..........#","#..........#","#..........#","#....X.....#","#..........#","#..........#","#..........#","#..........#","#..........#","#..........#","############"],ex:{}}
+}
+const BASE2={
+g:{m:[
+"############",
+"#..........#",
+"#..L..#..R.#",
+"#..........#",
+"#....#.....#",
+"#....>.....#",
+"#..........#",
+"#.....#....#",
+"#..........#",
+"#..........#",
+"#..........#",
+"############"],ex:{">":"h",L:"b",R:"e"}},
+b:{m:[
+"############",
+"#..........#",
+"#...MT.....#",
+"#....#.....#",
+"#..........#",
+"#..#..>....#",
+"#..........#",
+"#.....#....#",
+"#..........#",
+"#..........#",
+"#..........#",
+"############"],ex:{">":"h"}},
+v:{m:[
+"############",
+"#..........#",
+"#...#C.K...#",
+"#..........#",
+"#....#.....#",
+"#..........#",
+"#.....#....#",
+"#..........#",
+"#..........#",
+"#...>......#",
+"#..........#",
+"############"],ex:{">":"e"}},
+d:BASE.d
+}
+const BASE3={
+g:{m:[
+"############",
+"#..........#",
+"#..L..S..R.#",
+"#..........#",
+"#....#.....#",
+"#....>.....#",
+"#..........#",
+"#.....#....#",
+"#..........#",
+"#..........#",
+"#..........#",
+"############"],ex:{">":"h",L:"b",R:"e"}},
+b:{m:[
+"############",
+"#..........#",
+"#..SMT.....#",
+"#....#.....#",
+"#..........#",
+"#..#..>....#",
+"#..........#",
+"#.....#....#",
+"#..........#",
+"#..........#",
+"#..........#",
+"############"],ex:{">":"h"}},
+v:{m:[
+"############",
+"#..........#",
+"#...#C.K.S.#",
+"#..........#",
+"#....#.....#",
+"#..........#",
+"#.....#....#",
+"#..........#",
+"#..........#",
+"#...>......#",
+"#..........#",
+"############"],ex:{">":"e"}},
+d:BASE.d
+}
+const BASES={1:BASE,2:BASE2,3:BASE3,4:BASE3,5:BASE3,6:BASE3,7:BASE3}