krz/micro-roguelike
A micro roguelike web game in 1kb and 1mb versions.
clone: git clone https://gitbay.org/krz/micro-roguelike.git
1// Game data — edit this file to mod the run (floors, relics, hazards, balance).
2// Loaded before the engine in index.html.
3const W=12,H=12,FUEL=16
4const 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
5const 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]}
6const PITS=[[
7"############",
8"#OOOOOOOOOO#",
9"#O....F...O#",
10"#O...OO...O#",
11"#O........O#",
12"#O....>...O#",
13"#O........O#",
14"#O...OO...O#",
15"#O........O#",
16"#O........O#",
17"#OOOOOOOOOO#",
18"############"],[
19"############",
20"#OOOOOOOOOO#",
21"#O.......OO#",
22"#O.OOOOO..O#",
23"#O.......OO#",
24"#O..>.....O#",
25"#O....F...O#",
26"#O..OOOOO.O#",
27"#O........O#",
28"#O........O#",
29"#OOOOOOOOOO#",
30"############"],[
31"############",
32"#OOOOOOOOOO#",
33"#O........O#",
34"#O..OO....O#",
35"#O........O#",
36"#OF....>..O#",
37"#O....OO..O#",
38"#O........O#",
39"#O..OO....O#",
40"#O........O#",
41"#OOOOOOOOOO#",
42"############"]]
43const IDOLS=[[
44"############",
45"#..........#",
46"#...ggg....#",
47"#...gIg....#",
48"#...ggg....#",
49"#..........#",
50"#..........#",
51"#..........#",
52"#..........#",
53"#..........#",
54"#....>.....#",
55"############"],[
56"############",
57"#..........#",
58"#....gg....#",
59"#...gIg....#",
60"#....ggg...#",
61"#..........#",
62"#..........#",
63"#..........#",
64"#..........#",
65"#..........#",
66"#....>.....#",
67"############"],[
68"############",
69"#..........#",
70"#...gg.....#",
71"#...gIgg...#",
72"#.....gg...#",
73"#..........#",
74"#..........#",
75"#..........#",
76"#..........#",
77"#..........#",
78"#....>.....#",
79"############"]]
80const IDOLS2=[[
81"############",
82"#..........#",
83"#..ggg.....#",
84"#..gIgg....#",
85"#....gg....#",
86"#..........#",
87"#.....#....#",
88"#..........#",
89"#..........#",
90"#..........#",
91"#...>......#",
92"############"],[
93"############",
94"#..........#",
95"#....ggg...#",
96"#...ggIg...#",
97"#....gg....#",
98"#..........#",
99"#..........#",
100"#....#.....#",
101"#..........#",
102"#..........#",
103"#.....>....#",
104"############"],[
105"############",
106"#..........#",
107"#...gg.....#",
108"#..ggIg....#",
109"#...gg.....#",
110"#..........#",
111"#..........#",
112"#.....#....#",
113"#..........#",
114"#..........#",
115"#....>.....#",
116"############"]]
117const CRACKS=[[
118"############",
119"#..........#",
120"#.####.....#",
121"#....#.....#",
122"#..x.>.....#",
123"#....#.....#",
124"#....#.....#",
125"#..........#",
126"#..........#",
127"#..........#",
128"#..........#",
129"############"],[
130"############",
131"#..........#",
132"#.....####.#",
133"#.....#....#",
134"#.....#....#",
135"#...x.>....#",
136"#.....#....#",
137"#.....####.#",
138"#..........#",
139"#..........#",
140"#..........#",
141"############"],[
142"############",
143"#..........#",
144"#..######..#",
145"#.......#..#",
146"#...x...#..#",
147"#....>..#..#",
148"#.......#..#",
149"#..######..#",
150"#..........#",
151"#..........#",
152"#..........#",
153"############"]]
154const HALLS=[[
155"############",
156"#..........#",
157"#..a.......#",
158"#......b...#",
159"#..........#",
160"#....c.....#",
161"#......d...#",
162"#..........#",
163"#....F.....#",
164"#....>.....#",
165"#..........#",
166"############"],[
167"############",
168"#..........#",
169"#......b...#",
170"#..........#",
171"#..a.......#",
172"#..........#",
173"#....c..d..#",
174"#..........#",
175"#..F.>.....#",
176"#..........#",
177"#..........#",
178"############"],[
179"############",
180"#..........#",
181"#..a....b..#",
182"#..........#",
183"#..........#",
184"#....c..F..#",
185"#..........#",
186"#......d...#",
187"#..........#",
188"#....>.....#",
189"#..........#",
190"############"]]
191const ESCAPES=[[
192"############",
193"#..........#",
194"#..........#",
195"#..........#",
196"#..........#",
197"#....>.....#",
198"#..........#",
199"#..........#",
200"#..........#",
201"#..........#",
202"#..........#",
203"############"],[
204"############",
205"#..........#",
206"#..........#",
207"#...##.....#",
208"#......>...#",
209"#..........#",
210"#.....##...#",
211"#..........#",
212"#..........#",
213"#..........#",
214"#..........#",
215"############"],[
216"############",
217"#..........#",
218"#....##....#",
219"#..........#",
220"#..........#",
221"#..>.......#",
222"#.......##.#",
223"#..........#",
224"#..........#",
225"#..........#",
226"#..........#",
227"############"]]
228const BEASTS=[[10,8],[9,7]]
229const PITS2=[[
230"############",
231"#OOOOOOOOOO#",
232"#O..FOOO..O#",
233"#O...OO...O#",
234"#O........O#",
235"#O...O>O..O#",
236"#O........O#",
237"#O...OO...O#",
238"#O..OOOO..O#",
239"#O........O#",
240"#OOOOOOOOOO#",
241"############"],[
242"############",
243"#OOOOOOOOOO#",
244"#O......OOO#",
245"#O.OOOOO..O#",
246"#O....O...O#",
247"#O..O>O...O#",
248"#O....F...O#",
249"#O..OOOOO.O#",
250"#O....O...O#",
251"#O........O#",
252"#OOOOOOOOOO#",
253"############"],[
254"############",
255"#OOOOOOOOOO#",
256"#O....O...O#",
257"#O..OOO...O#",
258"#O........O#",
259"#OF..O.>..O#",
260"#O....OOO.O#",
261"#O........O#",
262"#O..OOO...O#",
263"#O....O...O#",
264"#OOOOOOOOOO#",
265"############"],[
266"############",
267"#OOOOOOOOOO#",
268"#O..F.....O#",
269"#O.OOOO...O#",
270"#O.....O..O#",
271"#O..>.OO..O#",
272"#O.....O..O#",
273"#O...OOOO.O#",
274"#O........O#",
275"#O........O#",
276"#OOOOOOOOOO#",
277"############"]]
278const CRACKS2=[[
279"############",
280"#.....x....#",
281"#.#####....#",
282"#....##....#",
283"#..x.>#....#",
284"#....##....#",
285"#....##....#",
286"#.....x....#",
287"#..........#",
288"#..........#",
289"#..........#",
290"############"],[
291"############",
292"#....x.....#",
293"#.....####.#",
294"#....##....#",
295"#....##....#",
296"#...x.>....#",
297"#....##....#",
298"#.....####.#",
299"#....x.....#",
300"#..........#",
301"#..........#",
302"############"],[
303"############",
304"#....x.....#",
305"#..######..#",
306"#.... ..#..#",
307"#...x...#..#",
308"#..x.>..#..#",
309"#.......#..#",
310"#..######..#",
311"#....x.....#",
312"#..........#",
313"#..........#",
314"############"]].map(m=>m.map(r=>r.replace(/ /g,".")))
315const HALLS2=[[
316"############",
317"#..........#",
318"#..a...b...#",
319"#..........#",
320"#....F.....#",
321"#....c.....#",
322"#......d...#",
323"#..........#",
324"#....>.....#",
325"#..........#",
326"#..........#",
327"############"],[
328"############",
329"#..........#",
330"#....b.....#",
331"#..a.......#",
332"#....F.....#",
333"#....c..d..#",
334"#..........#",
335"#....>.....#",
336"#..........#",
337"#..........#",
338"#..........#",
339"############"],[
340"############",
341"#..........#",
342"#..a....b..#",
343"#....F.....#",
344"#..........#",
345"#....c.....#",
346"#......d...#",
347"#..........#",
348"#....>.....#",
349"#..........#",
350"#..........#",
351"############"]]
352const ESCAPES2=[[
353"############",
354"#....##....#",
355"#..........#",
356"#..........#",
357"#...>......#",
358"#..........#",
359"#..##......#",
360"#..........#",
361"#......##..#",
362"#..........#",
363"#..........#",
364"############"],[
365"############",
366"#..........#",
367"#...##.....#",
368"#..........#",
369"#..>.......#",
370"#..........#",
371"#.....##...#",
372"#..........#",
373"#..........#",
374"#..........#",
375"#..........#",
376"############"],[
377"############",
378"#..........#",
379"#..##......#",
380"#..........#",
381"#..>....##.#",
382"#..........#",
383"#......##..#",
384"#..........#",
385"#..........#",
386"#..........#",
387"#..........#",
388"############"]]
389const BEASTS2=[[9,8],[9,7],[10,7]]
390const PITS3=[[
391"############",
392"#OOOOOOOOOO#",
393"#O..SFOO..O#",
394"#O...OO...O#",
395"#O........O#",
396"#O...O>O..O#",
397"#O........O#",
398"#O...OO...O#",
399"#O..OOOO..O#",
400"#O........O#",
401"#OOOOOOOOOO#",
402"############"],[
403"############",
404"#OOOOOOOOOO#",
405"#O.....SOOO#",
406"#O.OOOOO..O#",
407"#O....O...O#",
408"#O..O>O...O#",
409"#O....F...O#",
410"#O..OOOOO.O#",
411"#O....O...O#",
412"#O........O#",
413"#OOOOOOOOOO#",
414"############"],[
415"############",
416"#OOOOOOOOOO#",
417"#O....O...O#",
418"#O..OOO...O#",
419"#O....S...O#",
420"#OF..O.>..O#",
421"#O....OOO.O#",
422"#O........O#",
423"#O..OOO...O#",
424"#O....O...O#",
425"#OOOOOOOOOO#",
426"############"],[
427"############",
428"#OOOOOOOOOO#",
429"#O..S.O...O#",
430"#O..OOO...O#",
431"#O........O#",
432"#O...O.>..O#",
433"#O....OOO.O#",
434"#O....F...O#",
435"#O..OOO...O#",
436"#O....O...O#",
437"#OOOOOOOOOO#",
438"############"]]
439const IDOLS3=[[
440"############",
441"#..........#",
442"#..ggg.....#",
443"#..gISg....#",
444"#....gg....#",
445"#..........#",
446"#.....#....#",
447"#..........#",
448"#..........#",
449"#..........#",
450"#...>......#",
451"############"],[
452"############",
453"#..........#",
454"#....ggg...#",
455"#...gSIg...#",
456"#....gg....#",
457"#..........#",
458"#..........#",
459"#....#.....#",
460"#..........#",
461"#..........#",
462"#.....>....#",
463"############"],[
464"############",
465"#..........#",
466"#...gg.....#",
467"#..gSIg....#",
468"#...gg.....#",
469"#..........#",
470"#..........#",
471"#.....#....#",
472"#..........#",
473"#..........#",
474"#....>.....#",
475"############"]]
476const CRACKS3=[[
477"############",
478"#....Sx....#",
479"#.#####....#",
480"#....##....#",
481"#..x.>#....#",
482"#....##....#",
483"#....##....#",
484"#.....x....#",
485"#..........#",
486"#..........#",
487"#..........#",
488"############"],[
489"############",
490"#....x.....#",
491"#...S.####.#",
492"#....##....#",
493"#....##....#",
494"#...x.>....#",
495"#....##....#",
496"#.....####.#",
497"#....x.....#",
498"#..........#",
499"#..........#",
500"############"],[
501"############",
502"#....x.....#",
503"#..######..#",
504"#....S..#..#",
505"#...x...#..#",
506"#..x.>..#..#",
507"#.......#..#",
508"#..######..#",
509"#....x.....#",
510"#..........#",
511"#..........#",
512"############"]]
513const HALLS3=[[
514"############",
515"#..........#",
516"#..a..S.b..#",
517"#..........#",
518"#....F.....#",
519"#....c.....#",
520"#......d...#",
521"#..........#",
522"#....>.....#",
523"#..........#",
524"#..........#",
525"############"],[
526"############",
527"#..........#",
528"#....b..S..#",
529"#..a.......#",
530"#....F.....#",
531"#....c..d..#",
532"#..........#",
533"#....>.....#",
534"#..........#",
535"#..........#",
536"#..........#",
537"############"],[
538"############",
539"#..........#",
540"#..a....b..#",
541"#....F..S..#",
542"#..........#",
543"#....c.....#",
544"#......d...#",
545"#..........#",
546"#....>.....#",
547"#..........#",
548"#..........#",
549"############"],[
550"############",
551"#..........#",
552"#..a..S.b..#",
553"#....F.....#",
554"#..........#",
555"#....c.....#",
556"#......d...#",
557"#..........#",
558"#....>..F..#",
559"#..........#",
560"#..........#",
561"############"]]
562const ESCAPES3=[[
563"############",
564"#....##....#",
565"#..........#",
566"#....S.....#",
567"#...>......#",
568"#..........#",
569"#..##......#",
570"#..........#",
571"#......##..#",
572"#..........#",
573"#..........#",
574"############"],[
575"############",
576"#..........#",
577"#...##.....#",
578"#....S.....#",
579"#....>.....#",
580"#..........#",
581"#.....##...#",
582"#..........#",
583"#..##......#",
584"#..........#",
585"#..........#",
586"############"],[
587"############",
588"#..........#",
589"#..##......#",
590"#....S.....#",
591"#..>....##.#",
592"#..........#",
593"#......##..#",
594"#..........#",
595"#..........#",
596"#..........#",
597"#..........#",
598"############"],[
599"############",
600"#....##....#",
601"#..........#",
602"#..S.......#",
603"#....>.....#",
604"#..........#",
605"#..##..S...#",
606"#..........#",
607"#......##..#",
608"#..........#",
609"#..........#",
610"############"]]
611const BEASTS3=[[9,8],[9,7],[9,6],[10,7]]
612const ESCAPES4=[[
613"############",
614"#....##....#",
615"#....S.....#",
616"#..........#",
617"#...>......#",
618"#..........#",
619"#..##......#",
620"#......S...#",
621"#......##..#",
622"#..........#",
623"#..........#",
624"############"],[
625"############",
626"#..........#",
627"#...##.....#",
628"#....S.....#",
629"#..>.......#",
630"#..........#",
631"#.....##...#",
632"#.....S....#",
633"#..........#",
634"#..........#",
635"#..........#",
636"############"],[
637"############",
638"#..........#",
639"#..##......#",
640"#....S.....#",
641"#..>....##.#",
642"#..........#",
643"#......##..#",
644"#.....S....#",
645"#..........#",
646"#..........#",
647"#..........#",
648"############"],[
649"############",
650"#....##....#",
651"#..........#",
652"#..S.......#",
653"#....>.....#",
654"#..........#",
655"#..##..S...#",
656"#..........#",
657"#......##..#",
658"#..........#",
659"#..........#",
660"############"]]
661const BEASTS4=[[9,8],[10,8],[9,7],[10,7]]
662const PITS4=[[
663"############",
664"#OOOOOOOOOO#",
665"#O..SFOO..O#",
666"#O.O.OO...O#",
667"#O........O#",
668"#O..OO>O..O#",
669"#O........O#",
670"#O...OO...O#",
671"#O..OOOO..O#",
672"#O........O#",
673"#OOOOOOOOOO#",
674"############"],[
675"############",
676"#OOOOOOOOOO#",
677"#O....SO..O#",
678"#O.OOOOO..O#",
679"#O....O...O#",
680"#O..O>O...O#",
681"#O....F...O#",
682"#O..OOOOO.O#",
683"#O....O...O#",
684"#O........O#",
685"#OOOOOOOOOO#",
686"############"],[
687"############",
688"#OOOOOOOOOO#",
689"#O....O...O#",
690"#O..OOO...O#",
691"#O....S...O#",
692"#OF..O.>..O#",
693"#O....OOO.O#",
694"#O........O#",
695"#O..OOO...O#",
696"#O....O...O#",
697"#OOOOOOOOOO#",
698"############"],[
699"############",
700"#OOOOOOOOOO#",
701"#O..F.O...O#",
702"#O..OOO...O#",
703"#O....S...O#",
704"#O...O.>..O#",
705"#O....OOO.O#",
706"#O........O#",
707"#O..OOO...O#",
708"#O....O...O#",
709"#OOOOOOOOOO#",
710"############"]]
711const IDOLS4=[[
712"############",
713"#..........#",
714"#..ggg.....#",
715"#..gISg....#",
716"#...Sgg....#",
717"#..........#",
718"#.....#....#",
719"#..........#",
720"#..........#",
721"#..........#",
722"#...>......#",
723"############"],[
724"############",
725"#..........#",
726"#....ggg...#",
727"#...gSIg...#",
728"#....gg....#",
729"#....S.....#",
730"#..........#",
731"#....#.....#",
732"#..........#",
733"#..........#",
734"#.....>....#",
735"############"],[
736"############",
737"#..........#",
738"#...gg.....#",
739"#..gSIg....#",
740"#...gg..S..#",
741"#..........#",
742"#..........#",
743"#.....#....#",
744"#..........#",
745"#..........#",
746"#....>.....#",
747"############"]]
748const CRACKS4=[[
749"############",
750"#....Sx....#",
751"#.#####....#",
752"#....##....#",
753"#..x.>#....#",
754"#....##....#",
755"#....##....#",
756"#..x.......#",
757"#..........#",
758"#..........#",
759"#..........#",
760"############"],[
761"############",
762"#....x.....#",
763"#...S.####.#",
764"#....##....#",
765"#....##....#",
766"#..xx.>....#",
767"#....##....#",
768"#.....####.#",
769"#....x.....#",
770"#..........#",
771"#..........#",
772"############"],[
773"############",
774"#....x.....#",
775"#..######..#",
776"#....S..#..#",
777"#...x...#..#",
778"#..x.>..#..#",
779"#...x...#..#",
780"#..######..#",
781"#....x.....#",
782"#..........#",
783"#..........#",
784"############"],[
785"############",
786"#..S.x.....#",
787"#..######..#",
788"#.......#..#",
789"#..xx...#..#",
790"#....>..#..#",
791"#.......#..#",
792"#..######..#",
793"#....x.....#",
794"#..........#",
795"#..........#",
796"############"]]
797const HALLS4=[[
798"############",
799"#..........#",
800"#..a..S.b..#",
801"#..........#",
802"#....F.....#",
803"#....c.....#",
804"#......d...#",
805"#.....S....#",
806"#....>.....#",
807"#..........#",
808"#..........#",
809"############"],[
810"############",
811"#..........#",
812"#....b..S..#",
813"#..a.......#",
814"#....F.....#",
815"#....c..d..#",
816"#.....S....#",
817"#....>.....#",
818"#..........#",
819"#..........#",
820"#..........#",
821"############"],[
822"############",
823"#..........#",
824"#..a....b..#",
825"#....F..S..#",
826"#..........#",
827"#....c.....#",
828"#......d...#",
829"#.....S....#",
830"#....>.....#",
831"#..........#",
832"#..........#",
833"############"],[
834"############",
835"#..........#",
836"#..a..S.b..#",
837"#....F.....#",
838"#..........#",
839"#....c.....#",
840"#...S..d...#",
841"#..........#",
842"#....>..F..#",
843"#..........#",
844"#..........#",
845"############"]]
846const ESCAPES5=[[
847"############",
848"#....##....#",
849"#....S.....#",
850"#..........#",
851"#...>......#",
852"#..........#",
853"#..##......#",
854"#..........#",
855"#......##..#",
856"#....S.....#",
857"#..........#",
858"############"],[
859"############",
860"#..........#",
861"#...##.....#",
862"#....S.....#",
863"#..>.......#",
864"#..........#",
865"#.....##...#",
866"#....S.....#",
867"#..........#",
868"#..........#",
869"#..........#",
870"############"],[
871"############",
872"#..........#",
873"#..##......#",
874"#....S.....#",
875"#..>....##.#",
876"#..........#",
877"#......##..#",
878"#....S.....#",
879"#..........#",
880"#..........#",
881"#..........#",
882"############"],[
883"############",
884"#....##....#",
885"#..........#",
886"#..S.......#",
887"#....>.....#",
888"#..........#",
889"#..##..S...#",
890"#..........#",
891"#......##..#",
892"#....S.....#",
893"#..........#",
894"############"]]
895const BEASTS5=[[10,8],[10,7],[9,7],[9,6]]
896const ESCAPES6=[[
897"############",
898"#....##....#",
899"#....S.....#",
900"#..........#",
901"#...>......#",
902"#....S.....#",
903"#..##......#",
904"#......S...#",
905"#......##..#",
906"#..........#",
907"#..........#",
908"############"],[
909"############",
910"#..........#",
911"#...##.....#",
912"#....S.....#",
913"#..>.......#",
914"#.....S....#",
915"#.....##...#",
916"#.....S....#",
917"#..........#",
918"#..........#",
919"#..........#",
920"############"],[
921"############",
922"#..........#",
923"#..##......#",
924"#....S.....#",
925"#..>....##.#",
926"#.....S....#",
927"#......##..#",
928"#.....S....#",
929"#..........#",
930"#..........#",
931"#..........#",
932"############"],[
933"############",
934"#....##....#",
935"#....S.....#",
936"#..S.......#",
937"#....>.....#",
938"#..........#",
939"#..##..S...#",
940"#..........#",
941"#......##..#",
942"#..........#",
943"#..........#",
944"############"]]
945const BEASTS6=[[10,8],[10,7],[9,7],[10,6]]
946const LEVEL_ORDER=[1,2,3,4,5,6]
947const LEVEL_ARCS={1:"foundation",2:"pressure",3:"ward",4:"hunt",5:"hollow",6:"finale",7:"afterglow",9:"proving ground"}
948const MODES={
949 standard:{label:"standard",desc:"full campaign"},
950 iron:{label:"iron",desc:"early beast"},
951 greed:{label:"greed",desc:"hot relics, costly gold"},
952 dark:{label:"dark",desc:"weak flame, fast dread"},
953 daily:{label:"daily",desc:"fixed daily seed"},
954 heavy:{label:"heavy torch",desc:"starts lit, more fuel"},
955 swift:{label:"swift",desc:"pits never catch you"},
956 warded:{label:"warded",desc:"starts warded, wards hold longer"}
957}
958const MODE_IDS=Object.keys(MODES)
959const MODS={
960 thin:{label:"thin flame",desc:"torches burn faster"},
961 wake:{label:"wakeful beast",desc:"the beast starts hotter"},
962 rich:{label:"rich relics",desc:"more relics surface"},
963 gloom:{label:"heavy dread",desc:"darkness grips sooner"},
964 grace:{label:"strong shrines",desc:"wards hold longer"}
965}
966const MOD_IDS=Object.keys(MODS)
967const FLOOR_TEXT={
968 1:["A first descent through stale rites.","The old ruin still pretends to be fair."],
969 2:["Pressure arrives before understanding catches up.","Every branch feels closer to pursuit."],
970 3:["Wards answer, but never for free.","Blessing and burden share the same stone."],
971 4:["The hunt floor wants you heard.","Noise becomes destiny down here."],
972 5:["The hollow floor strips runs to their bones.","Only the sharpest choices still matter."],
973 6:["The last gate weighs what you became.","Every surviving system cashes in here."],
974 7:["Dawn should have ended this. The ruin has other plans.","Nothing left down here owes you mercy."]
975}
976const FLOOR_THEMES={
977 1:{name:"foundation",tag:"stale rite",accent:"verdigris",fog:"soft lantern fog"},
978 2:{name:"pressure",tag:"ember choke",accent:"rust flare",fog:"hot dust"},
979 3:{name:"ward",tag:"cold liturgy",accent:"aqua ward",fog:"glass mist"},
980 4:{name:"hunt",tag:"rose alarm",accent:"pink hunt",fog:"thin red haze"},
981 5:{name:"hollow",tag:"ash hush",accent:"bone gray",fog:"dry blackout"},
982 6:{name:"finale",tag:"crown weather",accent:"gold ruin",fog:"judging dark"},
983 7:{name:"afterglow",tag:"borrowed dawn",accent:"ash gold",fog:"embered haze"},
984 9:{name:"proving ground",tag:"debug",accent:"bare stone",fog:"none"}
985}
986const ENEMY_TEXT={
987 beast:["A one-eyed pursuer that reads space better than fear.","It wants a lane, not a duel."],
988 shade:["A cold pass-through that feeds dread and tells on you.","It does not block the path; it poisons it."],
989 watcher:["A fixed witness that turns position into pursuit.","Quiet fails where it stands."],
990 leech:["A grave thing that eats ward and heat.","It survives by thinning what protects you."],
991 effigy:["A second relic, and a third. Only one is true.","The others were never meant to be found."]
992}
993const SHRINE_TEXT=[
994 "The shrine lends shape to your nerve.",
995 "A ward forms, thin and listening.",
996 "The shrine answers, and the answer is costly."
997]
998const BRAZIER_TEXT=[
999 "The brazier spits up old warmth.",
1000 "A hungry flame leans toward your torch.",
1001 "The coals remember better fires than yours."
1002]
1003const CURSE_TEXT=[
1004 "The stone bites back.",
1005 "A mean seam in the floor wakes underfoot.",
1006 "The room answers touch with dread."
1007]
1008const SFX_MAP={
1009 hit:{freq:180,dur:.08,type:"square"},
1010 beast:{freq:90,dur:.12,type:"sawtooth"},
1011 win:{freq:660,dur:.4,type:"sine"},
1012 relic:{freq:520,dur:.15,type:"triangle"},
1013 ward:{freq:340,dur:.2,type:"sine"},
1014 shift:{freq:220,dur:.1,type:"sine"},
1015 dead:{freq:70,dur:.5,type:"sawtooth"}
1016}
1017const FINALE_NAMES=["Ash Gate","Gold Gate","Hush Gate","Ward Gate"]
1018const INTRO_TEXT=["Move with arrows or WASD.","Carry flame. Bow for gold.","Wards hold. Cracks strip. The beast reads haste."].join("\n")
1019const HINT_TEXT={
1020 torch:"Take the torch early. Darkness taxes every step without it.",
1021 ward:"Shrines raise ward. Ward softens dark pressure, then burns down.",
1022 crack:"Cracks are fast but costly. Mask or ward makes the crossing safer.",
1023 beast:"Fire slows pursuit. A dropped torch can buy one clean lane."
1024}
1025const RELICS={
1026 ember:{name:"ember heart",label:"ember",up:"slower torch drain",down:"beast ignores dropped flame"},
1027 tooth:{name:"gold tooth",label:"tooth",up:"gold slips the crack",down:"beast enrages sooner"},
1028 hush:{name:"hush bell",label:"hush",up:"dread stays low",down:"fire never slows beast"},
1029 eye:{name:"idol eye",label:"eye",up:"idol bows easier, shrines strengthen",down:"crown scorches torch"},
1030 brand:{name:"night brand",label:"brand",up:"shades break on touch",down:"cursed ground bites harder"},
1031 wick:{name:"long wick",label:"wick",up:"sight and dropped flame last longer",down:"carried torch burns hotter"},
1032 chain:{name:"ward chain",label:"chain",up:"wards and shrines linger",down:"gold no longer softens torch loss"},
1033 veil:{name:"veil thread",label:"veil",up:"mask protects torch through the crack",down:"shrines grant less"},
1034 greave:{name:"pit greaves",label:"greave",up:"pit footing stays sure",down:"crack crossings cost extra"},
1035 lure:{name:"lure spool",label:"lure",up:"dropped flame always pulls the beast",down:"carried fire never slows it"},
1036 salt:{name:"salt sigil",label:"salt",up:"watchers and curses bite softer",down:"shades drain more torch"},
1037 ash:{name:"ash lung",label:"ash",up:"braziers flare stronger",down:"shrines sip your torch"}
1038}
1039const RELIC_IDS=Object.keys(RELICS)
1040const RELIC_SPOTS={
10411:[["b",7,2],["v",8,8],["h",6,6]],
10422:[["h",6,6],["v",5,8],["p",8,8]],
10433:[["i",2,8],["c",2,1],["v",8,8],["h",6,6]],
10444:[["h",5,6],["i",5,8],["p",8,8],["v",8,8]],
10455:[["h",5,6],["i",5,8],["c",2,1],["v",5,8],["p",8,8]],
10466:[["e",7,3],["e",9,5],["e",5,8]],
10477:[["h",5,6],["i",5,8],["c",2,1],["v",5,8],["p",8,8]]
1048}
1049const EFFIGY_SPOTS={
10501:[],
10512:[["v",9,8]],
10523:[["v",9,8]],
10534:[["v",9,8]],
10545:[["v",9,8]],
10556:[],
10567:[["v",9,8]]
1057}
1058const BRAZIER_SPOTS={
10591:[["h",8,8],["p",2,8]],
10602:[["h",8,8],["v",2,8],["c",8,8]],
10613:[["h",8,8],["i",8,8],["p",2,8],["v",2,8]],
10624:[["h",8,8],["i",8,8],["p",2,8],["v",2,8]],
10635:[["h",8,8],["i",8,8],["p",2,8],["v",2,8],["c",8,8]],
10646:[["e",8,2],["e",2,8],["e",8,8]],
10657:[["h",8,8],["i",8,8],["p",2,8],["v",2,8],["c",8,8]]
1066}
1067const SHRINE_SPOTS={
10681:[["i",2,8]],
10692:[["h",8,4],["v",8,8]],
10703:[["h",8,4],["i",8,8],["c",8,8]],
10714:[["h",8,4],["i",8,8],["c",8,8],["p",8,4]],
10725:[["h",8,4],["i",8,8],["c",8,8],["v",8,8],["p",8,4]],
10736:[["e",8,4],["e",3,3],["e",8,8]],
10747:[["h",8,4],["i",8,8],["c",8,8],["v",8,8],["p",8,4]]
1075}
1076const CURSE_SPOTS={
10771:[["h",8,8],["p",8,2],["c",8,8]],
10782:[["h",7,4],["c",2,1],["p",8,8],["v",8,4]],
10793:[["h",7,4],["i",8,8],["c",7,1],["p",8,8],["v",8,4]],
10804:[["h",7,4],["i",8,8],["c",7,1],["p",8,8],["v",8,4]],
10815:[["h",7,4],["i",8,8],["c",7,1],["p",8,8],["v",8,4],["b",8,8]],
10826:[["e",8,8],["e",2,2],["e",8,2],["e",3,8]],
10837:[["h",7,4],["i",8,8],["c",7,1],["p",8,8],["v",8,4],["b",8,8]]
1084}
1085const SHADE_SPOTS={
10861:[["h",9,4],["p",8,8]],
10872:[["h",9,4],["c",8,8],["v",8,8]],
10883:[["h",9,4],["i",8,8],["c",8,8],["p",8,4]],
10894:[["h",9,4],["i",8,8],["c",8,8],["p",8,4],["v",8,8]],
10905:[["h",9,4],["i",8,8],["c",8,8],["p",8,4],["v",8,8],["b",8,8]],
10916:[["e",8,8],["e",2,8],["e",8,2],["e",3,8]],
10927:[["h",9,4],["i",8,8],["c",8,8],["p",8,4],["v",8,8],["b",8,8]]
1093}
1094const BLOCK_SPOTS={
10951:[],
10962:[["h",7,8],["p",2,8],["v",2,4]],
10973:[["h",7,8],["p",2,8],["c",8,2],["v",2,4]],
10984:[["h",7,8],["p",2,8],["c",8,2],["v",2,4],["b",8,8]],
10995:[["h",7,8],["p",2,8],["c",8,2],["v",2,4],["b",8,8],["i",8,4]],
11006:[["e",2,4],["e",7,7],["e",2,7]],
11017:[["h",7,8],["p",2,8],["c",8,2],["v",2,4],["b",8,8],["i",8,4]]
1102}
1103const WATCHER_SPOTS={
11041:[],
11052:[["h",8,8],["v",8,8]],
11063:[["h",8,8],["c",2,8],["v",8,8]],
11074:[["h",8,8],["c",2,8],["p",8,8],["v",8,8]],
11085:[["h",8,8],["c",2,8],["p",8,8],["v",8,8],["i",8,8]],
11096:[["e",8,2],["e",2,8]],
11107:[["h",8,8],["c",2,8],["p",8,8],["v",8,8],["i",8,8]]
1111}
1112const LEECH_SPOTS={
11131:[],
11142:[],
11153:[["p",8,8],["c",8,8]],
11164:[["p",8,8],["c",8,8],["v",8,8]],
11175:[["p",8,8],["c",8,8],["v",8,8],["h",8,4]],
11186:[["e",8,8],["e",3,3]],
11197:[["p",8,8],["c",8,8],["v",8,8],["h",8,4]]
1120}
1121const LEVELS={
11221:{pits:PITS,idols:IDOLS,cracks:CRACKS,halls:HALLS,escapes:ESCAPES,beasts:BEASTS,dark:"pecv",tone:"The air is stale with old rites."},
11232:{pits:PITS2,idols:IDOLS2,cracks:CRACKS2,halls:HALLS2,escapes:ESCAPES2,beasts:BEASTS2,dark:"behipcv",tone:"The ruin tightens. It knows your name now."},
11243:{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."},
11254:{pits:PITS4,idols:IDOLS4,cracks:CRACKS4,halls:HALLS4,escapes:ESCAPES4,beasts:BEASTS4,dark:"behipcv",tone:"The hunt floor listens for every sound you make."},
11265:{pits:PITS4,idols:IDOLS4,cracks:CRACKS4,halls:HALLS4,escapes:ESCAPES5,beasts:BEASTS5,dark:"behipcv",tone:"The hollow floor strips away whatever was merely enough."},
11276:{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."},
11287:{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."},
11299:{pits:PITS,idols:IDOLS,cracks:CRACKS,halls:HALLS,escapes:ESCAPES,beasts:BEASTS,dark:"",tone:"A proving ground outside the campaign."}
1130}
1131const BASE={
1132g:[
1133"############",
1134"#..........#",
1135"#..L.....R.#",
1136"#..........#",
1137"#..........#",
1138"#....>.....#",
1139"#..........#",
1140"#..........#",
1141"#..........#",
1142"#..........#",
1143"#..........#",
1144"############"],
1145b:[
1146"############",
1147"#..........#",
1148"#...MT.....#",
1149"#..........#",
1150"#..........#",
1151"#.....>....#",
1152"#..........#",
1153"#..........#",
1154"#..........#",
1155"#..........#",
1156"#..........#",
1157"############"],
1158v:[
1159"############",
1160"#..........#",
1161"#....C.K...#",
1162"#..........#",
1163"#..........#",
1164"#..........#",
1165"#..........#",
1166"#..........#",
1167"#..........#",
1168"#....>.....#",
1169"#..........#",
1170"############"],
1171d:["############","#..........#","#..........#","#..........#","#....X.....#","#..........#","#..........#","#..........#","#..........#","#..........#","#..........#","############"]
1172}
1173const BASE2={
1174g:[
1175"############",
1176"#..........#",
1177"#..L..#..R.#",
1178"#..........#",
1179"#....#.....#",
1180"#....>.....#",
1181"#..........#",
1182"#.....#....#",
1183"#..........#",
1184"#..........#",
1185"#..........#",
1186"############"],
1187b:[
1188"############",
1189"#..........#",
1190"#...MT.....#",
1191"#....#.....#",
1192"#..........#",
1193"#..#..>....#",
1194"#..........#",
1195"#.....#....#",
1196"#..........#",
1197"#..........#",
1198"#..........#",
1199"############"],
1200v:[
1201"############",
1202"#..........#",
1203"#...#C.K...#",
1204"#..........#",
1205"#....#.....#",
1206"#..........#",
1207"#.....#....#",
1208"#..........#",
1209"#..........#",
1210"#...>......#",
1211"#..........#",
1212"############"],
1213d:BASE.d
1214}
1215const BASE3={
1216g:[
1217"############",
1218"#..........#",
1219"#..L..S..R.#",
1220"#..........#",
1221"#....#.....#",
1222"#....>.....#",
1223"#..........#",
1224"#.....#....#",
1225"#..........#",
1226"#..........#",
1227"#..........#",
1228"############"],
1229b:[
1230"############",
1231"#..........#",
1232"#..SMT.....#",
1233"#....#.....#",
1234"#..........#",
1235"#..#..>....#",
1236"#..........#",
1237"#.....#....#",
1238"#..........#",
1239"#..........#",
1240"#..........#",
1241"############"],
1242v:[
1243"############",
1244"#..........#",
1245"#...#C.K.S.#",
1246"#..........#",
1247"#....#.....#",
1248"#..........#",
1249"#.....#....#",
1250"#..........#",
1251"#..........#",
1252"#...>......#",
1253"#..........#",
1254"############"],
1255d:BASE.d
1256}
1257const BASES={1:BASE,2:BASE2,3:BASE3,4:BASE3,5:BASE3,6:BASE3,7:BASE3,9:BASE}
1258// Procedural room slots: floors 2+ draw each variant pick from the authored
1259// arrays above plus PROC_SLOTS generated layouts per room type (escapes only
1260// through floor 5 — the finale arenas stay authored, as do BASES rooms).
1261// Specs feed genRoom() in the engine: exits lists required exit letters
1262// ("any" = random open tile), ring is the pit-room O border, walls and pits
1263// are tile budgets for wall clusters and pit veins, traps/items sprinkle
1264// chars onto open floor, stamp drops a small pattern whole onto the map.
1265const PROC_SLOTS=2
1266const PROC_SPECS={
1267 pits:{ring:1,pits:9,walls:2,exits:{">":"any"},items:{F:1}},
1268 idols:{walls:3,exits:{">":"any"},stamp:["ggg","gIg","ggg"]},
1269 cracks:{walls:14,traps:{x:3},exits:{">":"any"}},
1270 halls:{walls:5,exits:{a:"any",b:"any",c:"any",d:"any",">":"any"},items:{F:1}},
1271 escapes:{walls:5,exits:{">":"any"}}
1272}
1273// Floor topology: room set + exit wiring, consumed generically by build().
1274// base: fixed map from BASES[floor]. arr + v: variant array in LEVELS[floor]
1275// and the V slot that picks the variant. An exit destination prefixed "!" is
1276// one-way: it seals behind you after one crossing. Room codes beyond one char
1277// (h2) are extra instances; they inherit family behavior from the first letter.
1278const TOPO={
1279 g:{base:"g",ex:{">":"h",L:"b",R:"e"}},
1280 b:{base:"b",ex:{">":"h"}},
1281 v:{base:"v",ex:{">":"e"}},
1282 d:{base:"d",ex:{}},
1283 h:{arr:"halls",v:"hall",ex:{a:"p",b:"i",c:"c",d:"d",">":"g"}},
1284 p:{arr:"pits",v:"pit",ex:{">":"v"}},
1285 i:{arr:"idols",v:"idol",ex:{">":"h"}},
1286 c:{arr:"cracks",v:"crack",ex:{">":"v"}},
1287 e:{arr:"escapes",v:"escape",ex:{">":"g"}}
1288}
1289const GRAPH={1:TOPO,2:TOPO,3:TOPO,4:TOPO,5:TOPO,6:TOPO,7:TOPO,
1290// floor 9: debug proving ground (T in play) — a second hall instance reached
1291// by a one-way drop; exit b in h2 climbs back to the first hall.
12929:{
1293 g:{base:"g",ex:{">":"h"}},
1294 h:{arr:"halls",v:"hall",ex:{a:"!h2",">":"g"}},
1295 h2:{arr:"halls",v:"hall",ex:{b:"h",">":"g"}}
1296}}