alvations commited on
Commit
03b1c9d
·
verified ·
1 Parent(s): cb867cd

Deploy Hallway 8 (multi-arc memory game)

Browse files
anomalies.py CHANGED
@@ -15,20 +15,43 @@ from typing import Dict, Iterable, List, Optional, Tuple
15
 
16
 
17
  def pick_anomaly(properties: Dict[str, dict], rng: random.Random,
18
- exclude: Iterable[str] = ()) -> Optional[Tuple[str, str]]:
19
- """Choose one property and one of its anomalous values.
 
 
20
 
21
- Returns (property_name, anomaly_value), or None if every anomaly-capable
22
- property is excluded. `exclude` holds props that must not be the anomaly
23
- this loop, which powers two callers:
24
 
25
  - a late-revealed "aggro-item" the player has not yet seen at baseline, so
26
  it can never be the change on the loop it first appears; and
27
  - hard mode's second simultaneous change, where passing the already-chosen
28
  change (plus any held item) as `exclude` yields a distinct second detail,
29
  so the two changes never collide.
 
 
 
 
 
 
 
30
  """
31
  skip = set(exclude)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
32
  candidates = [name for name, spec in properties.items()
33
  if spec.get("anomalies") and name not in skip]
34
  if not candidates:
 
15
 
16
 
17
  def pick_anomaly(properties: Dict[str, dict], rng: random.Random,
18
+ exclude: Iterable[str] = (),
19
+ baseline_of: Optional[Dict[str, str]] = None
20
+ ) -> Optional[Tuple[str, str]]:
21
+ """Choose one property and one changed value.
22
 
23
+ Returns (property_name, changed_value), or None if every candidate property
24
+ is excluded. `exclude` holds props that must not be the anomaly this loop,
25
+ which powers two callers:
26
 
27
  - a late-revealed "aggro-item" the player has not yet seen at baseline, so
28
  it can never be the change on the loop it first appears; and
29
  - hard mode's second simultaneous change, where passing the already-chosen
30
  change (plus any held item) as `exclude` yields a distinct second detail,
31
  so the two changes never collide.
32
+
33
+ `baseline_of` (INSANE only): a map of prop -> this run's baseline value. When
34
+ given, the change is any value that DIFFERS from this run's baseline (drawn
35
+ from the property's full value set: baseline pools + anomaly pools), not the
36
+ fixed anomaly set. That is what makes 'insane' a memory test rather than a
37
+ vocabulary test. When None (every other difficulty), the behaviour is
38
+ unchanged: pick from the property's `anomalies`.
39
  """
40
  skip = set(exclude)
41
+ if baseline_of is not None:
42
+ candidates = []
43
+ for name, spec in properties.items():
44
+ if name in skip:
45
+ continue
46
+ allv = list(spec.get("values", {})) + list(spec.get("anomalies", {}))
47
+ base = baseline_of.get(name)
48
+ alts = [v for v in allv if v != base]
49
+ if alts:
50
+ candidates.append((name, alts))
51
+ if not candidates:
52
+ return None
53
+ prop, alts = rng.choice(candidates)
54
+ return prop, rng.choice(alts)
55
  candidates = [name for name, spec in properties.items()
56
  if spec.get("anomalies") and name not in skip]
57
  if not candidates:
data/i18n/compiled/en_US.json CHANGED
@@ -634,6 +634,10 @@
634
  "ui|ach_d_hard_coach8": "Escape Coach 8 on hard.",
635
  "ui|ach_d_hard_hallway-eight": "Escape Hallway 8 on hard.",
636
  "ui|ach_d_hard_stairway8": "Escape Stairway 8 on hard.",
 
 
 
 
637
  "ui|ach_d_melon": "Thank you for keeping the lights on. From all of us at Melon Labs.",
638
  "ui|ach_d_nerve": "Turn back at the final door, and be right.",
639
  "ui|ach_d_npc_knows": "Be acknowledged by the one who is always ahead.",
@@ -663,6 +667,10 @@
663
  "ui|ach_n_hard_coach8": "Coach, harder",
664
  "ui|ach_n_hard_hallway-eight": "Hallway, harder",
665
  "ui|ach_n_hard_stairway8": "Stairway, harder",
 
 
 
 
666
  "ui|ach_n_melon": "Melon Supporter",
667
  "ui|ach_n_nerve": "Nerve",
668
  "ui|ach_n_npc_knows": "It knows you",
@@ -696,7 +704,9 @@
696
  "ui|diff_easy": "Easy",
697
  "ui|diff_hard": "Hard",
698
  "ui|diff_hint_hard": "Hard adds new kinds of change.",
 
699
  "ui|diff_hint_locked": "Escape once to unlock Hard.",
 
700
  "ui|diff_normal": "Normal",
701
  "ui|end_credits": "End Credits",
702
  "ui|ending_back": "Back to the start",
 
634
  "ui|ach_d_hard_coach8": "Escape Coach 8 on hard.",
635
  "ui|ach_d_hard_hallway-eight": "Escape Hallway 8 on hard.",
636
  "ui|ach_d_hard_stairway8": "Escape Stairway 8 on hard.",
637
+ "ui|ach_d_insane_all": "Escape all three on insane.",
638
+ "ui|ach_d_insane_coach8": "Escape Coach 8 on insane.",
639
+ "ui|ach_d_insane_hallway-eight": "Escape Hallway 8 on insane.",
640
+ "ui|ach_d_insane_stairway8": "Escape Stairway 8 on insane.",
641
  "ui|ach_d_melon": "Thank you for keeping the lights on. From all of us at Melon Labs.",
642
  "ui|ach_d_nerve": "Turn back at the final door, and be right.",
643
  "ui|ach_d_npc_knows": "Be acknowledged by the one who is always ahead.",
 
667
  "ui|ach_n_hard_coach8": "Coach, harder",
668
  "ui|ach_n_hard_hallway-eight": "Hallway, harder",
669
  "ui|ach_n_hard_stairway8": "Stairway, harder",
670
+ "ui|ach_n_insane_all": "Trust nothing",
671
+ "ui|ach_n_insane_coach8": "Coach, unmade",
672
+ "ui|ach_n_insane_hallway-eight": "Hallway, unmade",
673
+ "ui|ach_n_insane_stairway8": "Stairway, unmade",
674
  "ui|ach_n_melon": "Melon Supporter",
675
  "ui|ach_n_nerve": "Nerve",
676
  "ui|ach_n_npc_knows": "It knows you",
 
704
  "ui|diff_easy": "Easy",
705
  "ui|diff_hard": "Hard",
706
  "ui|diff_hint_hard": "Hard adds new kinds of change.",
707
+ "ui|diff_hint_insane": "Insane remakes what normal is, every run.",
708
  "ui|diff_hint_locked": "Escape once to unlock Hard.",
709
+ "ui|diff_insane": "Insane",
710
  "ui|diff_normal": "Normal",
711
  "ui|end_credits": "End Credits",
712
  "ui|ending_back": "Back to the start",
hallway.py CHANGED
@@ -52,12 +52,20 @@ ANOMALY_MAX = 0.55 # never so high that "always turn back" wins
52
  # stiffer to a higher cap AND adds new *kinds* of change (see build(): double
53
  # changes and cross-loop persistence). No level-0 floor: the low opening is the
54
  # point, and levels 1+ ramp well clear of zero so "always continue" still loses.
55
- DIFFICULTIES = ("easy", "normal", "hard")
 
 
 
 
 
 
 
56
  DEFAULT_DIFFICULTY = "normal"
57
  _DIFF = {
58
  "easy": {"base": 0.01, "step": 0.042, "max": 0.30, "floor": 0.0},
59
  "normal": {"base": ANOMALY_BASE, "step": ANOMALY_STEP, "max": ANOMALY_MAX, "floor": 0.0},
60
  "hard": {"base": 0.03, "step": 0.081, "max": 0.60, "floor": 0.0},
 
61
  }
62
 
63
 
@@ -175,6 +183,23 @@ class Hallway:
175
  return near_end and rng.random() < roll
176
  return act2_exit_ready(mem.level, GOAL, rng, difficulty)
177
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
178
  def build(self, mem: PlayerMemory, rng: random.Random,
179
  locale: Optional[str] = None,
180
  difficulty: str = DEFAULT_DIFFICULTY) -> dict:
@@ -210,6 +235,7 @@ class Hallway:
210
  if mem.level == 0:
211
  mem.seen_props = []
212
  mem.held = {}
 
213
  if diff == "hard" and late_props:
214
  hold_k = 1 if len(late_props) < 2 else rng.randint(1, 2)
215
  elif diff == "normal" and late_props and rng.random() < 0.15:
@@ -221,6 +247,16 @@ class Hallway:
221
  hi = max(lo, GOAL - 2) # up to ~level 6 (never the last)
222
  for p in rng.sample(late_props, hold_k):
223
  mem.held[p] = rng.randint(lo, hi)
 
 
 
 
 
 
 
 
 
 
224
  # Props still held out of this loop (they reveal on a later loop).
225
  held_now = {p for p, rv in mem.held.items() if mem.level < rv}
226
  # An anomaly may not land on a held item until the player has seen it at
@@ -228,6 +264,15 @@ class Hallway:
228
  # "still held" and "revealed this very loop", so a held item's first
229
  # appearance is always a calm baseline, never the trap.
230
  excluded_anomaly = {p for p in mem.held if p not in mem.seen_props}
 
 
 
 
 
 
 
 
 
231
 
232
  # The opening loop (level 0) uses the very-low base above, so a fresh run
233
  # is almost always a clean baseline before anything is allowed to move.
@@ -256,7 +301,9 @@ class Hallway:
256
  has_anomaly = False # revert: a clean loop right after a change
257
 
258
  if has_anomaly and not changed:
259
- picked = anomalies.pick_anomaly(self.properties, rng, excluded_anomaly)
 
 
260
  if picked:
261
  changed[picked[0]] = picked[1]
262
 
@@ -345,8 +392,14 @@ class Hallway:
345
  for prop in shown:
346
  spec = self.properties[prop]
347
  if prop in changed:
348
- val, kind = changed[prop], "x"
349
- pool = spec["anomalies"][val]
 
 
 
 
 
 
350
  else:
351
  val, kind = spec["baseline"], "v"
352
  pool = spec["values"][val]
 
52
  # stiffer to a higher cap AND adds new *kinds* of change (see build(): double
53
  # changes and cross-loop persistence). No level-0 floor: the low opening is the
54
  # point, and levels 1+ ramp well clear of zero so "always continue" still loses.
55
+ # "insane" is a server-only, UNEXPOSED difficulty (the client offers only
56
+ # easy/normal/hard, like the hidden locales). Its defining feature is not the
57
+ # ramp but a per-run randomized baseline (see build()), which defeats a bot that
58
+ # memorizes the fixed all-clear vocabulary. It reuses existing translated content,
59
+ # so it needs no new i18n. Keep it out of the client picker until deliberately
60
+ # released.
61
+ DIFFICULTIES = ("easy", "normal", "hard", "insane")
62
+ EXPOSED_DIFFICULTIES = ("easy", "normal", "hard")
63
  DEFAULT_DIFFICULTY = "normal"
64
  _DIFF = {
65
  "easy": {"base": 0.01, "step": 0.042, "max": 0.30, "floor": 0.0},
66
  "normal": {"base": ANOMALY_BASE, "step": ANOMALY_STEP, "max": ANOMALY_MAX, "floor": 0.0},
67
  "hard": {"base": 0.03, "step": 0.081, "max": 0.60, "floor": 0.0},
68
+ "insane": {"base": 0.03, "step": 0.085, "max": 0.62, "floor": 0.0},
69
  }
70
 
71
 
 
183
  return near_end and rng.random() < roll
184
  return act2_exit_ready(mem.level, GOAL, rng, difficulty)
185
 
186
+ @staticmethod
187
+ def _value_keys(spec: dict) -> List[str]:
188
+ """Every value a property can take: its baseline value pools plus its
189
+ anomaly value pools. Used by 'insane' to pick a per-run baseline."""
190
+ return list(spec.get("values", {})) + list(spec.get("anomalies", {}))
191
+
192
+ @staticmethod
193
+ def _pool_and_kind(spec: dict, val: str):
194
+ """The sentence pool and i18n kind for ANY value of a property. A value
195
+ in `values` is a calm baseline line (kind 'v'); one in `anomalies` is a
196
+ wrongness line (kind 'x'). This lets a value serve as a run-baseline OR a
197
+ change depending on the difficulty, while always keying to the SAME
198
+ already-translated line, so 'insane' needs no new i18n."""
199
+ if val in spec.get("values", {}):
200
+ return spec["values"][val], "v"
201
+ return spec["anomalies"][val], "x"
202
+
203
  def build(self, mem: PlayerMemory, rng: random.Random,
204
  locale: Optional[str] = None,
205
  difficulty: str = DEFAULT_DIFFICULTY) -> dict:
 
235
  if mem.level == 0:
236
  mem.seen_props = []
237
  mem.held = {}
238
+ mem.run_baseline = {}
239
  if diff == "hard" and late_props:
240
  hold_k = 1 if len(late_props) < 2 else rng.randint(1, 2)
241
  elif diff == "normal" and late_props and rng.random() < 0.15:
 
247
  hi = max(lo, GOAL - 2) # up to ~level 6 (never the last)
248
  for p in rng.sample(late_props, hold_k):
249
  mem.held[p] = rng.randint(lo, hi)
250
+ # INSANE only: randomize this climb's baseline value for every
251
+ # property (from its full set of value pools). The "normal" state is
252
+ # then run-specific, so a bot that memorized the global all-clear
253
+ # vocabulary cannot tell clean from changed and must remember THIS
254
+ # run's baseline. Reuses existing lines, so no new content or i18n.
255
+ if diff == "insane":
256
+ for p, spec in self.properties.items():
257
+ keys = self._value_keys(spec)
258
+ if keys:
259
+ mem.run_baseline[p] = rng.choice(keys)
260
  # Props still held out of this loop (they reveal on a later loop).
261
  held_now = {p for p, rv in mem.held.items() if mem.level < rv}
262
  # An anomaly may not land on a held item until the player has seen it at
 
264
  # "still held" and "revealed this very loop", so a held item's first
265
  # appearance is always a calm baseline, never the trap.
266
  excluded_anomaly = {p for p in mem.held if p not in mem.seen_props}
267
+ # INSANE fairness: because the baseline is randomized per run, a property's
268
+ # "normal" is only knowable once the player has seen it this run. So an
269
+ # anomaly may only land on a property already shown at baseline on an
270
+ # earlier loop (exactly the aggro-item guard, extended to every property).
271
+ # This makes the opening loop always a clean baseline and every property's
272
+ # first appearance a calm baseline, never the trap.
273
+ if diff == "insane":
274
+ excluded_anomaly = excluded_anomaly | {
275
+ p for p in self.properties if p not in mem.seen_props}
276
 
277
  # The opening loop (level 0) uses the very-low base above, so a fresh run
278
  # is almost always a clean baseline before anything is allowed to move.
 
301
  has_anomaly = False # revert: a clean loop right after a change
302
 
303
  if has_anomaly and not changed:
304
+ picked = anomalies.pick_anomaly(
305
+ self.properties, rng, excluded_anomaly,
306
+ baseline_of=(mem.run_baseline if diff == "insane" else None))
307
  if picked:
308
  changed[picked[0]] = picked[1]
309
 
 
392
  for prop in shown:
393
  spec = self.properties[prop]
394
  if prop in changed:
395
+ val = changed[prop]
396
+ pool, kind = self._pool_and_kind(spec, val)
397
+ elif diff == "insane":
398
+ # This run's randomized baseline for the property (a calm 'v' line
399
+ # or, when the run-baseline happens to be a wrongness value, its
400
+ # 'x' line, keyed to the same existing translation).
401
+ val = mem.run_baseline.get(prop, spec["baseline"])
402
+ pool, kind = self._pool_and_kind(spec, val)
403
  else:
404
  val, kind = spec["baseline"], "v"
405
  pool = spec["values"][val]
i18n.py CHANGED
@@ -219,8 +219,10 @@ UI_STRINGS_EN: Dict[str, str] = {
219
  "diff_easy": "Easy",
220
  "diff_normal": "Normal",
221
  "diff_hard": "Hard",
 
222
  "diff_hint_hard": "Hard adds new kinds of change.",
223
  "diff_hint_locked": "Escape once to unlock Hard.",
 
224
  "age_simple": "Simple",
225
  "age_normal": "Normal",
226
  # The HUD "furthest reached" marker ({n} = best level).
@@ -291,6 +293,14 @@ UI_STRINGS_EN: Dict[str, str] = {
291
  "ach_d_hard_coach8": "Escape Coach 8 on hard.",
292
  "ach_n_hard_all": "Nowhere left soft",
293
  "ach_d_hard_all": "Escape all three on hard.",
 
 
 
 
 
 
 
 
294
  "ach_n_melon": "Melon Supporter",
295
  "ach_d_melon": "Thank you for keeping the lights on. From all of us at Melon Labs.",
296
  # Win-screen sharing. One of share_1..8 is chosen at random when the player
 
219
  "diff_easy": "Easy",
220
  "diff_normal": "Normal",
221
  "diff_hard": "Hard",
222
+ "diff_insane": "Insane",
223
  "diff_hint_hard": "Hard adds new kinds of change.",
224
  "diff_hint_locked": "Escape once to unlock Hard.",
225
+ "diff_hint_insane": "Insane remakes what normal is, every run.",
226
  "age_simple": "Simple",
227
  "age_normal": "Normal",
228
  # The HUD "furthest reached" marker ({n} = best level).
 
293
  "ach_d_hard_coach8": "Escape Coach 8 on hard.",
294
  "ach_n_hard_all": "Nowhere left soft",
295
  "ach_d_hard_all": "Escape all three on hard.",
296
+ "ach_n_insane_hallway-eight": "Hallway, unmade",
297
+ "ach_d_insane_hallway-eight": "Escape Hallway 8 on insane.",
298
+ "ach_n_insane_stairway8": "Stairway, unmade",
299
+ "ach_d_insane_stairway8": "Escape Stairway 8 on insane.",
300
+ "ach_n_insane_coach8": "Coach, unmade",
301
+ "ach_d_insane_coach8": "Escape Coach 8 on insane.",
302
+ "ach_n_insane_all": "Trust nothing",
303
+ "ach_d_insane_all": "Escape all three on insane.",
304
  "ach_n_melon": "Melon Supporter",
305
  "ach_d_melon": "Thank you for keeping the lights on. From all of us at Melon Labs.",
306
  # Win-screen sharing. One of share_1..8 is chosen at random when the player
memory.py CHANGED
@@ -57,6 +57,14 @@ class PlayerMemory:
57
  seen_props: list = field(default_factory=list)
58
  held: dict = field(default_factory=dict) # held prop -> reveal level
59
 
 
 
 
 
 
 
 
 
60
  def record_inspect(self, thing: str) -> None:
61
  self.inspects[thing] = self.inspects.get(thing, 0) + 1
62
 
 
57
  seen_props: list = field(default_factory=list)
58
  held: dict = field(default_factory=dict) # held prop -> reveal level
59
 
60
+ # "Insane" difficulty only: the baseline value chosen for each property THIS
61
+ # climb (maps prop -> value key). Insane randomizes the baseline per run from
62
+ # a property's existing value pools, so a wording that is the norm in one run
63
+ # is the change in another; a bot that memorized the global vocabulary cannot
64
+ # tell clean from changed and must remember *this* run's baseline. Empty for
65
+ # every other difficulty (they use the arc's fixed baseline).
66
+ run_baseline: dict = field(default_factory=dict)
67
+
68
  def record_inspect(self, thing: str) -> None:
69
  self.inspects[thing] = self.inspects.get(thing, 0) + 1
70
 
static/game.js CHANGED
@@ -61,6 +61,7 @@ const el = {
61
  setDiffLabel: $("#set-diff-label"),
62
  setDiffHint: $("#set-diff-hint"),
63
  setDiffHard: $("#set-diff-hard"),
 
64
  setAgeLabel: $("#set-age-label"),
65
  settingsGo: $("#settings-go"),
66
  achOpen: $("#ach-open"),
@@ -174,8 +175,13 @@ let difficulty = localStorage.getItem("h8_diff") || "normal";
174
  // for younger players. Default normal. Does not change any mechanic.
175
  let register = localStorage.getItem("h8_register") || "normal";
176
 
177
- // Hard mode is available to everyone from the start; Normal stays the default.
178
- function effectiveDifficulty() { return difficulty; }
 
 
 
 
 
179
 
180
  function headers(extra) {
181
  const h = Object.assign({}, extra || {});
@@ -245,7 +251,7 @@ async function applyUI() {
245
  if (el.setDiffLabel) el.setDiffLabel.textContent = t("set_diff", "Difficulty");
246
  if (el.setAgeLabel) el.setAgeLabel.textContent = t("set_age", "Reading");
247
  document.querySelectorAll('.set-opts[data-set="diff"] button').forEach((b) => {
248
- const d = { easy: "Easy", normal: "Normal", hard: "Hard" };
249
  b.textContent = t("diff_" + b.dataset.diff, d[b.dataset.diff]);
250
  });
251
  document.querySelectorAll('.set-opts[data-set="register"] button').forEach((b) => {
@@ -280,19 +286,28 @@ function applySettings() {
280
  // Ship defaults (a fresh visitor, and so every redeploy): text "0" = smallest,
281
  // bright "0" = most dim. Difficulty and register default to "normal" above.
282
  // Keep these as the resting state; the sliders/words only move on opt-in.
283
- let text = "0", bright = "0", motion = false;
284
  try {
285
  text = localStorage.getItem("h8_text") || "0";
286
  bright = localStorage.getItem("h8_bright") || "0";
287
- motion = localStorage.getItem("h8_motion") === "1";
288
  } catch (e) {}
289
  document.documentElement.dataset.text = text;
290
  document.body.dataset.bright = bright;
291
- reduceMotion = motion || osReduceMotion();
 
 
 
 
 
 
 
292
  document.documentElement.classList.toggle("motion-reduce", reduceMotion);
293
  if (el.setText) el.setText.value = text;
294
  if (el.setBright) el.setBright.value = bright;
295
- if (el.setMotion) el.setMotion.checked = motion;
 
 
296
  applyDifficultyUI();
297
  markOpts("register", register);
298
  }
@@ -300,8 +315,16 @@ function applySettings() {
300
  // the default is still Normal.
301
  function applyDifficultyUI() {
302
  markOpts("diff", difficulty);
 
 
 
 
 
 
303
  if (el.setDiffHint) {
304
- el.setDiffHint.textContent = ui["diff_hint_hard"] || "Hard adds new kinds of change.";
 
 
305
  }
306
  }
307
  applySettings();
@@ -326,7 +349,10 @@ document.querySelectorAll(".set-opts").forEach((group) => {
326
  if (!b || b.disabled) return;
327
  const set = group.dataset.set;
328
  const val = b.dataset.val;
329
- if (set === "diff") difficulty = val; // hard is available to everyone
 
 
 
330
  if (set === "register") register = val;
331
  try { localStorage.setItem("h8_" + set, val); } catch (e) {}
332
  applySettings();
@@ -628,11 +654,13 @@ async function interactTouch(prop, btn) {
628
  const res = await post("/api/interact", { prop });
629
  if (!res || res.kind === "none") return;
630
  if (res.kind === "fold") {
631
- // Curiosity folded the run back to the start. Show the line, drop into the
632
- // fresh loop the server handed back (already reset to level 0), then explain
633
- // that the reset was this touch, so it does not read as a glitch.
 
 
634
  showTouchLine(res.line);
635
- await sleep(reduceMotion ? 500 : 1500);
636
  run = freshRun(); // the fold sent the climb back to the start
637
  renderRoom(res);
638
  maybeFoldExplainer();
@@ -706,6 +734,12 @@ function maybeFoldExplainer() {
706
  });
707
  if (el.foldHideRow) el.foldHideRow.classList.toggle("hidden", seen < 2);
708
  if (el.foldHide) el.foldHide.checked = false;
 
 
 
 
 
 
709
  el.fold.classList.remove("hidden");
710
  if (el.foldGo) el.foldGo.focus();
711
  }
@@ -714,6 +748,12 @@ function hideFoldExplainer() {
714
  try { localStorage.setItem("h8_fold_hide", "1"); } catch (e) {}
715
  }
716
  if (el.fold) el.fold.classList.add("hidden");
 
 
 
 
 
 
717
  }
718
  if (el.foldGo) el.foldGo.addEventListener("click", hideFoldExplainer);
719
  if (el.fold) {
@@ -1405,11 +1445,14 @@ el.again.addEventListener("click", async () => {
1405
  // saves are alike.
1406
  const RELEASE_DAY = "2026-07-06"; // play on this local date...
1407
  const RELEASE_REVEAL = "2026-07-07"; // ...and the badge shows from here (all of earth past the 6th)
1408
- const ARC_IDS = ["hallway-eight", "stairway8", "coach8"];
 
 
 
1409
  const NPC_PROP = { "hallway-eight": "figure", "stairway8": "figure", "coach8": "passenger" };
1410
 
1411
  function blankMem() {
1412
- return { v: 1, flash: {}, flashText: {}, wins: {}, hardWins: {}, clean: {}, ends: {}, npc: {},
1413
  shared: false, releaseDay: false, plays: 0, promos: [], melon: false, langs: [],
1414
  arcStarted: {},
1415
  records: { steady: false, cold: false, nerve: false, streak: 0, best: 0 } };
@@ -1446,10 +1489,14 @@ function recordFlashback(arc, idx, line) {
1446
  if (dirty) saveMem();
1447
  }
1448
  function recordWin(arc, attempts) {
1449
- // Record the escape, and (if it was a hard run) the hard-mode escape.
1450
- if (effectiveDifficulty() === "hard") {
 
1451
  if (!mem.hardWins) mem.hardWins = {};
1452
  mem.hardWins[arc] = (mem.hardWins[arc] || 0) + 1;
 
 
 
1453
  }
1454
  mem.wins[arc] = (mem.wins[arc] || 0) + 1;
1455
  if (attempts <= 1) mem.clean[arc] = true;
@@ -1531,9 +1578,37 @@ const ACHS = [
1531
  { id: "hard_stairway8", test: () => (mem.hardWins || {})["stairway8"] > 0 },
1532
  { id: "hard_coach8", test: () => (mem.hardWins || {})["coach8"] > 0 },
1533
  { id: "hard_all", test: () => ARC_IDS.every((a) => (mem.hardWins || {})[a] > 0) },
 
 
 
 
 
 
 
1534
  { id: "melon", test: () => !!mem.melon }, // studio badge (kept for later use)
1535
  ];
1536
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1537
  // English badge text (name + one-line description). Discovered by playing; no
1538
  // spoilers of the specific detail to watch.
1539
  const ACH_TEXT = {
@@ -1561,6 +1636,10 @@ const ACH_TEXT = {
1561
  "hard_stairway8": ["Stairway, harder", "Escape Stairway 8 on hard."],
1562
  "hard_coach8": ["Coach, harder", "Escape Coach 8 on hard."],
1563
  "hard_all": ["Nowhere left soft", "Escape all three on hard."],
 
 
 
 
1564
  "melon": ["Melon Supporter", "Thank you for keeping the lights on. From all of us at Melon Labs."],
1565
  };
1566
  function computeAch() {
@@ -1609,6 +1688,10 @@ const ACH_ICON = {
1609
  "hard_stairway8": '<path d="M12 2l6 10-6 10-6-10z"/><path d="M12 7l3 5-3 5-3-5z"/>',
1610
  "hard_coach8": '<path d="M12 2l6 10-6 10-6-10z"/><path d="M12 7l3 5-3 5-3-5z"/>',
1611
  "hard_all": '<path d="M7 4l3 5-3 5-3-5z"/><path d="M17 4l3 5-3 5-3-5z"/><path d="M12 12l3 5-3 5-3-5z"/>',
 
 
 
 
1612
  // the studio: handled specially (a full-colour melon), see achIconSvg.
1613
  "melon": "",
1614
  };
@@ -1879,11 +1962,12 @@ let ARCS_BY_ID = {};
1879
  // the ways through in. An early interaction reveals them at once.
1880
  setTimeout(revealSelect, 1400);
1881
 
1882
- // Try to start the landing theme as soon as the screen loads. Browsers block
1883
- // audio until a user gesture, so this call is a no-op there (a suspended
1884
- // context) and the theme actually begins on the first interaction below;
1885
- // where autoplay is allowed it starts now.
1886
- if (window.ambience) window.ambience.play("landing");
 
1887
 
1888
  // Unlock audio on the first real gesture. This is the load-bearing part for
1889
  // mobile (and for the Spaces iframe): it must resume the context
 
61
  setDiffLabel: $("#set-diff-label"),
62
  setDiffHint: $("#set-diff-hint"),
63
  setDiffHard: $("#set-diff-hard"),
64
+ setDiffInsane: $("#set-diff-insane"),
65
  setAgeLabel: $("#set-age-label"),
66
  settingsGo: $("#settings-go"),
67
  achOpen: $("#ach-open"),
 
175
  // for younger players. Default normal. Does not change any mechanic.
176
  let register = localStorage.getItem("h8_register") || "normal";
177
 
178
+ // Hard is available to everyone from the start; Normal stays the default. Insane
179
+ // is honoured only once it is unlocked (all achievements bar the held/date-locked
180
+ // ones), so a stale saved "insane" never takes effect before it is earned.
181
+ function effectiveDifficulty() {
182
+ if (difficulty === "insane" && !insaneUnlocked()) return "normal";
183
+ return difficulty;
184
+ }
185
 
186
  function headers(extra) {
187
  const h = Object.assign({}, extra || {});
 
251
  if (el.setDiffLabel) el.setDiffLabel.textContent = t("set_diff", "Difficulty");
252
  if (el.setAgeLabel) el.setAgeLabel.textContent = t("set_age", "Reading");
253
  document.querySelectorAll('.set-opts[data-set="diff"] button').forEach((b) => {
254
+ const d = { easy: "Easy", normal: "Normal", hard: "Hard", insane: "Insane" };
255
  b.textContent = t("diff_" + b.dataset.diff, d[b.dataset.diff]);
256
  });
257
  document.querySelectorAll('.set-opts[data-set="register"] button').forEach((b) => {
 
286
  // Ship defaults (a fresh visitor, and so every redeploy): text "0" = smallest,
287
  // bright "0" = most dim. Difficulty and register default to "normal" above.
288
  // Keep these as the resting state; the sliders/words only move on opt-in.
289
+ let text = "0", bright = "0", motionPref = null;
290
  try {
291
  text = localStorage.getItem("h8_text") || "0";
292
  bright = localStorage.getItem("h8_bright") || "0";
293
+ motionPref = localStorage.getItem("h8_motion"); // null | "0" | "1"
294
  } catch (e) {}
295
  document.documentElement.dataset.text = text;
296
  document.body.dataset.bright = bright;
297
+ // Tri-state so the in-app toggle can OVERRIDE the OS, not merely add to it:
298
+ // "1" -> reduced (user asked), "0" -> full motion (user asked, beats the OS),
299
+ // unset -> follow the OS (prefers-reduced-motion / Low Power Mode).
300
+ // Without this a phone in Low Power Mode forced reduced motion even after the
301
+ // player turned the toggle off, so "full motion" looked broken on mobile.
302
+ reduceMotion = motionPref === "1" ? true
303
+ : motionPref === "0" ? false
304
+ : osReduceMotion();
305
  document.documentElement.classList.toggle("motion-reduce", reduceMotion);
306
  if (el.setText) el.setText.value = text;
307
  if (el.setBright) el.setBright.value = bright;
308
+ // The checkbox reflects the effective state, so with OS reduce-motion on it
309
+ // shows checked until the player explicitly clears it.
310
+ if (el.setMotion) el.setMotion.checked = reduceMotion;
311
  applyDifficultyUI();
312
  markOpts("register", register);
313
  }
 
315
  // the default is still Normal.
316
  function applyDifficultyUI() {
317
  markOpts("diff", difficulty);
318
+ // Reveal the Insane option only once it is unlocked (a completionist reward);
319
+ // it ships hidden. If a stale save selected it while still locked, fall back to
320
+ // the effective (clamped) difficulty for the highlight.
321
+ const unlocked = insaneUnlocked();
322
+ if (el.setDiffInsane) el.setDiffInsane.classList.toggle("hidden", !unlocked);
323
+ if (!unlocked && difficulty === "insane") markOpts("diff", "normal");
324
  if (el.setDiffHint) {
325
+ el.setDiffHint.textContent = (difficulty === "insane" && unlocked)
326
+ ? (ui["diff_hint_insane"] || "Insane remakes what normal is, every run.")
327
+ : (ui["diff_hint_hard"] || "Hard adds new kinds of change.");
328
  }
329
  }
330
  applySettings();
 
349
  if (!b || b.disabled) return;
350
  const set = group.dataset.set;
351
  const val = b.dataset.val;
352
+ if (set === "diff") {
353
+ if (val === "insane" && !insaneUnlocked()) return; // locked until earned
354
+ difficulty = val; // hard is available to everyone
355
+ }
356
  if (set === "register") register = val;
357
  try { localStorage.setItem("h8_" + set, val); } catch (e) {}
358
  applySettings();
 
654
  const res = await post("/api/interact", { prop });
655
  if (!res || res.kind === "none") return;
656
  if (res.kind === "fold") {
657
+ // Curiosity folded the run back to the start. Hold the fold line long enough
658
+ // to actually read (it was flashing past before), then drop into the fresh
659
+ // level-0 loop the server handed back and explain that the reset was this
660
+ // touch, so it never reads as a glitch. The explainer gates the controls
661
+ // (below), so the scene does not visibly rush to level 0 underneath it.
662
  showTouchLine(res.line);
663
+ await sleep(reduceMotion ? 1200 : 2600);
664
  run = freshRun(); // the fold sent the climb back to the start
665
  renderRoom(res);
666
  maybeFoldExplainer();
 
734
  });
735
  if (el.foldHideRow) el.foldHideRow.classList.toggle("hidden", seen < 2);
736
  if (el.foldHide) el.foldHide.checked = false;
737
+ // Gate the loop controls while the explainer is up (shares the onboarding
738
+ // gate): the level-0 controls must not go live under the modal, so the reset
739
+ // reads as a deliberate beat, not a scene that rushed past. hideFoldExplainer
740
+ // releases it.
741
+ onboarding = true;
742
+ el.controls.classList.add("hidden");
743
  el.fold.classList.remove("hidden");
744
  if (el.foldGo) el.foldGo.focus();
745
  }
 
748
  try { localStorage.setItem("h8_fold_hide", "1"); } catch (e) {}
749
  }
750
  if (el.fold) el.fold.classList.add("hidden");
751
+ // Release the control gate and hand the loop back at level 0.
752
+ onboarding = false;
753
+ if (el.corridor && !el.corridor.classList.contains("hidden")) {
754
+ el.controls.classList.remove("hidden");
755
+ decideStart = performance.now();
756
+ }
757
  }
758
  if (el.foldGo) el.foldGo.addEventListener("click", hideFoldExplainer);
759
  if (el.fold) {
 
1445
  // saves are alike.
1446
  const RELEASE_DAY = "2026-07-06"; // play on this local date...
1447
  const RELEASE_REVEAL = "2026-07-07"; // ...and the badge shows from here (all of earth past the 6th)
1448
+ // Order matches the landing/select screen (server list_arcs: default first, then
1449
+ // alphabetical), so the Recollections ledger and anything else iterating arcs
1450
+ // reads in the same order the player sees on the way in.
1451
+ const ARC_IDS = ["hallway-eight", "coach8", "stairway8"];
1452
  const NPC_PROP = { "hallway-eight": "figure", "stairway8": "figure", "coach8": "passenger" };
1453
 
1454
  function blankMem() {
1455
+ return { v: 1, flash: {}, flashText: {}, wins: {}, hardWins: {}, insaneWins: {}, clean: {}, ends: {}, npc: {},
1456
  shared: false, releaseDay: false, plays: 0, promos: [], melon: false, langs: [],
1457
  arcStarted: {},
1458
  records: { steady: false, cold: false, nerve: false, streak: 0, best: 0 } };
 
1489
  if (dirty) saveMem();
1490
  }
1491
  function recordWin(arc, attempts) {
1492
+ // Record the escape, and (if it was a hard/insane run) that tier's escape.
1493
+ const diff = effectiveDifficulty();
1494
+ if (diff === "hard") {
1495
  if (!mem.hardWins) mem.hardWins = {};
1496
  mem.hardWins[arc] = (mem.hardWins[arc] || 0) + 1;
1497
+ } else if (diff === "insane") {
1498
+ if (!mem.insaneWins) mem.insaneWins = {};
1499
+ mem.insaneWins[arc] = (mem.insaneWins[arc] || 0) + 1;
1500
  }
1501
  mem.wins[arc] = (mem.wins[arc] || 0) + 1;
1502
  if (attempts <= 1) mem.clean[arc] = true;
 
1578
  { id: "hard_stairway8", test: () => (mem.hardWins || {})["stairway8"] > 0 },
1579
  { id: "hard_coach8", test: () => (mem.hardWins || {})["coach8"] > 0 },
1580
  { id: "hard_all", test: () => ARC_IDS.every((a) => (mem.hardWins || {})[a] > 0) },
1581
+ // Insane-tier escapes (the hidden difficulty that randomizes the baseline each
1582
+ // run). Earnable only after Insane is unlocked, so they are NOT part of the
1583
+ // unlock gate below (that would be a chicken-and-egg).
1584
+ { id: "insane_hallway-eight", test: () => (mem.insaneWins || {})["hallway-eight"] > 0 },
1585
+ { id: "insane_stairway8", test: () => (mem.insaneWins || {})["stairway8"] > 0 },
1586
+ { id: "insane_coach8", test: () => (mem.insaneWins || {})["coach8"] > 0 },
1587
+ { id: "insane_all", test: () => ARC_IDS.every((a) => (mem.insaneWins || {})[a] > 0) },
1588
  { id: "melon", test: () => !!mem.melon }, // studio badge (kept for later use)
1589
  ];
1590
 
1591
+ // Insane unlocks only for a true completionist: every achievement earned, EXCEPT
1592
+ // the ones that cannot be earned through skill right now (the held studio badge,
1593
+ // the date-locked opening-night badge) and the Insane badges themselves. Nobody
1594
+ // is expected to reach this for weeks. Kept out of the difficulty picker until
1595
+ // then, so Insane ships hidden and unlockable, never breaking the other modes.
1596
+ const INSANE_GATE_EXCLUDE = new Set([
1597
+ "melon", "opening_night",
1598
+ "insane_hallway-eight", "insane_stairway8", "insane_coach8", "insane_all",
1599
+ ]);
1600
+ function insaneUnlocked() {
1601
+ // Defensive: this is reachable very early (effectiveDifficulty -> headers on the
1602
+ // first fetch) before ACHS is initialized. If achievements cannot be computed
1603
+ // yet, Insane is simply locked (the correct default), never a load-time crash.
1604
+ try {
1605
+ const state = computeAch();
1606
+ return ACHS.every((a) => INSANE_GATE_EXCLUDE.has(a.id) || state[a.id]);
1607
+ } catch (e) {
1608
+ return false;
1609
+ }
1610
+ }
1611
+
1612
  // English badge text (name + one-line description). Discovered by playing; no
1613
  // spoilers of the specific detail to watch.
1614
  const ACH_TEXT = {
 
1636
  "hard_stairway8": ["Stairway, harder", "Escape Stairway 8 on hard."],
1637
  "hard_coach8": ["Coach, harder", "Escape Coach 8 on hard."],
1638
  "hard_all": ["Nowhere left soft", "Escape all three on hard."],
1639
+ "insane_hallway-eight": ["Hallway, unmade", "Escape Hallway 8 on insane."],
1640
+ "insane_stairway8": ["Stairway, unmade", "Escape Stairway 8 on insane."],
1641
+ "insane_coach8": ["Coach, unmade", "Escape Coach 8 on insane."],
1642
+ "insane_all": ["Trust nothing", "Escape all three on insane."],
1643
  "melon": ["Melon Supporter", "Thank you for keeping the lights on. From all of us at Melon Labs."],
1644
  };
1645
  function computeAch() {
 
1688
  "hard_stairway8": '<path d="M12 2l6 10-6 10-6-10z"/><path d="M12 7l3 5-3 5-3-5z"/>',
1689
  "hard_coach8": '<path d="M12 2l6 10-6 10-6-10z"/><path d="M12 7l3 5-3 5-3-5z"/>',
1690
  "hard_all": '<path d="M7 4l3 5-3 5-3-5z"/><path d="M17 4l3 5-3 5-3-5z"/><path d="M12 12l3 5-3 5-3-5z"/>',
1691
+ "insane_hallway-eight": '<path d="M12 2l7 6-7 14-7-14z"/><path d="M12 8v8"/><path d="M9 12h6"/>',
1692
+ "insane_stairway8": '<path d="M12 2l7 6-7 14-7-14z"/><path d="M12 8v8"/><path d="M9 12h6"/>',
1693
+ "insane_coach8": '<path d="M12 2l7 6-7 14-7-14z"/><path d="M12 8v8"/><path d="M9 12h6"/>',
1694
+ "insane_all": '<path d="M6 3l2.5 4L6 11z"/><path d="M18 3l-2.5 4L18 11z"/><path d="M12 9l3 6-3 6-3-6z"/><path d="M12 13v4"/>',
1695
  // the studio: handled specially (a full-colour melon), see achIconSvg.
1696
  "melon": "",
1697
  };
 
1962
  // the ways through in. An early interaction reveals them at once.
1963
  setTimeout(revealSelect, 1400);
1964
 
1965
+ // Do NOT create the AudioContext at load. On mobile Chrome (and inside the
1966
+ // Spaces cross-origin iframe) a context constructed before any user gesture
1967
+ // can get stuck 'suspended' and a later resume() will not reliably start it,
1968
+ // which is why the landing/arc audio was silent on mobile. Instead the context
1969
+ // is created lazily INSIDE the first gesture (unlockAudio below), which mobile
1970
+ // Chrome requires, and the landing theme starts the instant it can be heard.
1971
 
1972
  // Unlock audio on the first real gesture. This is the load-bearing part for
1973
  // mobile (and for the Spaces iframe): it must resume the context
static/i18n/cs_CZ.json CHANGED
@@ -16,6 +16,10 @@
16
  "ach_d_hard_coach8": "Escape Coach 8 on hard.",
17
  "ach_d_hard_hallway-eight": "Escape Hallway 8 on hard.",
18
  "ach_d_hard_stairway8": "Escape Stairway 8 on hard.",
 
 
 
 
19
  "ach_d_melon": "Thank you for keeping the lights on. From all of us at Melon Labs.",
20
  "ach_d_nerve": "Turn back at the final door, and be right.",
21
  "ach_d_npc_knows": "Be acknowledged by the one who is always ahead.",
@@ -45,6 +49,10 @@
45
  "ach_n_hard_coach8": "Coach, harder",
46
  "ach_n_hard_hallway-eight": "Hallway, harder",
47
  "ach_n_hard_stairway8": "Stairway, harder",
 
 
 
 
48
  "ach_n_melon": "Melon Supporter",
49
  "ach_n_nerve": "Nerve",
50
  "ach_n_npc_knows": "It knows you",
@@ -78,7 +86,9 @@
78
  "diff_easy": "Easy",
79
  "diff_hard": "Hard",
80
  "diff_hint_hard": "Hard adds new kinds of change.",
 
81
  "diff_hint_locked": "Escape once to unlock Hard.",
 
82
  "diff_normal": "Normal",
83
  "end_credits": "End Credits",
84
  "ending_back": "Back to the start",
 
16
  "ach_d_hard_coach8": "Escape Coach 8 on hard.",
17
  "ach_d_hard_hallway-eight": "Escape Hallway 8 on hard.",
18
  "ach_d_hard_stairway8": "Escape Stairway 8 on hard.",
19
+ "ach_d_insane_all": "Escape all three on insane.",
20
+ "ach_d_insane_coach8": "Escape Coach 8 on insane.",
21
+ "ach_d_insane_hallway-eight": "Escape Hallway 8 on insane.",
22
+ "ach_d_insane_stairway8": "Escape Stairway 8 on insane.",
23
  "ach_d_melon": "Thank you for keeping the lights on. From all of us at Melon Labs.",
24
  "ach_d_nerve": "Turn back at the final door, and be right.",
25
  "ach_d_npc_knows": "Be acknowledged by the one who is always ahead.",
 
49
  "ach_n_hard_coach8": "Coach, harder",
50
  "ach_n_hard_hallway-eight": "Hallway, harder",
51
  "ach_n_hard_stairway8": "Stairway, harder",
52
+ "ach_n_insane_all": "Trust nothing",
53
+ "ach_n_insane_coach8": "Coach, unmade",
54
+ "ach_n_insane_hallway-eight": "Hallway, unmade",
55
+ "ach_n_insane_stairway8": "Stairway, unmade",
56
  "ach_n_melon": "Melon Supporter",
57
  "ach_n_nerve": "Nerve",
58
  "ach_n_npc_knows": "It knows you",
 
86
  "diff_easy": "Easy",
87
  "diff_hard": "Hard",
88
  "diff_hint_hard": "Hard adds new kinds of change.",
89
+ "diff_hint_insane": "Insane remakes what normal is, every run.",
90
  "diff_hint_locked": "Escape once to unlock Hard.",
91
+ "diff_insane": "Insane",
92
  "diff_normal": "Normal",
93
  "end_credits": "End Credits",
94
  "ending_back": "Back to the start",
static/i18n/de_DE.json CHANGED
@@ -16,6 +16,10 @@
16
  "ach_d_hard_coach8": "Entkomme Coach 8 auf Schwer.",
17
  "ach_d_hard_hallway-eight": "Entkomme Hallway 8 auf Schwer.",
18
  "ach_d_hard_stairway8": "Entkomme Stairway 8 auf Schwer.",
 
 
 
 
19
  "ach_d_melon": "Danke, dass du das Licht am Brennen hältst. Von uns allen bei Melon Labs.",
20
  "ach_d_nerve": "Kehre an der letzten Tür um, und behalte recht.",
21
  "ach_d_npc_knows": "Werde von dem erkannt, der dir immer voraus ist.",
@@ -45,6 +49,10 @@
45
  "ach_n_hard_coach8": "Coach, härter",
46
  "ach_n_hard_hallway-eight": "Hallway, härter",
47
  "ach_n_hard_stairway8": "Stairway, härter",
 
 
 
 
48
  "ach_n_melon": "Melon-Unterstützer",
49
  "ach_n_nerve": "Nervenstärke",
50
  "ach_n_npc_knows": "Es kennt dich",
@@ -78,7 +86,9 @@
78
  "diff_easy": "Leicht",
79
  "diff_hard": "Schwer",
80
  "diff_hint_hard": "Schwer bringt neue Arten von Veränderung.",
 
81
  "diff_hint_locked": "Entkomme einmal, um Schwer freizuschalten.",
 
82
  "diff_normal": "Normal",
83
  "end_credits": "Abspann",
84
  "ending_back": "Zurück zum Anfang",
 
16
  "ach_d_hard_coach8": "Entkomme Coach 8 auf Schwer.",
17
  "ach_d_hard_hallway-eight": "Entkomme Hallway 8 auf Schwer.",
18
  "ach_d_hard_stairway8": "Entkomme Stairway 8 auf Schwer.",
19
+ "ach_d_insane_all": "Escape all three on insane.",
20
+ "ach_d_insane_coach8": "Escape Coach 8 on insane.",
21
+ "ach_d_insane_hallway-eight": "Escape Hallway 8 on insane.",
22
+ "ach_d_insane_stairway8": "Escape Stairway 8 on insane.",
23
  "ach_d_melon": "Danke, dass du das Licht am Brennen hältst. Von uns allen bei Melon Labs.",
24
  "ach_d_nerve": "Kehre an der letzten Tür um, und behalte recht.",
25
  "ach_d_npc_knows": "Werde von dem erkannt, der dir immer voraus ist.",
 
49
  "ach_n_hard_coach8": "Coach, härter",
50
  "ach_n_hard_hallway-eight": "Hallway, härter",
51
  "ach_n_hard_stairway8": "Stairway, härter",
52
+ "ach_n_insane_all": "Trust nothing",
53
+ "ach_n_insane_coach8": "Coach, unmade",
54
+ "ach_n_insane_hallway-eight": "Hallway, unmade",
55
+ "ach_n_insane_stairway8": "Stairway, unmade",
56
  "ach_n_melon": "Melon-Unterstützer",
57
  "ach_n_nerve": "Nervenstärke",
58
  "ach_n_npc_knows": "Es kennt dich",
 
86
  "diff_easy": "Leicht",
87
  "diff_hard": "Schwer",
88
  "diff_hint_hard": "Schwer bringt neue Arten von Veränderung.",
89
+ "diff_hint_insane": "Insane remakes what normal is, every run.",
90
  "diff_hint_locked": "Entkomme einmal, um Schwer freizuschalten.",
91
+ "diff_insane": "Insane",
92
  "diff_normal": "Normal",
93
  "end_credits": "Abspann",
94
  "ending_back": "Zurück zum Anfang",
static/i18n/en_GB.json CHANGED
@@ -16,6 +16,10 @@
16
  "ach_d_hard_coach8": "Escape Coach 8 on hard.",
17
  "ach_d_hard_hallway-eight": "Escape Hallway 8 on hard.",
18
  "ach_d_hard_stairway8": "Escape Stairway 8 on hard.",
 
 
 
 
19
  "ach_d_melon": "Thank you for keeping the lights on. From all of us at Melon Labs.",
20
  "ach_d_nerve": "Turn back at the final door, and be right.",
21
  "ach_d_npc_knows": "Be acknowledged by the one who is always ahead.",
@@ -45,6 +49,10 @@
45
  "ach_n_hard_coach8": "Coach, harder",
46
  "ach_n_hard_hallway-eight": "Hallway, harder",
47
  "ach_n_hard_stairway8": "Stairway, harder",
 
 
 
 
48
  "ach_n_melon": "Melon Supporter",
49
  "ach_n_nerve": "Nerve",
50
  "ach_n_npc_knows": "It knows you",
@@ -78,7 +86,9 @@
78
  "diff_easy": "Easy",
79
  "diff_hard": "Hard",
80
  "diff_hint_hard": "Hard adds new kinds of change.",
 
81
  "diff_hint_locked": "Escape once to unlock Hard.",
 
82
  "diff_normal": "Normal",
83
  "end_credits": "End Credits",
84
  "ending_back": "Back to the start",
 
16
  "ach_d_hard_coach8": "Escape Coach 8 on hard.",
17
  "ach_d_hard_hallway-eight": "Escape Hallway 8 on hard.",
18
  "ach_d_hard_stairway8": "Escape Stairway 8 on hard.",
19
+ "ach_d_insane_all": "Escape all three on insane.",
20
+ "ach_d_insane_coach8": "Escape Coach 8 on insane.",
21
+ "ach_d_insane_hallway-eight": "Escape Hallway 8 on insane.",
22
+ "ach_d_insane_stairway8": "Escape Stairway 8 on insane.",
23
  "ach_d_melon": "Thank you for keeping the lights on. From all of us at Melon Labs.",
24
  "ach_d_nerve": "Turn back at the final door, and be right.",
25
  "ach_d_npc_knows": "Be acknowledged by the one who is always ahead.",
 
49
  "ach_n_hard_coach8": "Coach, harder",
50
  "ach_n_hard_hallway-eight": "Hallway, harder",
51
  "ach_n_hard_stairway8": "Stairway, harder",
52
+ "ach_n_insane_all": "Trust nothing",
53
+ "ach_n_insane_coach8": "Coach, unmade",
54
+ "ach_n_insane_hallway-eight": "Hallway, unmade",
55
+ "ach_n_insane_stairway8": "Stairway, unmade",
56
  "ach_n_melon": "Melon Supporter",
57
  "ach_n_nerve": "Nerve",
58
  "ach_n_npc_knows": "It knows you",
 
86
  "diff_easy": "Easy",
87
  "diff_hard": "Hard",
88
  "diff_hint_hard": "Hard adds new kinds of change.",
89
+ "diff_hint_insane": "Insane remakes what normal is, every run.",
90
  "diff_hint_locked": "Escape once to unlock Hard.",
91
+ "diff_insane": "Insane",
92
  "diff_normal": "Normal",
93
  "end_credits": "End Credits",
94
  "ending_back": "Back to the start",
static/i18n/en_US.json CHANGED
@@ -16,6 +16,10 @@
16
  "ach_d_hard_coach8": "Escape Coach 8 on hard.",
17
  "ach_d_hard_hallway-eight": "Escape Hallway 8 on hard.",
18
  "ach_d_hard_stairway8": "Escape Stairway 8 on hard.",
 
 
 
 
19
  "ach_d_melon": "Thank you for keeping the lights on. From all of us at Melon Labs.",
20
  "ach_d_nerve": "Turn back at the final door, and be right.",
21
  "ach_d_npc_knows": "Be acknowledged by the one who is always ahead.",
@@ -45,6 +49,10 @@
45
  "ach_n_hard_coach8": "Coach, harder",
46
  "ach_n_hard_hallway-eight": "Hallway, harder",
47
  "ach_n_hard_stairway8": "Stairway, harder",
 
 
 
 
48
  "ach_n_melon": "Melon Supporter",
49
  "ach_n_nerve": "Nerve",
50
  "ach_n_npc_knows": "It knows you",
@@ -78,7 +86,9 @@
78
  "diff_easy": "Easy",
79
  "diff_hard": "Hard",
80
  "diff_hint_hard": "Hard adds new kinds of change.",
 
81
  "diff_hint_locked": "Escape once to unlock Hard.",
 
82
  "diff_normal": "Normal",
83
  "end_credits": "End Credits",
84
  "ending_back": "Back to the start",
 
16
  "ach_d_hard_coach8": "Escape Coach 8 on hard.",
17
  "ach_d_hard_hallway-eight": "Escape Hallway 8 on hard.",
18
  "ach_d_hard_stairway8": "Escape Stairway 8 on hard.",
19
+ "ach_d_insane_all": "Escape all three on insane.",
20
+ "ach_d_insane_coach8": "Escape Coach 8 on insane.",
21
+ "ach_d_insane_hallway-eight": "Escape Hallway 8 on insane.",
22
+ "ach_d_insane_stairway8": "Escape Stairway 8 on insane.",
23
  "ach_d_melon": "Thank you for keeping the lights on. From all of us at Melon Labs.",
24
  "ach_d_nerve": "Turn back at the final door, and be right.",
25
  "ach_d_npc_knows": "Be acknowledged by the one who is always ahead.",
 
49
  "ach_n_hard_coach8": "Coach, harder",
50
  "ach_n_hard_hallway-eight": "Hallway, harder",
51
  "ach_n_hard_stairway8": "Stairway, harder",
52
+ "ach_n_insane_all": "Trust nothing",
53
+ "ach_n_insane_coach8": "Coach, unmade",
54
+ "ach_n_insane_hallway-eight": "Hallway, unmade",
55
+ "ach_n_insane_stairway8": "Stairway, unmade",
56
  "ach_n_melon": "Melon Supporter",
57
  "ach_n_nerve": "Nerve",
58
  "ach_n_npc_knows": "It knows you",
 
86
  "diff_easy": "Easy",
87
  "diff_hard": "Hard",
88
  "diff_hint_hard": "Hard adds new kinds of change.",
89
+ "diff_hint_insane": "Insane remakes what normal is, every run.",
90
  "diff_hint_locked": "Escape once to unlock Hard.",
91
+ "diff_insane": "Insane",
92
  "diff_normal": "Normal",
93
  "end_credits": "End Credits",
94
  "ending_back": "Back to the start",
static/i18n/es_ES.json CHANGED
@@ -16,6 +16,10 @@
16
  "ach_d_hard_coach8": "Escape Coach 8 on hard.",
17
  "ach_d_hard_hallway-eight": "Escape Hallway 8 on hard.",
18
  "ach_d_hard_stairway8": "Escape Stairway 8 on hard.",
 
 
 
 
19
  "ach_d_melon": "Thank you for keeping the lights on. From all of us at Melon Labs.",
20
  "ach_d_nerve": "Turn back at the final door, and be right.",
21
  "ach_d_npc_knows": "Be acknowledged by the one who is always ahead.",
@@ -45,6 +49,10 @@
45
  "ach_n_hard_coach8": "Coach, harder",
46
  "ach_n_hard_hallway-eight": "Hallway, harder",
47
  "ach_n_hard_stairway8": "Stairway, harder",
 
 
 
 
48
  "ach_n_melon": "Melon Supporter",
49
  "ach_n_nerve": "Nerve",
50
  "ach_n_npc_knows": "It knows you",
@@ -78,7 +86,9 @@
78
  "diff_easy": "Easy",
79
  "diff_hard": "Hard",
80
  "diff_hint_hard": "Hard adds new kinds of change.",
 
81
  "diff_hint_locked": "Escape once to unlock Hard.",
 
82
  "diff_normal": "Normal",
83
  "end_credits": "End Credits",
84
  "ending_back": "Back to the start",
 
16
  "ach_d_hard_coach8": "Escape Coach 8 on hard.",
17
  "ach_d_hard_hallway-eight": "Escape Hallway 8 on hard.",
18
  "ach_d_hard_stairway8": "Escape Stairway 8 on hard.",
19
+ "ach_d_insane_all": "Escape all three on insane.",
20
+ "ach_d_insane_coach8": "Escape Coach 8 on insane.",
21
+ "ach_d_insane_hallway-eight": "Escape Hallway 8 on insane.",
22
+ "ach_d_insane_stairway8": "Escape Stairway 8 on insane.",
23
  "ach_d_melon": "Thank you for keeping the lights on. From all of us at Melon Labs.",
24
  "ach_d_nerve": "Turn back at the final door, and be right.",
25
  "ach_d_npc_knows": "Be acknowledged by the one who is always ahead.",
 
49
  "ach_n_hard_coach8": "Coach, harder",
50
  "ach_n_hard_hallway-eight": "Hallway, harder",
51
  "ach_n_hard_stairway8": "Stairway, harder",
52
+ "ach_n_insane_all": "Trust nothing",
53
+ "ach_n_insane_coach8": "Coach, unmade",
54
+ "ach_n_insane_hallway-eight": "Hallway, unmade",
55
+ "ach_n_insane_stairway8": "Stairway, unmade",
56
  "ach_n_melon": "Melon Supporter",
57
  "ach_n_nerve": "Nerve",
58
  "ach_n_npc_knows": "It knows you",
 
86
  "diff_easy": "Easy",
87
  "diff_hard": "Hard",
88
  "diff_hint_hard": "Hard adds new kinds of change.",
89
+ "diff_hint_insane": "Insane remakes what normal is, every run.",
90
  "diff_hint_locked": "Escape once to unlock Hard.",
91
+ "diff_insane": "Insane",
92
  "diff_normal": "Normal",
93
  "end_credits": "End Credits",
94
  "ending_back": "Back to the start",
static/i18n/fr_CA.json CHANGED
@@ -16,6 +16,10 @@
16
  "ach_d_hard_coach8": "Escape Coach 8 on hard.",
17
  "ach_d_hard_hallway-eight": "Escape Hallway 8 on hard.",
18
  "ach_d_hard_stairway8": "Escape Stairway 8 on hard.",
 
 
 
 
19
  "ach_d_melon": "Thank you for keeping the lights on. From all of us at Melon Labs.",
20
  "ach_d_nerve": "Turn back at the final door, and be right.",
21
  "ach_d_npc_knows": "Be acknowledged by the one who is always ahead.",
@@ -45,6 +49,10 @@
45
  "ach_n_hard_coach8": "Coach, harder",
46
  "ach_n_hard_hallway-eight": "Hallway, harder",
47
  "ach_n_hard_stairway8": "Stairway, harder",
 
 
 
 
48
  "ach_n_melon": "Melon Supporter",
49
  "ach_n_nerve": "Nerve",
50
  "ach_n_npc_knows": "It knows you",
@@ -78,7 +86,9 @@
78
  "diff_easy": "Easy",
79
  "diff_hard": "Hard",
80
  "diff_hint_hard": "Hard adds new kinds of change.",
 
81
  "diff_hint_locked": "Escape once to unlock Hard.",
 
82
  "diff_normal": "Normal",
83
  "end_credits": "End Credits",
84
  "ending_back": "Back to the start",
 
16
  "ach_d_hard_coach8": "Escape Coach 8 on hard.",
17
  "ach_d_hard_hallway-eight": "Escape Hallway 8 on hard.",
18
  "ach_d_hard_stairway8": "Escape Stairway 8 on hard.",
19
+ "ach_d_insane_all": "Escape all three on insane.",
20
+ "ach_d_insane_coach8": "Escape Coach 8 on insane.",
21
+ "ach_d_insane_hallway-eight": "Escape Hallway 8 on insane.",
22
+ "ach_d_insane_stairway8": "Escape Stairway 8 on insane.",
23
  "ach_d_melon": "Thank you for keeping the lights on. From all of us at Melon Labs.",
24
  "ach_d_nerve": "Turn back at the final door, and be right.",
25
  "ach_d_npc_knows": "Be acknowledged by the one who is always ahead.",
 
49
  "ach_n_hard_coach8": "Coach, harder",
50
  "ach_n_hard_hallway-eight": "Hallway, harder",
51
  "ach_n_hard_stairway8": "Stairway, harder",
52
+ "ach_n_insane_all": "Trust nothing",
53
+ "ach_n_insane_coach8": "Coach, unmade",
54
+ "ach_n_insane_hallway-eight": "Hallway, unmade",
55
+ "ach_n_insane_stairway8": "Stairway, unmade",
56
  "ach_n_melon": "Melon Supporter",
57
  "ach_n_nerve": "Nerve",
58
  "ach_n_npc_knows": "It knows you",
 
86
  "diff_easy": "Easy",
87
  "diff_hard": "Hard",
88
  "diff_hint_hard": "Hard adds new kinds of change.",
89
+ "diff_hint_insane": "Insane remakes what normal is, every run.",
90
  "diff_hint_locked": "Escape once to unlock Hard.",
91
+ "diff_insane": "Insane",
92
  "diff_normal": "Normal",
93
  "end_credits": "End Credits",
94
  "ending_back": "Back to the start",
static/i18n/fr_FR.json CHANGED
@@ -16,6 +16,10 @@
16
  "ach_d_hard_coach8": "Sors de Coach 8 en difficile.",
17
  "ach_d_hard_hallway-eight": "Sors de Hallway 8 en difficile.",
18
  "ach_d_hard_stairway8": "Sors de Stairway 8 en difficile.",
 
 
 
 
19
  "ach_d_melon": "Merci de nous garder à flot. De toute l'équipe de Melon Labs.",
20
  "ach_d_nerve": "Fais demi-tour à la dernière porte, et aie raison.",
21
  "ach_d_npc_knows": "Sois reconnu par celui qui te précède toujours.",
@@ -45,6 +49,10 @@
45
  "ach_n_hard_coach8": "Coach, plus dur",
46
  "ach_n_hard_hallway-eight": "Hallway, plus dur",
47
  "ach_n_hard_stairway8": "Stairway, plus dur",
 
 
 
 
48
  "ach_n_melon": "Soutien de Melon",
49
  "ach_n_nerve": "Sang-froid",
50
  "ach_n_npc_knows": "Il te connaît",
@@ -78,7 +86,9 @@
78
  "diff_easy": "Facile",
79
  "diff_hard": "Difficile",
80
  "diff_hint_hard": "Le mode difficile ajoute de nouveaux types de changement.",
 
81
  "diff_hint_locked": "Sors une fois pour débloquer le mode difficile.",
 
82
  "diff_normal": "Normal",
83
  "end_credits": "Générique",
84
  "ending_back": "Retour au début",
 
16
  "ach_d_hard_coach8": "Sors de Coach 8 en difficile.",
17
  "ach_d_hard_hallway-eight": "Sors de Hallway 8 en difficile.",
18
  "ach_d_hard_stairway8": "Sors de Stairway 8 en difficile.",
19
+ "ach_d_insane_all": "Escape all three on insane.",
20
+ "ach_d_insane_coach8": "Escape Coach 8 on insane.",
21
+ "ach_d_insane_hallway-eight": "Escape Hallway 8 on insane.",
22
+ "ach_d_insane_stairway8": "Escape Stairway 8 on insane.",
23
  "ach_d_melon": "Merci de nous garder à flot. De toute l'équipe de Melon Labs.",
24
  "ach_d_nerve": "Fais demi-tour à la dernière porte, et aie raison.",
25
  "ach_d_npc_knows": "Sois reconnu par celui qui te précède toujours.",
 
49
  "ach_n_hard_coach8": "Coach, plus dur",
50
  "ach_n_hard_hallway-eight": "Hallway, plus dur",
51
  "ach_n_hard_stairway8": "Stairway, plus dur",
52
+ "ach_n_insane_all": "Trust nothing",
53
+ "ach_n_insane_coach8": "Coach, unmade",
54
+ "ach_n_insane_hallway-eight": "Hallway, unmade",
55
+ "ach_n_insane_stairway8": "Stairway, unmade",
56
  "ach_n_melon": "Soutien de Melon",
57
  "ach_n_nerve": "Sang-froid",
58
  "ach_n_npc_knows": "Il te connaît",
 
86
  "diff_easy": "Facile",
87
  "diff_hard": "Difficile",
88
  "diff_hint_hard": "Le mode difficile ajoute de nouveaux types de changement.",
89
+ "diff_hint_insane": "Insane remakes what normal is, every run.",
90
  "diff_hint_locked": "Sors une fois pour débloquer le mode difficile.",
91
+ "diff_insane": "Insane",
92
  "diff_normal": "Normal",
93
  "end_credits": "Générique",
94
  "ending_back": "Retour au début",
static/i18n/hi_IN.json CHANGED
@@ -16,6 +16,10 @@
16
  "ach_d_hard_coach8": "Escape Coach 8 on hard.",
17
  "ach_d_hard_hallway-eight": "Escape Hallway 8 on hard.",
18
  "ach_d_hard_stairway8": "Escape Stairway 8 on hard.",
 
 
 
 
19
  "ach_d_melon": "Thank you for keeping the lights on. From all of us at Melon Labs.",
20
  "ach_d_nerve": "Turn back at the final door, and be right.",
21
  "ach_d_npc_knows": "Be acknowledged by the one who is always ahead.",
@@ -45,6 +49,10 @@
45
  "ach_n_hard_coach8": "Coach, harder",
46
  "ach_n_hard_hallway-eight": "Hallway, harder",
47
  "ach_n_hard_stairway8": "Stairway, harder",
 
 
 
 
48
  "ach_n_melon": "Melon Supporter",
49
  "ach_n_nerve": "Nerve",
50
  "ach_n_npc_knows": "It knows you",
@@ -78,7 +86,9 @@
78
  "diff_easy": "Easy",
79
  "diff_hard": "Hard",
80
  "diff_hint_hard": "Hard adds new kinds of change.",
 
81
  "diff_hint_locked": "Escape once to unlock Hard.",
 
82
  "diff_normal": "Normal",
83
  "end_credits": "End Credits",
84
  "ending_back": "Back to the start",
 
16
  "ach_d_hard_coach8": "Escape Coach 8 on hard.",
17
  "ach_d_hard_hallway-eight": "Escape Hallway 8 on hard.",
18
  "ach_d_hard_stairway8": "Escape Stairway 8 on hard.",
19
+ "ach_d_insane_all": "Escape all three on insane.",
20
+ "ach_d_insane_coach8": "Escape Coach 8 on insane.",
21
+ "ach_d_insane_hallway-eight": "Escape Hallway 8 on insane.",
22
+ "ach_d_insane_stairway8": "Escape Stairway 8 on insane.",
23
  "ach_d_melon": "Thank you for keeping the lights on. From all of us at Melon Labs.",
24
  "ach_d_nerve": "Turn back at the final door, and be right.",
25
  "ach_d_npc_knows": "Be acknowledged by the one who is always ahead.",
 
49
  "ach_n_hard_coach8": "Coach, harder",
50
  "ach_n_hard_hallway-eight": "Hallway, harder",
51
  "ach_n_hard_stairway8": "Stairway, harder",
52
+ "ach_n_insane_all": "Trust nothing",
53
+ "ach_n_insane_coach8": "Coach, unmade",
54
+ "ach_n_insane_hallway-eight": "Hallway, unmade",
55
+ "ach_n_insane_stairway8": "Stairway, unmade",
56
  "ach_n_melon": "Melon Supporter",
57
  "ach_n_nerve": "Nerve",
58
  "ach_n_npc_knows": "It knows you",
 
86
  "diff_easy": "Easy",
87
  "diff_hard": "Hard",
88
  "diff_hint_hard": "Hard adds new kinds of change.",
89
+ "diff_hint_insane": "Insane remakes what normal is, every run.",
90
  "diff_hint_locked": "Escape once to unlock Hard.",
91
+ "diff_insane": "Insane",
92
  "diff_normal": "Normal",
93
  "end_credits": "End Credits",
94
  "ending_back": "Back to the start",
static/i18n/id_ID.json CHANGED
@@ -16,6 +16,10 @@
16
  "ach_d_hard_coach8": "Escape Coach 8 on hard.",
17
  "ach_d_hard_hallway-eight": "Escape Hallway 8 on hard.",
18
  "ach_d_hard_stairway8": "Escape Stairway 8 on hard.",
 
 
 
 
19
  "ach_d_melon": "Thank you for keeping the lights on. From all of us at Melon Labs.",
20
  "ach_d_nerve": "Turn back at the final door, and be right.",
21
  "ach_d_npc_knows": "Be acknowledged by the one who is always ahead.",
@@ -45,6 +49,10 @@
45
  "ach_n_hard_coach8": "Coach, harder",
46
  "ach_n_hard_hallway-eight": "Hallway, harder",
47
  "ach_n_hard_stairway8": "Stairway, harder",
 
 
 
 
48
  "ach_n_melon": "Melon Supporter",
49
  "ach_n_nerve": "Nerve",
50
  "ach_n_npc_knows": "It knows you",
@@ -78,7 +86,9 @@
78
  "diff_easy": "Easy",
79
  "diff_hard": "Hard",
80
  "diff_hint_hard": "Hard adds new kinds of change.",
 
81
  "diff_hint_locked": "Escape once to unlock Hard.",
 
82
  "diff_normal": "Normal",
83
  "end_credits": "End Credits",
84
  "ending_back": "Back to the start",
 
16
  "ach_d_hard_coach8": "Escape Coach 8 on hard.",
17
  "ach_d_hard_hallway-eight": "Escape Hallway 8 on hard.",
18
  "ach_d_hard_stairway8": "Escape Stairway 8 on hard.",
19
+ "ach_d_insane_all": "Escape all three on insane.",
20
+ "ach_d_insane_coach8": "Escape Coach 8 on insane.",
21
+ "ach_d_insane_hallway-eight": "Escape Hallway 8 on insane.",
22
+ "ach_d_insane_stairway8": "Escape Stairway 8 on insane.",
23
  "ach_d_melon": "Thank you for keeping the lights on. From all of us at Melon Labs.",
24
  "ach_d_nerve": "Turn back at the final door, and be right.",
25
  "ach_d_npc_knows": "Be acknowledged by the one who is always ahead.",
 
49
  "ach_n_hard_coach8": "Coach, harder",
50
  "ach_n_hard_hallway-eight": "Hallway, harder",
51
  "ach_n_hard_stairway8": "Stairway, harder",
52
+ "ach_n_insane_all": "Trust nothing",
53
+ "ach_n_insane_coach8": "Coach, unmade",
54
+ "ach_n_insane_hallway-eight": "Hallway, unmade",
55
+ "ach_n_insane_stairway8": "Stairway, unmade",
56
  "ach_n_melon": "Melon Supporter",
57
  "ach_n_nerve": "Nerve",
58
  "ach_n_npc_knows": "It knows you",
 
86
  "diff_easy": "Easy",
87
  "diff_hard": "Hard",
88
  "diff_hint_hard": "Hard adds new kinds of change.",
89
+ "diff_hint_insane": "Insane remakes what normal is, every run.",
90
  "diff_hint_locked": "Escape once to unlock Hard.",
91
+ "diff_insane": "Insane",
92
  "diff_normal": "Normal",
93
  "end_credits": "End Credits",
94
  "ending_back": "Back to the start",
static/i18n/it_IT.json CHANGED
@@ -16,6 +16,10 @@
16
  "ach_d_hard_coach8": "Escape Coach 8 on hard.",
17
  "ach_d_hard_hallway-eight": "Escape Hallway 8 on hard.",
18
  "ach_d_hard_stairway8": "Escape Stairway 8 on hard.",
 
 
 
 
19
  "ach_d_melon": "Thank you for keeping the lights on. From all of us at Melon Labs.",
20
  "ach_d_nerve": "Turn back at the final door, and be right.",
21
  "ach_d_npc_knows": "Be acknowledged by the one who is always ahead.",
@@ -45,6 +49,10 @@
45
  "ach_n_hard_coach8": "Coach, harder",
46
  "ach_n_hard_hallway-eight": "Hallway, harder",
47
  "ach_n_hard_stairway8": "Stairway, harder",
 
 
 
 
48
  "ach_n_melon": "Melon Supporter",
49
  "ach_n_nerve": "Nerve",
50
  "ach_n_npc_knows": "It knows you",
@@ -78,7 +86,9 @@
78
  "diff_easy": "Easy",
79
  "diff_hard": "Hard",
80
  "diff_hint_hard": "Hard adds new kinds of change.",
 
81
  "diff_hint_locked": "Escape once to unlock Hard.",
 
82
  "diff_normal": "Normal",
83
  "end_credits": "End Credits",
84
  "ending_back": "Back to the start",
 
16
  "ach_d_hard_coach8": "Escape Coach 8 on hard.",
17
  "ach_d_hard_hallway-eight": "Escape Hallway 8 on hard.",
18
  "ach_d_hard_stairway8": "Escape Stairway 8 on hard.",
19
+ "ach_d_insane_all": "Escape all three on insane.",
20
+ "ach_d_insane_coach8": "Escape Coach 8 on insane.",
21
+ "ach_d_insane_hallway-eight": "Escape Hallway 8 on insane.",
22
+ "ach_d_insane_stairway8": "Escape Stairway 8 on insane.",
23
  "ach_d_melon": "Thank you for keeping the lights on. From all of us at Melon Labs.",
24
  "ach_d_nerve": "Turn back at the final door, and be right.",
25
  "ach_d_npc_knows": "Be acknowledged by the one who is always ahead.",
 
49
  "ach_n_hard_coach8": "Coach, harder",
50
  "ach_n_hard_hallway-eight": "Hallway, harder",
51
  "ach_n_hard_stairway8": "Stairway, harder",
52
+ "ach_n_insane_all": "Trust nothing",
53
+ "ach_n_insane_coach8": "Coach, unmade",
54
+ "ach_n_insane_hallway-eight": "Hallway, unmade",
55
+ "ach_n_insane_stairway8": "Stairway, unmade",
56
  "ach_n_melon": "Melon Supporter",
57
  "ach_n_nerve": "Nerve",
58
  "ach_n_npc_knows": "It knows you",
 
86
  "diff_easy": "Easy",
87
  "diff_hard": "Hard",
88
  "diff_hint_hard": "Hard adds new kinds of change.",
89
+ "diff_hint_insane": "Insane remakes what normal is, every run.",
90
  "diff_hint_locked": "Escape once to unlock Hard.",
91
+ "diff_insane": "Insane",
92
  "diff_normal": "Normal",
93
  "end_credits": "End Credits",
94
  "ending_back": "Back to the start",
static/i18n/ja_JP.json CHANGED
@@ -16,6 +16,10 @@
16
  "ach_d_hard_coach8": "むずかしいで Coach 8 を抜ける。",
17
  "ach_d_hard_hallway-eight": "むずかしいで Hallway 8 を抜ける。",
18
  "ach_d_hard_stairway8": "むずかしいで Stairway 8 を抜ける。",
 
 
 
 
19
  "ach_d_melon": "灯りを絶やさずにいてくれてありがとう。Melon Labs 一同より。",
20
  "ach_d_nerve": "最後の扉で引き返し、そして正しい。",
21
  "ach_d_npc_knows": "いつも先を行くものに、気づかれる。",
@@ -45,6 +49,10 @@
45
  "ach_n_hard_coach8": "Coach、さらに難しく",
46
  "ach_n_hard_hallway-eight": "Hallway、さらに難しく",
47
  "ach_n_hard_stairway8": "Stairway、さらに難しく",
 
 
 
 
48
  "ach_n_melon": "Melon サポーター",
49
  "ach_n_nerve": "胆力",
50
  "ach_n_npc_knows": "それはあなたを知っている",
@@ -78,7 +86,9 @@
78
  "diff_easy": "やさしい",
79
  "diff_hard": "むずかしい",
80
  "diff_hint_hard": "むずかしいでは新しい種類の変化が加わる。",
 
81
  "diff_hint_locked": "一度脱出すると、むずかしいが解放される。",
 
82
  "diff_normal": "ふつう",
83
  "end_credits": "エンドロール",
84
  "ending_back": "最初に戻る",
 
16
  "ach_d_hard_coach8": "むずかしいで Coach 8 を抜ける。",
17
  "ach_d_hard_hallway-eight": "むずかしいで Hallway 8 を抜ける。",
18
  "ach_d_hard_stairway8": "むずかしいで Stairway 8 を抜ける。",
19
+ "ach_d_insane_all": "Escape all three on insane.",
20
+ "ach_d_insane_coach8": "Escape Coach 8 on insane.",
21
+ "ach_d_insane_hallway-eight": "Escape Hallway 8 on insane.",
22
+ "ach_d_insane_stairway8": "Escape Stairway 8 on insane.",
23
  "ach_d_melon": "灯りを絶やさずにいてくれてありがとう。Melon Labs 一同より。",
24
  "ach_d_nerve": "最後の扉で引き返し、そして正しい。",
25
  "ach_d_npc_knows": "いつも先を行くものに、気づかれる。",
 
49
  "ach_n_hard_coach8": "Coach、さらに難しく",
50
  "ach_n_hard_hallway-eight": "Hallway、さらに難しく",
51
  "ach_n_hard_stairway8": "Stairway、さらに難しく",
52
+ "ach_n_insane_all": "Trust nothing",
53
+ "ach_n_insane_coach8": "Coach, unmade",
54
+ "ach_n_insane_hallway-eight": "Hallway, unmade",
55
+ "ach_n_insane_stairway8": "Stairway, unmade",
56
  "ach_n_melon": "Melon サポーター",
57
  "ach_n_nerve": "胆力",
58
  "ach_n_npc_knows": "それはあなたを知っている",
 
86
  "diff_easy": "やさしい",
87
  "diff_hard": "むずかしい",
88
  "diff_hint_hard": "むずかしいでは新しい種類の変化が加わる。",
89
+ "diff_hint_insane": "Insane remakes what normal is, every run.",
90
  "diff_hint_locked": "一度脱出すると、むずかしいが解放される。",
91
+ "diff_insane": "Insane",
92
  "diff_normal": "ふつう",
93
  "end_credits": "エンドロール",
94
  "ending_back": "最初に戻る",
static/i18n/ko_KR.json CHANGED
@@ -16,6 +16,10 @@
16
  "ach_d_hard_coach8": "어려움에서 Coach 8을 빠져나간다.",
17
  "ach_d_hard_hallway-eight": "어려움에서 Hallway 8을 빠져나간다.",
18
  "ach_d_hard_stairway8": "어려움에서 Stairway 8을 빠져나간다.",
 
 
 
 
19
  "ach_d_melon": "불이 꺼지지 않게 해줘서 고마워요. Melon Labs 모두가.",
20
  "ach_d_nerve": "마지막 문에서 돌아서고, 그게 옳다.",
21
  "ach_d_npc_knows": "늘 앞서 있는 그가 너를 알아본다.",
@@ -45,6 +49,10 @@
45
  "ach_n_hard_coach8": "Coach, 더 어렵게",
46
  "ach_n_hard_hallway-eight": "Hallway, 더 어렵게",
47
  "ach_n_hard_stairway8": "Stairway, 더 어렵게",
 
 
 
 
48
  "ach_n_melon": "Melon 서포터",
49
  "ach_n_nerve": "배짱",
50
  "ach_n_npc_knows": "그것은 너를 안다",
@@ -78,7 +86,9 @@
78
  "diff_easy": "쉬움",
79
  "diff_hard": "어려움",
80
  "diff_hint_hard": "어려움은 새로운 종류의 변화를 더한다.",
 
81
  "diff_hint_locked": "한 번 빠져나가면 어려움이 열린다.",
 
82
  "diff_normal": "보통",
83
  "end_credits": "엔딩 크레딧",
84
  "ending_back": "처음으로 돌아가기",
 
16
  "ach_d_hard_coach8": "어려움에서 Coach 8을 빠져나간다.",
17
  "ach_d_hard_hallway-eight": "어려움에서 Hallway 8을 빠져나간다.",
18
  "ach_d_hard_stairway8": "어려움에서 Stairway 8을 빠져나간다.",
19
+ "ach_d_insane_all": "Escape all three on insane.",
20
+ "ach_d_insane_coach8": "Escape Coach 8 on insane.",
21
+ "ach_d_insane_hallway-eight": "Escape Hallway 8 on insane.",
22
+ "ach_d_insane_stairway8": "Escape Stairway 8 on insane.",
23
  "ach_d_melon": "불이 꺼지지 않게 해줘서 고마워요. Melon Labs 모두가.",
24
  "ach_d_nerve": "마지막 문에서 돌아서고, 그게 옳다.",
25
  "ach_d_npc_knows": "늘 앞서 있는 그가 너를 알아본다.",
 
49
  "ach_n_hard_coach8": "Coach, 더 어렵게",
50
  "ach_n_hard_hallway-eight": "Hallway, 더 어렵게",
51
  "ach_n_hard_stairway8": "Stairway, 더 어렵게",
52
+ "ach_n_insane_all": "Trust nothing",
53
+ "ach_n_insane_coach8": "Coach, unmade",
54
+ "ach_n_insane_hallway-eight": "Hallway, unmade",
55
+ "ach_n_insane_stairway8": "Stairway, unmade",
56
  "ach_n_melon": "Melon 서포터",
57
  "ach_n_nerve": "배짱",
58
  "ach_n_npc_knows": "그것은 너를 안다",
 
86
  "diff_easy": "쉬움",
87
  "diff_hard": "어려움",
88
  "diff_hint_hard": "어려움은 새로운 종류의 변화를 더한다.",
89
+ "diff_hint_insane": "Insane remakes what normal is, every run.",
90
  "diff_hint_locked": "한 번 빠져나가면 어려움이 열린다.",
91
+ "diff_insane": "Insane",
92
  "diff_normal": "보통",
93
  "end_credits": "엔딩 크레딧",
94
  "ending_back": "처음으로 돌아가기",
static/i18n/ms_MY.json CHANGED
@@ -16,6 +16,10 @@
16
  "ach_d_hard_coach8": "Escape Coach 8 on hard.",
17
  "ach_d_hard_hallway-eight": "Escape Hallway 8 on hard.",
18
  "ach_d_hard_stairway8": "Escape Stairway 8 on hard.",
 
 
 
 
19
  "ach_d_melon": "Thank you for keeping the lights on. From all of us at Melon Labs.",
20
  "ach_d_nerve": "Turn back at the final door, and be right.",
21
  "ach_d_npc_knows": "Be acknowledged by the one who is always ahead.",
@@ -45,6 +49,10 @@
45
  "ach_n_hard_coach8": "Coach, harder",
46
  "ach_n_hard_hallway-eight": "Hallway, harder",
47
  "ach_n_hard_stairway8": "Stairway, harder",
 
 
 
 
48
  "ach_n_melon": "Melon Supporter",
49
  "ach_n_nerve": "Nerve",
50
  "ach_n_npc_knows": "It knows you",
@@ -78,7 +86,9 @@
78
  "diff_easy": "Easy",
79
  "diff_hard": "Hard",
80
  "diff_hint_hard": "Hard adds new kinds of change.",
 
81
  "diff_hint_locked": "Escape once to unlock Hard.",
 
82
  "diff_normal": "Normal",
83
  "end_credits": "End Credits",
84
  "ending_back": "Back to the start",
 
16
  "ach_d_hard_coach8": "Escape Coach 8 on hard.",
17
  "ach_d_hard_hallway-eight": "Escape Hallway 8 on hard.",
18
  "ach_d_hard_stairway8": "Escape Stairway 8 on hard.",
19
+ "ach_d_insane_all": "Escape all three on insane.",
20
+ "ach_d_insane_coach8": "Escape Coach 8 on insane.",
21
+ "ach_d_insane_hallway-eight": "Escape Hallway 8 on insane.",
22
+ "ach_d_insane_stairway8": "Escape Stairway 8 on insane.",
23
  "ach_d_melon": "Thank you for keeping the lights on. From all of us at Melon Labs.",
24
  "ach_d_nerve": "Turn back at the final door, and be right.",
25
  "ach_d_npc_knows": "Be acknowledged by the one who is always ahead.",
 
49
  "ach_n_hard_coach8": "Coach, harder",
50
  "ach_n_hard_hallway-eight": "Hallway, harder",
51
  "ach_n_hard_stairway8": "Stairway, harder",
52
+ "ach_n_insane_all": "Trust nothing",
53
+ "ach_n_insane_coach8": "Coach, unmade",
54
+ "ach_n_insane_hallway-eight": "Hallway, unmade",
55
+ "ach_n_insane_stairway8": "Stairway, unmade",
56
  "ach_n_melon": "Melon Supporter",
57
  "ach_n_nerve": "Nerve",
58
  "ach_n_npc_knows": "It knows you",
 
86
  "diff_easy": "Easy",
87
  "diff_hard": "Hard",
88
  "diff_hint_hard": "Hard adds new kinds of change.",
89
+ "diff_hint_insane": "Insane remakes what normal is, every run.",
90
  "diff_hint_locked": "Escape once to unlock Hard.",
91
+ "diff_insane": "Insane",
92
  "diff_normal": "Normal",
93
  "end_credits": "End Credits",
94
  "ending_back": "Back to the start",
static/i18n/nl_NL.json CHANGED
@@ -16,6 +16,10 @@
16
  "ach_d_hard_coach8": "Escape Coach 8 on hard.",
17
  "ach_d_hard_hallway-eight": "Escape Hallway 8 on hard.",
18
  "ach_d_hard_stairway8": "Escape Stairway 8 on hard.",
 
 
 
 
19
  "ach_d_melon": "Thank you for keeping the lights on. From all of us at Melon Labs.",
20
  "ach_d_nerve": "Turn back at the final door, and be right.",
21
  "ach_d_npc_knows": "Be acknowledged by the one who is always ahead.",
@@ -45,6 +49,10 @@
45
  "ach_n_hard_coach8": "Coach, harder",
46
  "ach_n_hard_hallway-eight": "Hallway, harder",
47
  "ach_n_hard_stairway8": "Stairway, harder",
 
 
 
 
48
  "ach_n_melon": "Melon Supporter",
49
  "ach_n_nerve": "Nerve",
50
  "ach_n_npc_knows": "It knows you",
@@ -78,7 +86,9 @@
78
  "diff_easy": "Easy",
79
  "diff_hard": "Hard",
80
  "diff_hint_hard": "Hard adds new kinds of change.",
 
81
  "diff_hint_locked": "Escape once to unlock Hard.",
 
82
  "diff_normal": "Normal",
83
  "end_credits": "End Credits",
84
  "ending_back": "Back to the start",
 
16
  "ach_d_hard_coach8": "Escape Coach 8 on hard.",
17
  "ach_d_hard_hallway-eight": "Escape Hallway 8 on hard.",
18
  "ach_d_hard_stairway8": "Escape Stairway 8 on hard.",
19
+ "ach_d_insane_all": "Escape all three on insane.",
20
+ "ach_d_insane_coach8": "Escape Coach 8 on insane.",
21
+ "ach_d_insane_hallway-eight": "Escape Hallway 8 on insane.",
22
+ "ach_d_insane_stairway8": "Escape Stairway 8 on insane.",
23
  "ach_d_melon": "Thank you for keeping the lights on. From all of us at Melon Labs.",
24
  "ach_d_nerve": "Turn back at the final door, and be right.",
25
  "ach_d_npc_knows": "Be acknowledged by the one who is always ahead.",
 
49
  "ach_n_hard_coach8": "Coach, harder",
50
  "ach_n_hard_hallway-eight": "Hallway, harder",
51
  "ach_n_hard_stairway8": "Stairway, harder",
52
+ "ach_n_insane_all": "Trust nothing",
53
+ "ach_n_insane_coach8": "Coach, unmade",
54
+ "ach_n_insane_hallway-eight": "Hallway, unmade",
55
+ "ach_n_insane_stairway8": "Stairway, unmade",
56
  "ach_n_melon": "Melon Supporter",
57
  "ach_n_nerve": "Nerve",
58
  "ach_n_npc_knows": "It knows you",
 
86
  "diff_easy": "Easy",
87
  "diff_hard": "Hard",
88
  "diff_hint_hard": "Hard adds new kinds of change.",
89
+ "diff_hint_insane": "Insane remakes what normal is, every run.",
90
  "diff_hint_locked": "Escape once to unlock Hard.",
91
+ "diff_insane": "Insane",
92
  "diff_normal": "Normal",
93
  "end_credits": "End Credits",
94
  "ending_back": "Back to the start",
static/i18n/pt_PT.json CHANGED
@@ -16,6 +16,10 @@
16
  "ach_d_hard_coach8": "Sai do Coach 8 no difícil.",
17
  "ach_d_hard_hallway-eight": "Sai do Hallway 8 no difícil.",
18
  "ach_d_hard_stairway8": "Sai do Stairway 8 no difícil.",
 
 
 
 
19
  "ach_d_melon": "Obrigado por nos manteres de portas abertas. De todos nós na Melon Labs.",
20
  "ach_d_nerve": "Volta na última porta, e acerta.",
21
  "ach_d_npc_knows": "Sê reconhecido por aquele que vai sempre à frente.",
@@ -45,6 +49,10 @@
45
  "ach_n_hard_coach8": "Coach, mais difícil",
46
  "ach_n_hard_hallway-eight": "Hallway, mais difícil",
47
  "ach_n_hard_stairway8": "Stairway, mais difícil",
 
 
 
 
48
  "ach_n_melon": "Apoiante da Melon",
49
  "ach_n_nerve": "Coragem",
50
  "ach_n_npc_knows": "Sabe de ti",
@@ -78,7 +86,9 @@
78
  "diff_easy": "Fácil",
79
  "diff_hard": "Difícil",
80
  "diff_hint_hard": "O difícil acrescenta novos tipos de mudança.",
 
81
  "diff_hint_locked": "Sai uma vez para desbloquear o difícil.",
 
82
  "diff_normal": "Normal",
83
  "end_credits": "Créditos",
84
  "ending_back": "Voltar ao início",
 
16
  "ach_d_hard_coach8": "Sai do Coach 8 no difícil.",
17
  "ach_d_hard_hallway-eight": "Sai do Hallway 8 no difícil.",
18
  "ach_d_hard_stairway8": "Sai do Stairway 8 no difícil.",
19
+ "ach_d_insane_all": "Escape all three on insane.",
20
+ "ach_d_insane_coach8": "Escape Coach 8 on insane.",
21
+ "ach_d_insane_hallway-eight": "Escape Hallway 8 on insane.",
22
+ "ach_d_insane_stairway8": "Escape Stairway 8 on insane.",
23
  "ach_d_melon": "Obrigado por nos manteres de portas abertas. De todos nós na Melon Labs.",
24
  "ach_d_nerve": "Volta na última porta, e acerta.",
25
  "ach_d_npc_knows": "Sê reconhecido por aquele que vai sempre à frente.",
 
49
  "ach_n_hard_coach8": "Coach, mais difícil",
50
  "ach_n_hard_hallway-eight": "Hallway, mais difícil",
51
  "ach_n_hard_stairway8": "Stairway, mais difícil",
52
+ "ach_n_insane_all": "Trust nothing",
53
+ "ach_n_insane_coach8": "Coach, unmade",
54
+ "ach_n_insane_hallway-eight": "Hallway, unmade",
55
+ "ach_n_insane_stairway8": "Stairway, unmade",
56
  "ach_n_melon": "Apoiante da Melon",
57
  "ach_n_nerve": "Coragem",
58
  "ach_n_npc_knows": "Sabe de ti",
 
86
  "diff_easy": "Fácil",
87
  "diff_hard": "Difícil",
88
  "diff_hint_hard": "O difícil acrescenta novos tipos de mudança.",
89
+ "diff_hint_insane": "Insane remakes what normal is, every run.",
90
  "diff_hint_locked": "Sai uma vez para desbloquear o difícil.",
91
+ "diff_insane": "Insane",
92
  "diff_normal": "Normal",
93
  "end_credits": "Créditos",
94
  "ending_back": "Voltar ao início",
static/i18n/ta_IN.json CHANGED
@@ -16,6 +16,10 @@
16
  "ach_d_hard_coach8": "Escape Coach 8 on hard.",
17
  "ach_d_hard_hallway-eight": "Escape Hallway 8 on hard.",
18
  "ach_d_hard_stairway8": "Escape Stairway 8 on hard.",
 
 
 
 
19
  "ach_d_melon": "Thank you for keeping the lights on. From all of us at Melon Labs.",
20
  "ach_d_nerve": "Turn back at the final door, and be right.",
21
  "ach_d_npc_knows": "Be acknowledged by the one who is always ahead.",
@@ -45,6 +49,10 @@
45
  "ach_n_hard_coach8": "Coach, harder",
46
  "ach_n_hard_hallway-eight": "Hallway, harder",
47
  "ach_n_hard_stairway8": "Stairway, harder",
 
 
 
 
48
  "ach_n_melon": "Melon Supporter",
49
  "ach_n_nerve": "Nerve",
50
  "ach_n_npc_knows": "It knows you",
@@ -78,7 +86,9 @@
78
  "diff_easy": "Easy",
79
  "diff_hard": "Hard",
80
  "diff_hint_hard": "Hard adds new kinds of change.",
 
81
  "diff_hint_locked": "Escape once to unlock Hard.",
 
82
  "diff_normal": "Normal",
83
  "end_credits": "End Credits",
84
  "ending_back": "Back to the start",
 
16
  "ach_d_hard_coach8": "Escape Coach 8 on hard.",
17
  "ach_d_hard_hallway-eight": "Escape Hallway 8 on hard.",
18
  "ach_d_hard_stairway8": "Escape Stairway 8 on hard.",
19
+ "ach_d_insane_all": "Escape all three on insane.",
20
+ "ach_d_insane_coach8": "Escape Coach 8 on insane.",
21
+ "ach_d_insane_hallway-eight": "Escape Hallway 8 on insane.",
22
+ "ach_d_insane_stairway8": "Escape Stairway 8 on insane.",
23
  "ach_d_melon": "Thank you for keeping the lights on. From all of us at Melon Labs.",
24
  "ach_d_nerve": "Turn back at the final door, and be right.",
25
  "ach_d_npc_knows": "Be acknowledged by the one who is always ahead.",
 
49
  "ach_n_hard_coach8": "Coach, harder",
50
  "ach_n_hard_hallway-eight": "Hallway, harder",
51
  "ach_n_hard_stairway8": "Stairway, harder",
52
+ "ach_n_insane_all": "Trust nothing",
53
+ "ach_n_insane_coach8": "Coach, unmade",
54
+ "ach_n_insane_hallway-eight": "Hallway, unmade",
55
+ "ach_n_insane_stairway8": "Stairway, unmade",
56
  "ach_n_melon": "Melon Supporter",
57
  "ach_n_nerve": "Nerve",
58
  "ach_n_npc_knows": "It knows you",
 
86
  "diff_easy": "Easy",
87
  "diff_hard": "Hard",
88
  "diff_hint_hard": "Hard adds new kinds of change.",
89
+ "diff_hint_insane": "Insane remakes what normal is, every run.",
90
  "diff_hint_locked": "Escape once to unlock Hard.",
91
+ "diff_insane": "Insane",
92
  "diff_normal": "Normal",
93
  "end_credits": "End Credits",
94
  "ending_back": "Back to the start",
static/i18n/th_TH.json CHANGED
@@ -16,6 +16,10 @@
16
  "ach_d_hard_coach8": "Escape Coach 8 on hard.",
17
  "ach_d_hard_hallway-eight": "Escape Hallway 8 on hard.",
18
  "ach_d_hard_stairway8": "Escape Stairway 8 on hard.",
 
 
 
 
19
  "ach_d_melon": "Thank you for keeping the lights on. From all of us at Melon Labs.",
20
  "ach_d_nerve": "Turn back at the final door, and be right.",
21
  "ach_d_npc_knows": "Be acknowledged by the one who is always ahead.",
@@ -45,6 +49,10 @@
45
  "ach_n_hard_coach8": "Coach, harder",
46
  "ach_n_hard_hallway-eight": "Hallway, harder",
47
  "ach_n_hard_stairway8": "Stairway, harder",
 
 
 
 
48
  "ach_n_melon": "Melon Supporter",
49
  "ach_n_nerve": "Nerve",
50
  "ach_n_npc_knows": "It knows you",
@@ -78,7 +86,9 @@
78
  "diff_easy": "Easy",
79
  "diff_hard": "Hard",
80
  "diff_hint_hard": "Hard adds new kinds of change.",
 
81
  "diff_hint_locked": "Escape once to unlock Hard.",
 
82
  "diff_normal": "Normal",
83
  "end_credits": "End Credits",
84
  "ending_back": "Back to the start",
 
16
  "ach_d_hard_coach8": "Escape Coach 8 on hard.",
17
  "ach_d_hard_hallway-eight": "Escape Hallway 8 on hard.",
18
  "ach_d_hard_stairway8": "Escape Stairway 8 on hard.",
19
+ "ach_d_insane_all": "Escape all three on insane.",
20
+ "ach_d_insane_coach8": "Escape Coach 8 on insane.",
21
+ "ach_d_insane_hallway-eight": "Escape Hallway 8 on insane.",
22
+ "ach_d_insane_stairway8": "Escape Stairway 8 on insane.",
23
  "ach_d_melon": "Thank you for keeping the lights on. From all of us at Melon Labs.",
24
  "ach_d_nerve": "Turn back at the final door, and be right.",
25
  "ach_d_npc_knows": "Be acknowledged by the one who is always ahead.",
 
49
  "ach_n_hard_coach8": "Coach, harder",
50
  "ach_n_hard_hallway-eight": "Hallway, harder",
51
  "ach_n_hard_stairway8": "Stairway, harder",
52
+ "ach_n_insane_all": "Trust nothing",
53
+ "ach_n_insane_coach8": "Coach, unmade",
54
+ "ach_n_insane_hallway-eight": "Hallway, unmade",
55
+ "ach_n_insane_stairway8": "Stairway, unmade",
56
  "ach_n_melon": "Melon Supporter",
57
  "ach_n_nerve": "Nerve",
58
  "ach_n_npc_knows": "It knows you",
 
86
  "diff_easy": "Easy",
87
  "diff_hard": "Hard",
88
  "diff_hint_hard": "Hard adds new kinds of change.",
89
+ "diff_hint_insane": "Insane remakes what normal is, every run.",
90
  "diff_hint_locked": "Escape once to unlock Hard.",
91
+ "diff_insane": "Insane",
92
  "diff_normal": "Normal",
93
  "end_credits": "End Credits",
94
  "ending_back": "Back to the start",
static/i18n/vi_VN.json CHANGED
@@ -16,6 +16,10 @@
16
  "ach_d_hard_coach8": "Thoát khỏi Coach 8 ở chế độ khó.",
17
  "ach_d_hard_hallway-eight": "Thoát khỏi Hallway 8 ở chế độ khó.",
18
  "ach_d_hard_stairway8": "Thoát khỏi Stairway 8 ở chế độ khó.",
 
 
 
 
19
  "ach_d_melon": "Cảm ơn bạn đã giữ cho ánh đèn luôn sáng. Từ tất cả chúng tôi ở Melon Labs.",
20
  "ach_d_nerve": "Quay lại ở cánh cửa cuối cùng, và đúng.",
21
  "ach_d_npc_knows": "Được kẻ luôn đi trước nhận ra.",
@@ -45,6 +49,10 @@
45
  "ach_n_hard_coach8": "Coach, khó hơn",
46
  "ach_n_hard_hallway-eight": "Hallway, khó hơn",
47
  "ach_n_hard_stairway8": "Stairway, khó hơn",
 
 
 
 
48
  "ach_n_melon": "Người ủng hộ Melon",
49
  "ach_n_nerve": "Bản lĩnh",
50
  "ach_n_npc_knows": "Nó biết bạn",
@@ -78,7 +86,9 @@
78
  "diff_easy": "Dễ",
79
  "diff_hard": "Khó",
80
  "diff_hint_hard": "Chế độ khó thêm những kiểu thay đổi mới.",
 
81
  "diff_hint_locked": "Thoát ra một lần để mở khóa chế độ khó.",
 
82
  "diff_normal": "Thường",
83
  "end_credits": "Phần ghi công",
84
  "ending_back": "Về lại điểm đầu",
 
16
  "ach_d_hard_coach8": "Thoát khỏi Coach 8 ở chế độ khó.",
17
  "ach_d_hard_hallway-eight": "Thoát khỏi Hallway 8 ở chế độ khó.",
18
  "ach_d_hard_stairway8": "Thoát khỏi Stairway 8 ở chế độ khó.",
19
+ "ach_d_insane_all": "Escape all three on insane.",
20
+ "ach_d_insane_coach8": "Escape Coach 8 on insane.",
21
+ "ach_d_insane_hallway-eight": "Escape Hallway 8 on insane.",
22
+ "ach_d_insane_stairway8": "Escape Stairway 8 on insane.",
23
  "ach_d_melon": "Cảm ơn bạn đã giữ cho ánh đèn luôn sáng. Từ tất cả chúng tôi ở Melon Labs.",
24
  "ach_d_nerve": "Quay lại ở cánh cửa cuối cùng, và đúng.",
25
  "ach_d_npc_knows": "Được kẻ luôn đi trước nhận ra.",
 
49
  "ach_n_hard_coach8": "Coach, khó hơn",
50
  "ach_n_hard_hallway-eight": "Hallway, khó hơn",
51
  "ach_n_hard_stairway8": "Stairway, khó hơn",
52
+ "ach_n_insane_all": "Trust nothing",
53
+ "ach_n_insane_coach8": "Coach, unmade",
54
+ "ach_n_insane_hallway-eight": "Hallway, unmade",
55
+ "ach_n_insane_stairway8": "Stairway, unmade",
56
  "ach_n_melon": "Người ủng hộ Melon",
57
  "ach_n_nerve": "Bản lĩnh",
58
  "ach_n_npc_knows": "Nó biết bạn",
 
86
  "diff_easy": "Dễ",
87
  "diff_hard": "Khó",
88
  "diff_hint_hard": "Chế độ khó thêm những kiểu thay đổi mới.",
89
+ "diff_hint_insane": "Insane remakes what normal is, every run.",
90
  "diff_hint_locked": "Thoát ra một lần để mở khóa chế độ khó.",
91
+ "diff_insane": "Insane",
92
  "diff_normal": "Thường",
93
  "end_credits": "Phần ghi công",
94
  "ending_back": "Về lại điểm đầu",
static/i18n/yue_HK.json CHANGED
@@ -16,6 +16,10 @@
16
  "ach_d_hard_coach8": "Escape Coach 8 on hard.",
17
  "ach_d_hard_hallway-eight": "Escape Hallway 8 on hard.",
18
  "ach_d_hard_stairway8": "Escape Stairway 8 on hard.",
 
 
 
 
19
  "ach_d_melon": "Thank you for keeping the lights on. From all of us at Melon Labs.",
20
  "ach_d_nerve": "Turn back at the final door, and be right.",
21
  "ach_d_npc_knows": "Be acknowledged by the one who is always ahead.",
@@ -45,6 +49,10 @@
45
  "ach_n_hard_coach8": "Coach, harder",
46
  "ach_n_hard_hallway-eight": "Hallway, harder",
47
  "ach_n_hard_stairway8": "Stairway, harder",
 
 
 
 
48
  "ach_n_melon": "Melon Supporter",
49
  "ach_n_nerve": "Nerve",
50
  "ach_n_npc_knows": "It knows you",
@@ -78,7 +86,9 @@
78
  "diff_easy": "Easy",
79
  "diff_hard": "Hard",
80
  "diff_hint_hard": "Hard adds new kinds of change.",
 
81
  "diff_hint_locked": "Escape once to unlock Hard.",
 
82
  "diff_normal": "Normal",
83
  "end_credits": "End Credits",
84
  "ending_back": "Back to the start",
 
16
  "ach_d_hard_coach8": "Escape Coach 8 on hard.",
17
  "ach_d_hard_hallway-eight": "Escape Hallway 8 on hard.",
18
  "ach_d_hard_stairway8": "Escape Stairway 8 on hard.",
19
+ "ach_d_insane_all": "Escape all three on insane.",
20
+ "ach_d_insane_coach8": "Escape Coach 8 on insane.",
21
+ "ach_d_insane_hallway-eight": "Escape Hallway 8 on insane.",
22
+ "ach_d_insane_stairway8": "Escape Stairway 8 on insane.",
23
  "ach_d_melon": "Thank you for keeping the lights on. From all of us at Melon Labs.",
24
  "ach_d_nerve": "Turn back at the final door, and be right.",
25
  "ach_d_npc_knows": "Be acknowledged by the one who is always ahead.",
 
49
  "ach_n_hard_coach8": "Coach, harder",
50
  "ach_n_hard_hallway-eight": "Hallway, harder",
51
  "ach_n_hard_stairway8": "Stairway, harder",
52
+ "ach_n_insane_all": "Trust nothing",
53
+ "ach_n_insane_coach8": "Coach, unmade",
54
+ "ach_n_insane_hallway-eight": "Hallway, unmade",
55
+ "ach_n_insane_stairway8": "Stairway, unmade",
56
  "ach_n_melon": "Melon Supporter",
57
  "ach_n_nerve": "Nerve",
58
  "ach_n_npc_knows": "It knows you",
 
86
  "diff_easy": "Easy",
87
  "diff_hard": "Hard",
88
  "diff_hint_hard": "Hard adds new kinds of change.",
89
+ "diff_hint_insane": "Insane remakes what normal is, every run.",
90
  "diff_hint_locked": "Escape once to unlock Hard.",
91
+ "diff_insane": "Insane",
92
  "diff_normal": "Normal",
93
  "end_credits": "End Credits",
94
  "ending_back": "Back to the start",
static/i18n/zh_CN.json CHANGED
@@ -16,6 +16,10 @@
16
  "ach_d_hard_coach8": "在困难难度脱出 Coach 8。",
17
  "ach_d_hard_hallway-eight": "在困难难度脱出 Hallway 8。",
18
  "ach_d_hard_stairway8": "在困难难度脱出 Stairway 8。",
 
 
 
 
19
  "ach_d_melon": "谢谢你让灯一直亮着。Melon Labs 全体敬上。",
20
  "ach_d_nerve": "在最后一道门前折返,而且没错。",
21
  "ach_d_npc_knows": "被那个总在前方的身影认出。",
@@ -45,6 +49,10 @@
45
  "ach_n_hard_coach8": "Coach,更难",
46
  "ach_n_hard_hallway-eight": "Hallway,更难",
47
  "ach_n_hard_stairway8": "Stairway,更难",
 
 
 
 
48
  "ach_n_melon": "Melon 支持者",
49
  "ach_n_nerve": "定力",
50
  "ach_n_npc_knows": "它认得你",
@@ -78,7 +86,9 @@
78
  "diff_easy": "简单",
79
  "diff_hard": "困难",
80
  "diff_hint_hard": "困难会加入新的变化种类。",
 
81
  "diff_hint_locked": "先脱出一次,解锁困难。",
 
82
  "diff_normal": "普通",
83
  "end_credits": "片尾字幕",
84
  "ending_back": "回到起点",
 
16
  "ach_d_hard_coach8": "在困难难度脱出 Coach 8。",
17
  "ach_d_hard_hallway-eight": "在困难难度脱出 Hallway 8。",
18
  "ach_d_hard_stairway8": "在困难难度脱出 Stairway 8。",
19
+ "ach_d_insane_all": "Escape all three on insane.",
20
+ "ach_d_insane_coach8": "Escape Coach 8 on insane.",
21
+ "ach_d_insane_hallway-eight": "Escape Hallway 8 on insane.",
22
+ "ach_d_insane_stairway8": "Escape Stairway 8 on insane.",
23
  "ach_d_melon": "谢谢你让灯一直亮着。Melon Labs 全体敬上。",
24
  "ach_d_nerve": "在最后一道门前折返,而且没错。",
25
  "ach_d_npc_knows": "被那个总在前方的身影认出。",
 
49
  "ach_n_hard_coach8": "Coach,更难",
50
  "ach_n_hard_hallway-eight": "Hallway,更难",
51
  "ach_n_hard_stairway8": "Stairway,更难",
52
+ "ach_n_insane_all": "Trust nothing",
53
+ "ach_n_insane_coach8": "Coach, unmade",
54
+ "ach_n_insane_hallway-eight": "Hallway, unmade",
55
+ "ach_n_insane_stairway8": "Stairway, unmade",
56
  "ach_n_melon": "Melon 支持者",
57
  "ach_n_nerve": "定力",
58
  "ach_n_npc_knows": "它认得你",
 
86
  "diff_easy": "简单",
87
  "diff_hard": "困难",
88
  "diff_hint_hard": "困难会加入新的变化种类。",
89
+ "diff_hint_insane": "Insane remakes what normal is, every run.",
90
  "diff_hint_locked": "先脱出一次,解锁困难。",
91
+ "diff_insane": "Insane",
92
  "diff_normal": "普通",
93
  "end_credits": "片尾字幕",
94
  "ending_back": "回到起点",
static/i18n/zh_TW.json CHANGED
@@ -16,6 +16,10 @@
16
  "ach_d_hard_coach8": "Escape Coach 8 on hard.",
17
  "ach_d_hard_hallway-eight": "Escape Hallway 8 on hard.",
18
  "ach_d_hard_stairway8": "Escape Stairway 8 on hard.",
 
 
 
 
19
  "ach_d_melon": "Thank you for keeping the lights on. From all of us at Melon Labs.",
20
  "ach_d_nerve": "Turn back at the final door, and be right.",
21
  "ach_d_npc_knows": "Be acknowledged by the one who is always ahead.",
@@ -45,6 +49,10 @@
45
  "ach_n_hard_coach8": "Coach, harder",
46
  "ach_n_hard_hallway-eight": "Hallway, harder",
47
  "ach_n_hard_stairway8": "Stairway, harder",
 
 
 
 
48
  "ach_n_melon": "Melon Supporter",
49
  "ach_n_nerve": "Nerve",
50
  "ach_n_npc_knows": "It knows you",
@@ -78,7 +86,9 @@
78
  "diff_easy": "Easy",
79
  "diff_hard": "Hard",
80
  "diff_hint_hard": "Hard adds new kinds of change.",
 
81
  "diff_hint_locked": "Escape once to unlock Hard.",
 
82
  "diff_normal": "Normal",
83
  "end_credits": "End Credits",
84
  "ending_back": "Back to the start",
 
16
  "ach_d_hard_coach8": "Escape Coach 8 on hard.",
17
  "ach_d_hard_hallway-eight": "Escape Hallway 8 on hard.",
18
  "ach_d_hard_stairway8": "Escape Stairway 8 on hard.",
19
+ "ach_d_insane_all": "Escape all three on insane.",
20
+ "ach_d_insane_coach8": "Escape Coach 8 on insane.",
21
+ "ach_d_insane_hallway-eight": "Escape Hallway 8 on insane.",
22
+ "ach_d_insane_stairway8": "Escape Stairway 8 on insane.",
23
  "ach_d_melon": "Thank you for keeping the lights on. From all of us at Melon Labs.",
24
  "ach_d_nerve": "Turn back at the final door, and be right.",
25
  "ach_d_npc_knows": "Be acknowledged by the one who is always ahead.",
 
49
  "ach_n_hard_coach8": "Coach, harder",
50
  "ach_n_hard_hallway-eight": "Hallway, harder",
51
  "ach_n_hard_stairway8": "Stairway, harder",
52
+ "ach_n_insane_all": "Trust nothing",
53
+ "ach_n_insane_coach8": "Coach, unmade",
54
+ "ach_n_insane_hallway-eight": "Hallway, unmade",
55
+ "ach_n_insane_stairway8": "Stairway, unmade",
56
  "ach_n_melon": "Melon Supporter",
57
  "ach_n_nerve": "Nerve",
58
  "ach_n_npc_knows": "It knows you",
 
86
  "diff_easy": "Easy",
87
  "diff_hard": "Hard",
88
  "diff_hint_hard": "Hard adds new kinds of change.",
89
+ "diff_hint_insane": "Insane remakes what normal is, every run.",
90
  "diff_hint_locked": "Escape once to unlock Hard.",
91
+ "diff_insane": "Insane",
92
  "diff_normal": "Normal",
93
  "end_credits": "End Credits",
94
  "ending_back": "Back to the start",
static/style.css CHANGED
@@ -710,6 +710,10 @@ body[data-bright="2"] { --dim: #dcdcd7 !important; --dim2: #c6cad0 !important; }
710
  background: color-mix(in srgb, var(--accent) 6%, transparent); }
711
  .ach-icon { flex: none; margin-top: 0.05rem; color: var(--dim2); }
712
  .ach-tile.on .ach-icon { color: var(--accent); }
 
 
 
 
713
  .ach-body { min-width: 0; }
714
  .ach-name { color: var(--fg); font-size: 0.98rem; letter-spacing: 0.03em; margin-bottom: 0.2rem; }
715
  .ach-tile:not(.on) .ach-name { color: var(--dim2); letter-spacing: 0.14em; text-transform: uppercase; font-size: 0.8rem; }
@@ -839,6 +843,11 @@ body[data-bright="2"] { --dim: #dcdcd7 !important; --dim2: #c6cad0 !important; }
839
  .learn-panel {
840
  width: 34rem;
841
  max-width: 92vw;
 
 
 
 
 
842
  background: color-mix(in srgb, var(--bg) 82%, #16181c);
843
  border: 1px solid #2a2d31;
844
  border-top: 2px solid var(--accent);
@@ -846,6 +855,9 @@ body[data-bright="2"] { --dim: #dcdcd7 !important; --dim2: #c6cad0 !important; }
846
  box-shadow: 0 24px 80px -30px #000;
847
  animation: fade-in 0.9s ease both;
848
  }
 
 
 
849
  .learn-title {
850
  color: var(--fg);
851
  font-size: 1.15rem;
@@ -1040,7 +1052,10 @@ html.motion-reduce .credits-scroller { overflow-y: auto; }
1040
  }
1041
  #screen {
1042
  padding: 1.1rem;
1043
- padding-top: 3rem; /* clear the fixed sound toggle */
 
 
 
1044
  }
1045
 
1046
  .title { font-size: 2.2rem; }
@@ -1055,6 +1070,10 @@ html.motion-reduce .credits-scroller { overflow-y: auto; }
1055
  margin-bottom: 1.6rem;
1056
  flex-wrap: wrap;
1057
  gap: 0.2rem 0.8rem;
 
 
 
 
1058
  }
1059
  .progress { font-weight: 500; }
1060
 
@@ -1064,8 +1083,29 @@ html.motion-reduce .credits-scroller { overflow-y: auto; }
1064
  .give-up-row { margin-top: 2.2rem; }
1065
  .arcs { margin-top: 1.5rem; }
1066
 
1067
- .sound-toggle { top: 0.5rem; right: 0.5rem; opacity: 0.6; }
1068
- .settings-toggle { top: 0.5rem; right: 2.7rem; opacity: 0.6; }
1069
- .ach-corner-toggle { top: 0.5rem; right: 4.9rem; opacity: 0.6; }
1070
- .lang-corner { top: 0.5rem; left: 0.5rem; opacity: 0.6; }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1071
  }
 
710
  background: color-mix(in srgb, var(--accent) 6%, transparent); }
711
  .ach-icon { flex: none; margin-top: 0.05rem; color: var(--dim2); }
712
  .ach-tile.on .ach-icon { color: var(--accent); }
713
+ /* The empty-state line lives inside the 2-column grid; without this it is boxed
714
+ into one column (half width), so a short English line fits but longer
715
+ translations wrap to two. Span the full row so every locale reads as one line. */
716
+ .ach-empty { grid-column: 1 / -1; color: var(--dim); font-size: 0.9rem; }
717
  .ach-body { min-width: 0; }
718
  .ach-name { color: var(--fg); font-size: 0.98rem; letter-spacing: 0.03em; margin-bottom: 0.2rem; }
719
  .ach-tile:not(.on) .ach-name { color: var(--dim2); letter-spacing: 0.14em; text-transform: uppercase; font-size: 0.8rem; }
 
843
  .learn-panel {
844
  width: 34rem;
845
  max-width: 92vw;
846
+ /* Never taller than the viewport: scroll inside the panel so the button at the
847
+ bottom (Begin / Go on) is always reachable, even on a short phone. */
848
+ max-height: calc(100dvh - 2rem);
849
+ overflow-y: auto;
850
+ -webkit-overflow-scrolling: touch;
851
  background: color-mix(in srgb, var(--bg) 82%, #16181c);
852
  border: 1px solid #2a2d31;
853
  border-top: 2px solid var(--accent);
 
855
  box-shadow: 0 24px 80px -30px #000;
856
  animation: fade-in 0.9s ease both;
857
  }
858
+ /* Settings uses the same overlay; keep its panel scrollable too. */
859
+ .learn-overlay > .settings-panel,
860
+ #settings .learn-panel { max-height: calc(100dvh - 2rem); overflow-y: auto; }
861
  .learn-title {
862
  color: var(--fg);
863
  font-size: 1.15rem;
 
1052
  }
1053
  #screen {
1054
  padding: 1.1rem;
1055
+ /* Clear the fixed toggle cluster, and add the notch inset so on a notched
1056
+ iPhone (Safari) the content shifts down with the toggles instead of
1057
+ sliding under them. */
1058
+ padding-top: calc(3rem + env(safe-area-inset-top));
1059
  }
1060
 
1061
  .title { font-size: 2.2rem; }
 
1070
  margin-bottom: 1.6rem;
1071
  flex-wrap: wrap;
1072
  gap: 0.2rem 0.8rem;
1073
+ /* Keep "Furthest" out from under the sound/settings toggles at the top-right.
1074
+ space-between otherwise pins it to the very edge, directly beneath the
1075
+ icons; on Safari the vertical clearance is tight and they touched. */
1076
+ padding-right: 4rem;
1077
  }
1078
  .progress { font-weight: 500; }
1079
 
 
1083
  .give-up-row { margin-top: 2.2rem; }
1084
  .arcs { margin-top: 1.5rem; }
1085
 
1086
+ /* Memory action row: on a 375px phone three 7rem buttons overflow the panel.
1087
+ Let them share the width evenly and shrink instead of running off-edge. */
1088
+ .ach-actions { gap: 0.5rem; }
1089
+ .ach-actions .btn { min-width: 0; flex: 1 1 0; padding-left: 0.6rem; padding-right: 0.6rem; }
1090
+
1091
+ /* Follow the notch on the fixed corner controls so they never hide under it. */
1092
+ .sound-toggle { top: calc(0.5rem + env(safe-area-inset-top)); right: 0.5rem; opacity: 0.6; }
1093
+ .settings-toggle { top: calc(0.5rem + env(safe-area-inset-top)); right: 2.7rem; opacity: 0.6; }
1094
+ .ach-corner-toggle { top: calc(0.5rem + env(safe-area-inset-top)); right: 4.9rem; opacity: 0.6; }
1095
+ .lang-corner { top: calc(0.5rem + env(safe-area-inset-top)); left: 0.5rem; opacity: 0.6; }
1096
+ }
1097
+
1098
+ /* Very small phones (iPhone 12/13 mini, ~375px and under): tighten type and
1099
+ spacing so prose stays compact and nothing overflows its box. The larger
1100
+ phones (390-430px: 14/15/16/17 and the Pro / Pro Max) keep the 640px sizing. */
1101
+ @media (max-width: 380px) {
1102
+ #screen { padding: 0.9rem; padding-top: calc(2.8rem + env(safe-area-inset-top)); }
1103
+ .title { font-size: 2rem; }
1104
+ .heading { font-size: 1.15rem; letter-spacing: 0.16em; }
1105
+ .prose { font-size: 0.97rem; line-height: 1.85; }
1106
+ .hud { font-size: 0.64rem; letter-spacing: 0.09em; padding-right: 3.6rem; }
1107
+ .ach-panel { padding: 1.4rem 1.2rem 1.8rem; }
1108
+ .ach-title { font-size: 1.15rem; }
1109
+ .ach-actions .btn { padding-left: 0.4rem; padding-right: 0.4rem; font-size: 0.85rem; }
1110
+ .learn-panel { padding-left: 1.3rem; padding-right: 1.3rem; }
1111
  }
templates/index.html CHANGED
@@ -80,6 +80,7 @@
80
  <button data-val="easy" data-diff="easy"></button>
81
  <button data-val="normal" data-diff="normal"></button>
82
  <button data-val="hard" data-diff="hard" id="set-diff-hard"></button>
 
83
  </div>
84
  </div>
85
  <p id="set-diff-hint" class="set-hint"></p>
 
80
  <button data-val="easy" data-diff="easy"></button>
81
  <button data-val="normal" data-diff="normal"></button>
82
  <button data-val="hard" data-diff="hard" id="set-diff-hard"></button>
83
+ <button data-val="insane" data-diff="insane" id="set-diff-insane" class="hidden"></button>
84
  </div>
85
  </div>
86
  <p id="set-diff-hint" class="set-hint"></p>